<commit_before>#include "SocketHandler.hpp"

ssize_t SocketHandler::readAll(int fd, void* buf, size_t count) {
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesRead = read(fd, ((char*)buf) + pos, count - pos);
    if (bytesRead < 0) {
      VLOG(1) << "Failed a call to readAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to readAll");
    }
    pos += bytesRead;
  }
  return count;
}

ssize_t SocketHandler::writeAll(int fd, const void* buf, size_t count) {
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesWritten = write(fd, ((const char*)buf) + pos, count - pos);
    if (bytesWritten < 0) {
      VLOG(1) << "Failed a call to writeAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to writeAll");
    }
    pos += bytesWritten;
  }
  return count;
}

#define SOCKET_TIMEOUT (5)

ssize_t SocketHandler::readAllTimeout(int fd, void* buf, size_t count) {
  time_t timeout = time(NULL) + SOCKET_TIMEOUT;
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesRead = read(fd, ((char*)buf) + pos, count - pos);
    if (bytesRead < 0) {
      VLOG(1) << "Failed a call to readAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to readAll");
    }
    pos += bytesRead;
    if (timeout < time(NULL)) {
      throw runtime_error("Timeout");
    }
  }
  return count;
}

ssize_t SocketHandler::writeAllTimeout(int fd, const void* buf, size_t count) {
  time_t timeout = time(NULL) + SOCKET_TIMEOUT;
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesWritten = write(fd, ((const char*)buf) + pos, count - pos);
    if (bytesWritten < 0) {
      VLOG(1) << "Failed a call to writeAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to writeAll");
    }
    pos += bytesWritten;
    if (timeout < time(NULL)) {
      throw runtime_error("Timeout");
    }
  }
  return count;
}
<commit_msg>Increase timeout.  Add prints<commit_after>#include "SocketHandler.hpp"

ssize_t SocketHandler::readAll(int fd, void* buf, size_t count) {
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesRead = read(fd, ((char*)buf) + pos, count - pos);
    if (bytesRead < 0) {
      VLOG(1) << "Failed a call to readAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to readAll");
    }
    pos += bytesRead;
  }
  return count;
}

ssize_t SocketHandler::writeAll(int fd, const void* buf, size_t count) {
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesWritten = write(fd, ((const char*)buf) + pos, count - pos);
    if (bytesWritten < 0) {
      VLOG(1) << "Failed a call to writeAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to writeAll");
    }
    pos += bytesWritten;
  }
  return count;
}

#define SOCKET_TIMEOUT (60)

ssize_t SocketHandler::readAllTimeout(int fd, void* buf, size_t count) {
  time_t timeout = time(NULL) + SOCKET_TIMEOUT;
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesRead = read(fd, ((char*)buf) + pos, count - pos);
    if (bytesRead < 0) {
      VLOG(1) << "Failed a call to readAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to readAll");
    }
    VLOG(1) << "Read " << bytesRead << " bytes...";
    pos += bytesRead;
    if (timeout < time(NULL)) {
      throw runtime_error("Timeout");
    }
  }
  return count;
}

ssize_t SocketHandler::writeAllTimeout(int fd, const void* buf, size_t count) {
  time_t timeout = time(NULL) + SOCKET_TIMEOUT;
  size_t pos=0;
  while (pos<count) {
    ssize_t bytesWritten = write(fd, ((const char*)buf) + pos, count - pos);
    if (bytesWritten < 0) {
      VLOG(1) << "Failed a call to writeAll: " << strerror(errno);
      throw std::runtime_error("Failed a call to writeAll");
    }
    VLOG(1) << "Written " << bytesWritten << " bytes...";
    pos += bytesWritten;
    if (timeout < time(NULL)) {
      throw runtime_error("Timeout");
    }
  }
  return count;
}
<|endoftext|>


<commit_before>/**
 * @file	src/ThreadManager.cpp
 * @date	Mar 2016
 * @author	PhRG - opticalp.fr
 */

/*
 Copyright (c) 2016 Ph. Renaud-Goud / Opticalp

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

#include "ThreadManager.h"

#include "DataLogger.h"
#include "ModuleTask.h"
#include "Module.h"

#include "Poco/Observer.h"
#include "Poco/NumberFormatter.h"
#include "Poco/ThreadPool.h"
#include "Poco/AutoPtr.h"

using Poco::Observer;

ThreadManager::ThreadManager():
        VerboseEntity(name()),
        threadPool(2,32), // TODO set maxCapacity from config file
        taskManager(threadPool),
		cancellingAll(false)
{
    taskManager.addObserver(
            Observer<ThreadManager, TaskStartedNotification>(
                    *this, &ThreadManager::onStarted ) );
    taskManager.addObserver(
            Observer<ThreadManager, TaskFailedNotification>(
                    *this, &ThreadManager::onFailed ) );
    taskManager.addObserver(
                Observer<ThreadManager, TaskFinishedNotification>(
                        *this, &ThreadManager::onFinished ) );
    taskManager.addObserver(
                Observer<ThreadManager, TaskEnslavedNotification>(
                        *this, &ThreadManager::onEnslaved ) );

    threadPool.addCapacity(32);
}

void ThreadManager::onStarted(TaskStartedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name() + " was started");

    // TODO:
    // - dispatch to a NotificationQueue

    pNf->release();
}

void ThreadManager::onFailed(TaskFailedNotification* pNf)
{
    Poco::Exception e(pNf->reason());
    poco_error(logger(), e.displayText());

    ModuleTask* modTask = dynamic_cast<ModuleTask*>(pNf->task());
    modTask->resetModule();

    // TODO:
    // - dispatch to a NotificationQueue

    pNf->release();
}

void ThreadManager::onFinished(TaskFinishedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name() + " has stopped");

    ModuleTask* modTask = dynamic_cast<ModuleTask*>(pNf->task());

    if (modTask)
    {
    	// TODO:
		// - dispatch to a NotificationQueue

    	unregisterModuleTask(modTask);

    	taskListLock.readLock();

		poco_information(logger(), "pending module tasks list size is: "
				+ Poco::NumberFormatter::format(pendingModTasks.size()));

//		if (pendingModTasks.size() == 1)
//		{
//			Poco::AutoPtr<ModuleTask> tmpTsk(*pendingModTasks.begin());
//			poco_information(logger(),
//					"remaining task is: " + tmpTsk->name());
//		}

		taskListLock.unlock();

		poco_information(logger(), "TaskFinishednotification treated. ");
    }
    // else   datalogger task ==> 06.06.16 datalogger does not run in a task any more?

    pNf->release();
}

void ThreadManager::onEnslaved(TaskEnslavedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name()
    		+ " enslaved " + pNf->slave()->name() );

    pNf->release();
}

void ThreadManager::startDataLogger(DataLogger* dataLogger)
{
	try
	{
		threadPool.start(*dataLogger);
	}
	catch (Poco::NoThreadAvailableException& e)
	{
		// FIXME

		poco_error(logger(), dataLogger->name() + " cannot be started, "
				+ e.displayText());
	}
}

void ThreadManager::startModuleTask(ModuleTask* pTask)
{
	Poco::AutoPtr<ModuleTask> taskPtr(pTask, true); // do not take ownership!

	poco_information(logger(), "starting " + taskPtr->name());

	try
	{
		if (cancellingAll)
			throw Poco::RuntimeException("Cancelling, can not start " + taskPtr->name());

		taskManager.start(taskPtr);
	}
	catch (Poco::NoThreadAvailableException& e)
	{
		// FIXME

		poco_error(logger(), pTask->name() + " cannot be started, "
				+ e.displayText());
	}
	catch (...)
	{
		poco_information(logger(), pTask->name()
				+ " failed to start");
		unregisterModuleTask(pTask);
		throw;
	}
}

void ThreadManager::startSyncModuleTask(ModuleTask* pTask)
{
	Poco::AutoPtr<MergeableTask> taskPtr(pTask, true); // do not take ownership!

	poco_information(logger(), "SYNC starting " + taskPtr->name());

	try
	{
		if (cancellingAll)
			throw Poco::RuntimeException("Cancelling, can not sync start " + pTask->name());

		taskManager.startSync(taskPtr);
	}
	catch (...)
	{
		poco_information(logger(), pTask->name()
				+ " failed to sync start");
		unregisterModuleTask(pTask);
//		poco_information(logger(), pTask->name()
//				+ " is probably erased");
		throw;
	}
}

size_t ThreadManager::count()
{
	Poco::ScopedReadRWLock lock(taskListLock);

    return pendingModTasks.size();
}

#define TIME_LAPSE_WAIT_ALL 5

void ThreadManager::waitAll()
{
	bool stoppedOnCancel = false;

    // joinAll does not work here,
    // since it seems that it locks the recursive creation of new threads...
    // We use an event instead.
    while (count() || cancellingAll)
    {
        //Poco::TaskManager::TaskList list = taskManager.taskList();
        //std::string nameList("\n");
        //for (Poco::TaskManager::TaskList::iterator it = list.begin(),
        //        ite = list.end(); it != ite; it++)
        //    nameList += " - " + (*it)->name() + "\n";

        //nameList.erase(nameList.end()-1);

        //poco_information(logger(), "active threads are : " + nameList);

        Poco::Thread::sleep(TIME_LAPSE_WAIT_ALL);

        if (cancellingAll)
        	stoppedOnCancel = true;
    }

    if (stoppedOnCancel)
    	throw Poco::RuntimeException("waitAll","Cancellation upon user request");

    poco_information(logger(), "All threads have stopped. ");
}

void ThreadManager::registerNewModuleTask(ModuleTask* pTask)
{
	if (cancellingAll)
		throw Poco::RuntimeException("Cancelling, "
				"can not register the new task: "
				+ pTask->name());

	Poco::ScopedWriteRWLock lock(taskListLock);

	Poco::AutoPtr<ModuleTask> taskPtr(pTask);
	pendingModTasks.insert(taskPtr);
}

void ThreadManager::unregisterModuleTask(ModuleTask* pTask)
{
	Poco::ScopedWriteRWLock lock(taskListLock);

	Poco::AutoPtr<ModuleTask> taskPtr(pTask, true); // do not take ownership!
	if (pendingModTasks.erase(taskPtr) < 1)
		poco_warning(logger(), "Failed to erase the task " + pTask->name()
				+ " from the thread manager");
}

void ThreadManager::cancelAll()
{
	taskListLock.readLock();
	std::set< Poco::AutoPtr<ModuleTask> > tempModTasks = pendingModTasks;
	taskListLock.unlock();

	cancellingAll = true; // we wish that it is an atomic operation

	poco_notice(logger(), "Dispatching cancel() to all active tasks");

	for (std::set< Poco::AutoPtr<ModuleTask> >::iterator it = tempModTasks.begin(),
			ite = tempModTasks.end(); it != ite; it++)
	{
		Poco::AutoPtr<ModuleTask> tsk = *it;
		poco_information(logger(), "cancelling " + tsk->name());
		tsk->cancel();
	}

	while (count())
		Poco::Thread::sleep(TIME_LAPSE_WAIT_ALL);

	cancellingAll = false;
}
<commit_msg>Improve reliability in cancellation<commit_after>/**
 * @file	src/ThreadManager.cpp
 * @date	Mar 2016
 * @author	PhRG - opticalp.fr
 */

/*
 Copyright (c) 2016 Ph. Renaud-Goud / Opticalp

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

#include "ThreadManager.h"

#include "DataLogger.h"
#include "ModuleTask.h"
#include "Module.h"

#include "Poco/Observer.h"
#include "Poco/NumberFormatter.h"
#include "Poco/ThreadPool.h"
#include "Poco/AutoPtr.h"

using Poco::Observer;

ThreadManager::ThreadManager():
        VerboseEntity(name()),
        threadPool(2,32), // TODO set maxCapacity from config file
        taskManager(threadPool),
		cancellingAll(false)
{
    taskManager.addObserver(
            Observer<ThreadManager, TaskStartedNotification>(
                    *this, &ThreadManager::onStarted ) );
    taskManager.addObserver(
            Observer<ThreadManager, TaskFailedNotification>(
                    *this, &ThreadManager::onFailed ) );
    taskManager.addObserver(
                Observer<ThreadManager, TaskFinishedNotification>(
                        *this, &ThreadManager::onFinished ) );
    taskManager.addObserver(
                Observer<ThreadManager, TaskEnslavedNotification>(
                        *this, &ThreadManager::onEnslaved ) );

    threadPool.addCapacity(32);
}

void ThreadManager::onStarted(TaskStartedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name() + " was started");

    // TODO:
    // - dispatch to a NotificationQueue

    pNf->release();
}

void ThreadManager::onFailed(TaskFailedNotification* pNf)
{
    Poco::Exception e(pNf->reason());
    poco_error(logger(), e.displayText());

    ModuleTask* modTask = dynamic_cast<ModuleTask*>(pNf->task());
    modTask->resetModule();

    // TODO:
    // - dispatch to a NotificationQueue

    pNf->release();
}

void ThreadManager::onFinished(TaskFinishedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name() + " has stopped");

    ModuleTask* modTask = dynamic_cast<ModuleTask*>(pNf->task());

    if (modTask)
    {
    	// TODO:
		// - dispatch to a NotificationQueue

    	unregisterModuleTask(modTask);

    	taskListLock.readLock();

		poco_information(logger(), "pending module tasks list size is: "
				+ Poco::NumberFormatter::format(pendingModTasks.size()));

//		if (pendingModTasks.size() == 1)
//		{
//			Poco::AutoPtr<ModuleTask> tmpTsk(*pendingModTasks.begin());
//			poco_information(logger(),
//					"remaining task is: " + tmpTsk->name());
//		}

		taskListLock.unlock();

		poco_information(logger(), "TaskFinishednotification treated. ");
    }
    // else   datalogger task ==> 06.06.16 datalogger does not run in a task any more?

    pNf->release();
}

void ThreadManager::onEnslaved(TaskEnslavedNotification* pNf)
{
    poco_information(logger(), pNf->task()->name()
    		+ " enslaved " + pNf->slave()->name() );

    pNf->release();
}

void ThreadManager::startDataLogger(DataLogger* dataLogger)
{
	try
	{
		threadPool.start(*dataLogger);
	}
	catch (Poco::NoThreadAvailableException& e)
	{
		// FIXME

		poco_error(logger(), dataLogger->name() + " cannot be started, "
				+ e.displayText());
	}
}

void ThreadManager::startModuleTask(ModuleTask* pTask)
{
	Poco::AutoPtr<ModuleTask> taskPtr(pTask, true); // do not take ownership!

	poco_information(logger(), "starting " + taskPtr->name());

	try
	{
		if (cancellingAll)
			throw Poco::RuntimeException("Cancelling, can not start " + taskPtr->name());

		taskManager.start(taskPtr);
	}
	catch (Poco::NoThreadAvailableException& e)
	{
		// FIXME

		poco_error(logger(), pTask->name() + " cannot be started, "
				+ e.displayText());
	}
	catch (...)
	{
		poco_information(logger(), pTask->name()
				+ " failed to start");
		unregisterModuleTask(pTask);
		throw;
	}
}

void ThreadManager::startSyncModuleTask(ModuleTask* pTask)
{
	Poco::AutoPtr<MergeableTask> taskPtr(pTask, true); // do not take ownership!

	poco_information(logger(), "SYNC starting " + taskPtr->name());

	try
	{
		if (cancellingAll)
			throw Poco::RuntimeException("Cancelling, can not sync start " + pTask->name());

		taskManager.startSync(taskPtr);
	}
	catch (...)
	{
		poco_information(logger(), pTask->name()
				+ " failed to sync start");
		unregisterModuleTask(pTask);
//		poco_information(logger(), pTask->name()
//				+ " is probably erased");
		throw;
	}
}

size_t ThreadManager::count()
{
	Poco::ScopedReadRWLock lock(taskListLock);

    return pendingModTasks.size();
}

#define TIME_LAPSE_WAIT_ALL 5

void ThreadManager::waitAll()
{
	bool stoppedOnCancel = false;

    // joinAll does not work here,
    // since it seems that it locks the recursive creation of new threads...
    // We use an event instead.
    while (count() || cancellingAll)
    {
        //Poco::TaskManager::TaskList list = taskManager.taskList();
        //std::string nameList("\n");
        //for (Poco::TaskManager::TaskList::iterator it = list.begin(),
        //        ite = list.end(); it != ite; it++)
        //    nameList += " - " + (*it)->name() + "\n";

        //nameList.erase(nameList.end()-1);

        //poco_information(logger(), "active threads are : " + nameList);

        Poco::Thread::sleep(TIME_LAPSE_WAIT_ALL);

        if (cancellingAll)
        	stoppedOnCancel = true;
    }

    if (stoppedOnCancel)
    	throw Poco::RuntimeException("waitAll","Cancellation upon user request");

    poco_information(logger(), "All threads have stopped. ");
}

void ThreadManager::registerNewModuleTask(ModuleTask* pTask)
{
	if (cancellingAll)
		throw Poco::RuntimeException("Cancelling, "
				"can not register the new task: "
				+ pTask->name());

	Poco::ScopedWriteRWLock lock(taskListLock);

	Poco::AutoPtr<ModuleTask> taskPtr(pTask);
	pendingModTasks.insert(taskPtr);
}

void ThreadManager::unregisterModuleTask(ModuleTask* pTask)
{
	Poco::ScopedWriteRWLock lock(taskListLock);

	Poco::AutoPtr<ModuleTask> taskPtr(pTask, true); // do not take ownership!
	if (pendingModTasks.erase(taskPtr) < 1)
		poco_warning(logger(), "Failed to erase the task " + pTask->name()
				+ " from the thread manager");
}

void ThreadManager::cancelAll()
{
	cancellingAll = true;

	taskListLock.readLock();
	std::set< Poco::AutoPtr<ModuleTask> > tempModTasks = pendingModTasks;
	taskListLock.unlock();

	poco_notice(logger(), "Dispatching cancel() to all active tasks");

	for (std::set< Poco::AutoPtr<ModuleTask> >::iterator it = tempModTasks.begin(),
			ite = tempModTasks.end(); it != ite; it++)
	{
		Poco::AutoPtr<ModuleTask> tsk = *it;
		poco_information(logger(), "cancelling " + tsk->name());
		tsk->cancel();
	}

	poco_information(logger(), "All active tasks cancelled. Wait for them to delete. ");

	while (count())
		Poco::Thread::sleep(TIME_LAPSE_WAIT_ALL);

	poco_information(logger(), "No more pending task. cancellAll exiting. ");

	cancellingAll = false;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "VorbisDecoder.h"
#include "libvorbis/include/vorbis/vorbisfile.h"
#include <string.h>

using namespace nqr;

//@todo: implement decoding from memory (c.f. http://stackoverflow.com/questions/13437422/libvorbis-audio-decode-from-memory-in-c)
class VorbisDecoderInternal
{

public:

    VorbisDecoderInternal(AudioData * d, const std::string & filepath) : d(d)
    {
        fileHandle = new OggVorbis_File();

        /* @todo proper steaming support + classes
         const ov_callbacks callbacks =
         {
             .read_func = s_readCallback,
             .seek_func = s_seekCallback,
             .tell_func = s_tellCallback,
             .close_func = nullptr
         };
         */

        FILE * f = fopen(filepath.c_str(), "rb");

        if (!f)
            throw std::runtime_error("Can't open file");

        if (auto r = ov_test_callbacks(f, fileHandle, nullptr, 0, OV_CALLBACKS_DEFAULT) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info *ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr)
        {
            throw std::runtime_error("Reading metadata failed");
        }

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples))
            throw std::runtime_error("could not read any data");
    }

    VorbisDecoderInternal(AudioData * d, std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
    {
        fileHandle = new OggVorbis_File();

        ov_callbacks callbacks = {
          read_func,
          seek_func,
          close_func,
          tell_func,
        };
        if (auto r = ov_open_callbacks(this, fileHandle, nullptr, 0, callbacks) != 0) {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("Failed to open ogg vorbis file");
        }

        if (auto r = ov_test_callbacks(this, fileHandle, nullptr, 0, callbacks) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info *ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr)
        {
            throw std::runtime_error("Reading metadata failed");
        }

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples))
            throw std::runtime_error("could not read any data");
    }

    ~VorbisDecoderInternal()
    {
        ov_clear(fileHandle);
    }

    size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
    {

        //@todo support offset

        float **buffer = nullptr;
        size_t framesRemaining = requestedFrameCount;
        size_t totalFramesRead = 0;
        int bitstream = 0;

        while(0 < framesRemaining)
        {
            int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);

            // EOF
            if(!framesRead)
                break;

            if (framesRead < 0)
            {
                // Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. Log warning here.
                continue;
            }

            for (int i = 0; i < framesRead; ++i)
            {
                for(int ch = 0; ch < d->channelCount; ch++)
                {
                    d->samples[totalFramesRead] = buffer[ch][i];
                    totalFramesRead++;
                }
            }

        }

        return totalFramesRead;
    }

    std::string errorAsString(int ovErrorCode)
    {
        switch(ovErrorCode)
        {
            case OV_FALSE: return "OV_FALSE";
            case OV_EOF: return "OV_EOF";
            case OV_HOLE: return "OV_HOLE";
            case OV_EREAD: return "OV_EREAD";
            case OV_EFAULT: return "OV_EFAULT";
            case OV_EIMPL: return "OV_EIMPL";
            case OV_EINVAL: return "OV_EINVAL";
            case OV_ENOTVORBIS: return "OV_ENOTVORBIS";
            case OV_EBADHEADER: return "OV_EBADHEADER";
            case OV_EVERSION: return "OV_EVERSION";
            case OV_ENOTAUDIO: return "OV_ENOTAUDIO";
            case OV_EBADPACKET: return "OV_EBADPACKET";
            case OV_EBADLINK: return "OV_EBADLINK";
            case OV_ENOSEEK: return "OV_ENOSEEK";
            default: return "OV_UNKNOWN_ERROR";
        }
    }

    //////////////////////
    // vorbis callbacks //
    //////////////////////

    static size_t read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      size_t readLength = std::min<size_t>(size * nmemb, decoder->data.size() - decoder->dataPos);
      if (readLength > 0) {
        memcpy(ptr, decoder->data.data(), readLength);
        decoder->dataPos += readLength;
      }
      return readLength;
    }
    static int seek_func(void *datasource, ogg_int64_t offset, int whence) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      decoder->dataPos = std::min<size_t>(offset, decoder->data.size());
      return 0;
    }
    static int close_func(void *datasource) {
      return 0;
    }
    static long tell_func(void *datasource) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      return decoder->dataPos;
    }
    //@todo: implement streaming support

private:

    NO_COPY(VorbisDecoderInternal);

    OggVorbis_File * fileHandle;
    AudioData * d;
    std::vector<uint8_t> data;
    size_t dataPos;

    inline int64_t getTotalSamples() const { return int64_t(ov_pcm_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }

};

//////////////////////
// Public Interface //
//////////////////////

void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
    VorbisDecoderInternal decoder(data, path);
}

void VorbisDecoder::LoadFromBuffer(AudioData * data, std::vector<uint8_t> & memory)
{
    VorbisDecoderInternal decoder(data, memory);
}

std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()
{
    return {"ogg"};
}
<commit_msg>Bugfix vorbis decoder seeking<commit_after>/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "VorbisDecoder.h"
#include "libvorbis/include/vorbis/vorbisfile.h"
#include <string.h>

using namespace nqr;

//@todo: implement decoding from memory (c.f. http://stackoverflow.com/questions/13437422/libvorbis-audio-decode-from-memory-in-c)
class VorbisDecoderInternal
{

public:

    VorbisDecoderInternal(AudioData * d, const std::string & filepath) : d(d)
    {
        fileHandle = new OggVorbis_File();

        /* @todo proper steaming support + classes
         const ov_callbacks callbacks =
         {
             .read_func = s_readCallback,
             .seek_func = s_seekCallback,
             .tell_func = s_tellCallback,
             .close_func = nullptr
         };
         */

        FILE * f = fopen(filepath.c_str(), "rb");

        if (!f)
            throw std::runtime_error("Can't open file");

        if (auto r = ov_test_callbacks(f, fileHandle, nullptr, 0, OV_CALLBACKS_DEFAULT) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info *ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr)
        {
            throw std::runtime_error("Reading metadata failed");
        }

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples))
            throw std::runtime_error("could not read any data");
    }

    VorbisDecoderInternal(AudioData * d, std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
    {
        fileHandle = new OggVorbis_File();

        ov_callbacks callbacks = {
          read_func,
          seek_func,
          close_func,
          tell_func,
        };
        if (auto r = ov_open_callbacks(this, fileHandle, nullptr, 0, callbacks) != 0) {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("Failed to open ogg vorbis file");
        }

        if (auto r = ov_test_callbacks(this, fileHandle, nullptr, 0, callbacks) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info *ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr)
        {
            throw std::runtime_error("Reading metadata failed");
        }

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples))
            throw std::runtime_error("could not read any data");
    }

    ~VorbisDecoderInternal()
    {
        ov_clear(fileHandle);
    }

    size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
    {

        //@todo support offset

        float **buffer = nullptr;
        size_t framesRemaining = requestedFrameCount;
        size_t totalFramesRead = 0;
        int bitstream = 0;

        while(0 < framesRemaining)
        {
            int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);

            // EOF
            if(!framesRead)
                break;

            if (framesRead < 0)
            {
                // Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. Log warning here.
                continue;
            }

            for (int i = 0; i < framesRead; ++i)
            {
                for(int ch = 0; ch < d->channelCount; ch++)
                {
                    d->samples[totalFramesRead] = buffer[ch][i];
                    totalFramesRead++;
                }
            }

        }

        return totalFramesRead;
    }

    std::string errorAsString(int ovErrorCode)
    {
        switch(ovErrorCode)
        {
            case OV_FALSE: return "OV_FALSE";
            case OV_EOF: return "OV_EOF";
            case OV_HOLE: return "OV_HOLE";
            case OV_EREAD: return "OV_EREAD";
            case OV_EFAULT: return "OV_EFAULT";
            case OV_EIMPL: return "OV_EIMPL";
            case OV_EINVAL: return "OV_EINVAL";
            case OV_ENOTVORBIS: return "OV_ENOTVORBIS";
            case OV_EBADHEADER: return "OV_EBADHEADER";
            case OV_EVERSION: return "OV_EVERSION";
            case OV_ENOTAUDIO: return "OV_ENOTAUDIO";
            case OV_EBADPACKET: return "OV_EBADPACKET";
            case OV_EBADLINK: return "OV_EBADLINK";
            case OV_ENOSEEK: return "OV_ENOSEEK";
            default: return "OV_UNKNOWN_ERROR";
        }
    }

    //////////////////////
    // vorbis callbacks //
    //////////////////////

    static size_t read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      size_t readLength = std::min<size_t>(size * nmemb, decoder->data.size() - decoder->dataPos);
      if (readLength > 0) {
        memcpy(ptr, decoder->data.data(), readLength);
        decoder->dataPos += readLength;
      }
      return readLength;
    }
    static int seek_func(void *datasource, ogg_int64_t offset, int whence) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      size_t newPos = 0;
      if (whence == SEEK_SET) {
        newPos = offset;
      } else if (whence == SEEK_CUR) {
        newPos = decoder->dataPos + offset;
      } else if (whence == SEEK_END) {
        newPos = decoder->data.size() + offset;
      }
      newPos = std::min<size_t>(offset, decoder->data.size());
      decoder->dataPos = newPos;
      return newPos;
    }
    static int close_func(void *datasource) {
      return 0;
    }
    static long tell_func(void *datasource) {
      VorbisDecoderInternal *decoder = (VorbisDecoderInternal *)datasource;
      return decoder->dataPos;
    }
    //@todo: implement streaming support

private:

    NO_COPY(VorbisDecoderInternal);

    OggVorbis_File * fileHandle;
    AudioData * d;
    std::vector<uint8_t> data;
    size_t dataPos;

    inline int64_t getTotalSamples() const { return int64_t(ov_pcm_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }

};

//////////////////////
// Public Interface //
//////////////////////

void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
    VorbisDecoderInternal decoder(data, path);
}

void VorbisDecoder::LoadFromBuffer(AudioData * data, std::vector<uint8_t> & memory)
{
    VorbisDecoderInternal decoder(data, memory);
}

std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()
{
    return {"ogg"};
}
<|endoftext|>


<commit_before>#include "content/nw/src/api/nw_app_api.h"

#include "build/build_config.h"
#include "third_party/widevine/cdm/buildflags.h"

#include "chrome/browser/lifetime/browser_close_manager.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "content/public/common/content_features.h"

#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/task/current_thread.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "components/browsing_data/content/appcache_helper.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "components/component_updater/component_updater_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/devtools_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "content/nw/src/api/nw_app.h"
#include "content/nw/src/nw_base.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/app_window/native_app_window.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/error_utils.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"

using namespace extensions::nwapi::nw__app;

namespace extensions {
NwAppQuitFunction::NwAppQuitFunction() {

}

NwAppQuitFunction::~NwAppQuitFunction() {
}

void NwAppQuitFunction::DoJob(ExtensionService* service, std::string extension_id) {
  if (base::FeatureList::IsEnabled(::features::kNWNewWin)) {
    chrome::CloseAllBrowsersAndQuit(true);
    // trigger BrowserProcessImpl::Unpin()
    KeepAliveRegistry::GetInstance()->Register(KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::ENABLED);
    KeepAliveRegistry::GetInstance()->Unregister(KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::ENABLED);
    return;
  }
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
                                                      FROM_HERE,
                                                      base::BindOnce(&ExtensionService::TerminateExtension,
                                                                   service->AsWeakPtr(),
                                                                   extension_id));
}

ExtensionFunction::ResponseAction
NwAppQuitFunction::Run() {
  ExtensionService* service =
    ExtensionSystem::Get(browser_context())->extension_service();
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
        FROM_HERE,
        base::BindOnce(&NwAppQuitFunction::DoJob,
                   service,
                   extension_id()));
  return RespondNow(NoArguments());
}

void NwAppCloseAllWindowsFunction::DoJob(AppWindowRegistry* registry, std::string id) {
  if (base::FeatureList::IsEnabled(::features::kNWNewWin)) {
    chrome::CloseAllBrowsers();
  }
  AppWindowRegistry::AppWindowList windows =
    registry->GetAppWindowsForApp(id);

  for (AppWindow* window : windows) {
    if (window->NWCanClose())
      window->GetBaseWindow()->Close();
  }
}

ExtensionFunction::ResponseAction
NwAppCloseAllWindowsFunction::Run() {
  AppWindowRegistry* registry = AppWindowRegistry::Get(browser_context());
  if (!registry)
    return RespondNow(Error(""));
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
        FROM_HERE,
        base::BindOnce(&NwAppCloseAllWindowsFunction::DoJob, registry, extension()->id()));

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
NwAppEnableComponentFunction::Run() {
#if BUILDFLAG(ENABLE_WIDEVINE)
  component_updater::RegisterWidevineCdmComponent(g_browser_process->component_updater(),
                                                  base::BindOnce(&NwAppEnableComponentFunction::OnRegistered,
                                                                 this));
  return RespondLater();
#else
  return RespondNow(NoArguments());
#endif
}

void NwAppEnableComponentFunction::OnRegistered() {
  std::string ret;
  const std::vector<component_updater::ComponentInfo> component_list =
    g_browser_process->component_updater()->GetComponents();

  for (const auto& component : component_list) {
    if (component.id == "oimompecagnajdejgnnjijobebaeigek") {
      ret = component.version.GetString();
    }
  }
  auto result_value = std::make_unique<base::Value>(ret);

  Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
}

ExtensionFunction::ResponseAction
  NwAppUpdateComponentFunction::Run() {
  g_browser_process->component_updater()->GetOnDemandUpdater().OnDemandUpdate(
   "oimompecagnajdejgnnjijobebaeigek", component_updater::OnDemandUpdater::Priority::FOREGROUND,
   base::BindOnce(&NwAppUpdateComponentFunction::OnUpdated, this));

  return RespondLater();
}

void NwAppUpdateComponentFunction::OnUpdated(update_client::Error error) {
  bool ret = (error == update_client::Error::NONE);
  auto result_value = std::make_unique<base::Value>(ret);
  if (ret) {
    Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
  } else {
    VLOG(1) << "update component error: " << (int)error;
    Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
  }
}

NwAppGetArgvSyncFunction::NwAppGetArgvSyncFunction() {
}

NwAppGetArgvSyncFunction::~NwAppGetArgvSyncFunction() {
}

bool NwAppGetArgvSyncFunction::RunNWSync(base::ListValue* response, std::string* error) {

  nw::Package* package = nw::package();
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::CommandLine::StringVector args = command_line->GetArgs();
  base::CommandLine::StringVector argv = command_line->original_argv();

  // Ignore first non-switch arg if it's not a standalone package.
  bool ignore_arg = !package->self_extract();
  for (unsigned i = 1; i < argv.size(); ++i) {
    if (ignore_arg && args.size() && argv[i] == args[0]) {
      ignore_arg = false;
      continue;
    }

#if defined(OS_WIN)
    response->AppendString(base::WideToUTF16(argv[i]));
#else
    response->AppendString(argv[i]);
#endif
  }
  return true;
}

NwAppClearAppCacheFunction::NwAppClearAppCacheFunction() {
}

NwAppClearAppCacheFunction::~NwAppClearAppCacheFunction() {
}

bool NwAppClearAppCacheFunction::RunNWSync(base::ListValue* response, std::string* error) {
  std::string manifest;
  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &manifest));

  GURL manifest_url(manifest);
  scoped_refptr<browsing_data::CannedAppCacheHelper> helper(
       new browsing_data::CannedAppCacheHelper(browser_context()->GetDefaultStoragePartition()
                                                           ->GetAppCacheService()));

  helper->DeleteAppCaches(url::Origin::Create(manifest_url));
  return true;
}

NwAppClearCacheFunction::NwAppClearCacheFunction() {
}

NwAppClearCacheFunction::~NwAppClearCacheFunction() {
}

bool NwAppClearCacheFunction::RunNWSync(base::ListValue* response, std::string* error) {
  content::BrowsingDataRemover* remover =
    Profile::FromBrowserContext(browser_context())->GetBrowsingDataRemover();

  remover->AddObserver(this);
  remover->RemoveAndReply(base::Time(), base::Time::Max(),
                          content::BrowsingDataRemover::DATA_TYPE_CACHE,
                          content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
                          this);
  // BrowsingDataRemover deletes itself.
  base::CurrentThread::ScopedNestableTaskAllower allow;

  run_loop_.Run();
  remover->RemoveObserver(this);
  return true;
}

void NwAppClearCacheFunction::OnBrowsingDataRemoverDone(uint64_t failed_data_types) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  run_loop_.Quit();
}

NwAppSetProxyConfigFunction::NwAppSetProxyConfigFunction() {
}

NwAppSetProxyConfigFunction::~NwAppSetProxyConfigFunction() {
}

bool NwAppSetProxyConfigFunction::RunNWSync(base::ListValue* response, std::string* error) {
  net::ProxyConfigWithAnnotation config;
  std::unique_ptr<nwapi::nw__app::SetProxyConfig::Params> params(
      nwapi::nw__app::SetProxyConfig::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params.get());

  std::string pac_url = params->pac_url.get() ? *params->pac_url : "";
  if (!pac_url.empty()) {
    if (pac_url == "<direct>")
      config = net::ProxyConfigWithAnnotation::CreateDirect();
    else if (pac_url == "<auto>")
      config = net::ProxyConfigWithAnnotation(net::ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS);
    else
      config = net::ProxyConfigWithAnnotation(net::ProxyConfig::CreateFromCustomPacURL(GURL(pac_url)), TRAFFIC_ANNOTATION_FOR_TESTS);
  } else {
    std::string proxy_config;
    net::ProxyConfig pc;
    EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &proxy_config));
    pc.proxy_rules().ParseFromString(proxy_config);
    config = net::ProxyConfigWithAnnotation(pc, TRAFFIC_ANNOTATION_FOR_TESTS);
  }

  Profile* profile = Profile::FromBrowserContext(browser_context());
  auto* profile_network_context =
    ProfileNetworkContextServiceFactory::GetForContext(profile);
  profile_network_context->UpdateProxyConfig(config);
  return true;
}

bool NwAppGetDataPathFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
  response->AppendString(base::WideToUTF16(browser_context()->GetPath().value()));
#else
  response->AppendString(browser_context()->GetPath().value());
#endif
  return true;
}

ExtensionFunction::ResponseAction
NwAppCrashBrowserFunction::Run() {
  int* ptr = nullptr;
  *ptr = 1;
  return RespondNow(NoArguments());
}

} // namespace extensions
<commit_msg>Fix win build: add utf_string_conversions.h<commit_after>#include "content/nw/src/api/nw_app_api.h"

#include "build/build_config.h"
#include "third_party/widevine/cdm/buildflags.h"

#include "chrome/browser/lifetime/browser_close_manager.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "content/public/common/content_features.h"

#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/current_thread.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "components/browsing_data/content/appcache_helper.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "components/component_updater/component_updater_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/devtools_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "content/nw/src/api/nw_app.h"
#include "content/nw/src/nw_base.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/app_window/native_app_window.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/error_utils.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"

using namespace extensions::nwapi::nw__app;

namespace extensions {
NwAppQuitFunction::NwAppQuitFunction() {

}

NwAppQuitFunction::~NwAppQuitFunction() {
}

void NwAppQuitFunction::DoJob(ExtensionService* service, std::string extension_id) {
  if (base::FeatureList::IsEnabled(::features::kNWNewWin)) {
    chrome::CloseAllBrowsersAndQuit(true);
    // trigger BrowserProcessImpl::Unpin()
    KeepAliveRegistry::GetInstance()->Register(KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::ENABLED);
    KeepAliveRegistry::GetInstance()->Unregister(KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::ENABLED);
    return;
  }
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
                                                      FROM_HERE,
                                                      base::BindOnce(&ExtensionService::TerminateExtension,
                                                                   service->AsWeakPtr(),
                                                                   extension_id));
}

ExtensionFunction::ResponseAction
NwAppQuitFunction::Run() {
  ExtensionService* service =
    ExtensionSystem::Get(browser_context())->extension_service();
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
        FROM_HERE,
        base::BindOnce(&NwAppQuitFunction::DoJob,
                   service,
                   extension_id()));
  return RespondNow(NoArguments());
}

void NwAppCloseAllWindowsFunction::DoJob(AppWindowRegistry* registry, std::string id) {
  if (base::FeatureList::IsEnabled(::features::kNWNewWin)) {
    chrome::CloseAllBrowsers();
  }
  AppWindowRegistry::AppWindowList windows =
    registry->GetAppWindowsForApp(id);

  for (AppWindow* window : windows) {
    if (window->NWCanClose())
      window->GetBaseWindow()->Close();
  }
}

ExtensionFunction::ResponseAction
NwAppCloseAllWindowsFunction::Run() {
  AppWindowRegistry* registry = AppWindowRegistry::Get(browser_context());
  if (!registry)
    return RespondNow(Error(""));
  base::ThreadTaskRunnerHandle::Get().get()->PostTask(
        FROM_HERE,
        base::BindOnce(&NwAppCloseAllWindowsFunction::DoJob, registry, extension()->id()));

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
NwAppEnableComponentFunction::Run() {
#if BUILDFLAG(ENABLE_WIDEVINE)
  component_updater::RegisterWidevineCdmComponent(g_browser_process->component_updater(),
                                                  base::BindOnce(&NwAppEnableComponentFunction::OnRegistered,
                                                                 this));
  return RespondLater();
#else
  return RespondNow(NoArguments());
#endif
}

void NwAppEnableComponentFunction::OnRegistered() {
  std::string ret;
  const std::vector<component_updater::ComponentInfo> component_list =
    g_browser_process->component_updater()->GetComponents();

  for (const auto& component : component_list) {
    if (component.id == "oimompecagnajdejgnnjijobebaeigek") {
      ret = component.version.GetString();
    }
  }
  auto result_value = std::make_unique<base::Value>(ret);

  Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
}

ExtensionFunction::ResponseAction
  NwAppUpdateComponentFunction::Run() {
  g_browser_process->component_updater()->GetOnDemandUpdater().OnDemandUpdate(
   "oimompecagnajdejgnnjijobebaeigek", component_updater::OnDemandUpdater::Priority::FOREGROUND,
   base::BindOnce(&NwAppUpdateComponentFunction::OnUpdated, this));

  return RespondLater();
}

void NwAppUpdateComponentFunction::OnUpdated(update_client::Error error) {
  bool ret = (error == update_client::Error::NONE);
  auto result_value = std::make_unique<base::Value>(ret);
  if (ret) {
    Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
  } else {
    VLOG(1) << "update component error: " << (int)error;
    Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result_value))));
  }
}

NwAppGetArgvSyncFunction::NwAppGetArgvSyncFunction() {
}

NwAppGetArgvSyncFunction::~NwAppGetArgvSyncFunction() {
}

bool NwAppGetArgvSyncFunction::RunNWSync(base::ListValue* response, std::string* error) {

  nw::Package* package = nw::package();
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::CommandLine::StringVector args = command_line->GetArgs();
  base::CommandLine::StringVector argv = command_line->original_argv();

  // Ignore first non-switch arg if it's not a standalone package.
  bool ignore_arg = !package->self_extract();
  for (unsigned i = 1; i < argv.size(); ++i) {
    if (ignore_arg && args.size() && argv[i] == args[0]) {
      ignore_arg = false;
      continue;
    }

#if defined(OS_WIN)
    response->AppendString(base::WideToUTF16(argv[i]));
#else
    response->AppendString(argv[i]);
#endif
  }
  return true;
}

NwAppClearAppCacheFunction::NwAppClearAppCacheFunction() {
}

NwAppClearAppCacheFunction::~NwAppClearAppCacheFunction() {
}

bool NwAppClearAppCacheFunction::RunNWSync(base::ListValue* response, std::string* error) {
  std::string manifest;
  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &manifest));

  GURL manifest_url(manifest);
  scoped_refptr<browsing_data::CannedAppCacheHelper> helper(
       new browsing_data::CannedAppCacheHelper(browser_context()->GetDefaultStoragePartition()
                                                           ->GetAppCacheService()));

  helper->DeleteAppCaches(url::Origin::Create(manifest_url));
  return true;
}

NwAppClearCacheFunction::NwAppClearCacheFunction() {
}

NwAppClearCacheFunction::~NwAppClearCacheFunction() {
}

bool NwAppClearCacheFunction::RunNWSync(base::ListValue* response, std::string* error) {
  content::BrowsingDataRemover* remover =
    Profile::FromBrowserContext(browser_context())->GetBrowsingDataRemover();

  remover->AddObserver(this);
  remover->RemoveAndReply(base::Time(), base::Time::Max(),
                          content::BrowsingDataRemover::DATA_TYPE_CACHE,
                          content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
                          this);
  // BrowsingDataRemover deletes itself.
  base::CurrentThread::ScopedNestableTaskAllower allow;

  run_loop_.Run();
  remover->RemoveObserver(this);
  return true;
}

void NwAppClearCacheFunction::OnBrowsingDataRemoverDone(uint64_t failed_data_types) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  run_loop_.Quit();
}

NwAppSetProxyConfigFunction::NwAppSetProxyConfigFunction() {
}

NwAppSetProxyConfigFunction::~NwAppSetProxyConfigFunction() {
}

bool NwAppSetProxyConfigFunction::RunNWSync(base::ListValue* response, std::string* error) {
  net::ProxyConfigWithAnnotation config;
  std::unique_ptr<nwapi::nw__app::SetProxyConfig::Params> params(
      nwapi::nw__app::SetProxyConfig::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params.get());

  std::string pac_url = params->pac_url.get() ? *params->pac_url : "";
  if (!pac_url.empty()) {
    if (pac_url == "<direct>")
      config = net::ProxyConfigWithAnnotation::CreateDirect();
    else if (pac_url == "<auto>")
      config = net::ProxyConfigWithAnnotation(net::ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS);
    else
      config = net::ProxyConfigWithAnnotation(net::ProxyConfig::CreateFromCustomPacURL(GURL(pac_url)), TRAFFIC_ANNOTATION_FOR_TESTS);
  } else {
    std::string proxy_config;
    net::ProxyConfig pc;
    EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &proxy_config));
    pc.proxy_rules().ParseFromString(proxy_config);
    config = net::ProxyConfigWithAnnotation(pc, TRAFFIC_ANNOTATION_FOR_TESTS);
  }

  Profile* profile = Profile::FromBrowserContext(browser_context());
  auto* profile_network_context =
    ProfileNetworkContextServiceFactory::GetForContext(profile);
  profile_network_context->UpdateProxyConfig(config);
  return true;
}

bool NwAppGetDataPathFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
  response->AppendString(base::WideToUTF16(browser_context()->GetPath().value()));
#else
  response->AppendString(browser_context()->GetPath().value());
#endif
  return true;
}

ExtensionFunction::ResponseAction
NwAppCrashBrowserFunction::Run() {
  int* ptr = nullptr;
  *ptr = 1;
  return RespondNow(NoArguments());
}

} // namespace extensions
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Stephen Hines
 */

#ifndef __ARCH_ARM_TYPES_HH__
#define __ARCH_ARM_TYPES_HH__

#include "arch/generic/types.hh"
#include "base/bitunion.hh"
#include "base/hashmap.hh"
#include "base/misc.hh"
#include "base/types.hh"

namespace ArmISA
{
    typedef uint32_t MachInst;

    BitUnion64(ExtMachInst)
        Bitfield<63, 56> newItstate;
        // ITSTATE bits
        Bitfield<55, 48> itstate;
        Bitfield<55, 52> itstateCond;
        Bitfield<51, 48> itstateMask;

        // FPSCR fields
        Bitfield<41, 40> fpscrStride;
        Bitfield<39, 37> fpscrLen;

        // Bitfields to select mode.
        Bitfield<36>     thumb;
        Bitfield<35>     bigThumb;

        // Made up bitfields that make life easier.
        Bitfield<33>     sevenAndFour;
        Bitfield<32>     isMisc;

        uint32_t         instBits;

        // All the different types of opcode fields.
        Bitfield<27, 25> encoding;
        Bitfield<25>     useImm;
        Bitfield<24, 21> opcode;
        Bitfield<24, 20> mediaOpcode;
        Bitfield<24>     opcode24;
        Bitfield<24, 23> opcode24_23;
        Bitfield<23, 20> opcode23_20;
        Bitfield<23, 21> opcode23_21;
        Bitfield<20>     opcode20;
        Bitfield<22>     opcode22;
        Bitfield<19, 16> opcode19_16;
        Bitfield<19>     opcode19;
        Bitfield<18>     opcode18;
        Bitfield<15, 12> opcode15_12;
        Bitfield<15>     opcode15;
        Bitfield<7,  4>  miscOpcode;
        Bitfield<7,5>    opc2;
        Bitfield<7>      opcode7;
        Bitfield<6>      opcode6;
        Bitfield<4>      opcode4;

        Bitfield<31, 28> condCode;
        Bitfield<20>     sField;
        Bitfield<19, 16> rn;
        Bitfield<15, 12> rd;
        Bitfield<15, 12> rt;
        Bitfield<11, 7>  shiftSize;
        Bitfield<6,  5>  shift;
        Bitfield<3,  0>  rm;

        Bitfield<11, 8>  rs;

        SubBitUnion(puswl, 24, 20)
            Bitfield<24> prepost;
            Bitfield<23> up;
            Bitfield<22> psruser;
            Bitfield<21> writeback;
            Bitfield<20> loadOp;
        EndSubBitUnion(puswl)

        Bitfield<24, 20> pubwl;

        Bitfield<7, 0> imm;

        Bitfield<11, 8>  rotate;

        Bitfield<11, 0>  immed11_0;
        Bitfield<7,  0>  immed7_0;

        Bitfield<11, 8>  immedHi11_8;
        Bitfield<3,  0>  immedLo3_0;

        Bitfield<15, 0>  regList;

        Bitfield<23, 0>  offset;

        Bitfield<23, 0>  immed23_0;

        Bitfield<11, 8>  cpNum;
        Bitfield<18, 16> fn;
        Bitfield<14, 12> fd;
        Bitfield<3>      fpRegImm;
        Bitfield<3,  0>  fm;
        Bitfield<2,  0>  fpImm;
        Bitfield<24, 20> punwl;

        Bitfield<15,  8>  m5Func;

        // 16 bit thumb bitfields
        Bitfield<15, 13> topcode15_13;
        Bitfield<13, 11> topcode13_11;
        Bitfield<12, 11> topcode12_11;
        Bitfield<12, 10> topcode12_10;
        Bitfield<11, 9>  topcode11_9;
        Bitfield<11, 8>  topcode11_8;
        Bitfield<10, 9>  topcode10_9;
        Bitfield<10, 8>  topcode10_8;
        Bitfield<9,  6>  topcode9_6;
        Bitfield<7>      topcode7;
        Bitfield<7, 6>   topcode7_6;
        Bitfield<7, 5>   topcode7_5;
        Bitfield<7, 4>   topcode7_4;
        Bitfield<3, 0>   topcode3_0;

        // 32 bit thumb bitfields
        Bitfield<28, 27> htopcode12_11;
        Bitfield<26, 25> htopcode10_9;
        Bitfield<25>     htopcode9;
        Bitfield<25, 24> htopcode9_8;
        Bitfield<25, 21> htopcode9_5;
        Bitfield<25, 20> htopcode9_4;
        Bitfield<24>     htopcode8;
        Bitfield<24, 23> htopcode8_7;
        Bitfield<24, 22> htopcode8_6;
        Bitfield<24, 21> htopcode8_5;
        Bitfield<23>     htopcode7;
        Bitfield<23, 21> htopcode7_5;
        Bitfield<22>     htopcode6;
        Bitfield<22, 21> htopcode6_5;
        Bitfield<21, 20> htopcode5_4;
        Bitfield<20>     htopcode4;

        Bitfield<19, 16> htrn;
        Bitfield<20>     hts;

        Bitfield<15>     ltopcode15;
        Bitfield<11, 8>  ltopcode11_8;
        Bitfield<7,  6>  ltopcode7_6;
        Bitfield<7,  4>  ltopcode7_4;
        Bitfield<4>      ltopcode4;

        Bitfield<11, 8>  ltrd;
        Bitfield<11, 8>  ltcoproc;
    EndBitUnion(ExtMachInst)

    class PCState : public GenericISA::UPCState<MachInst>
    {
      protected:

        typedef GenericISA::UPCState<MachInst> Base;

        enum FlagBits {
            ThumbBit = (1 << 0),
            JazelleBit = (1 << 1)
        };
        uint8_t flags;
        uint8_t nextFlags;
        uint8_t forcedItStateValue;
        bool forcedItStateValid;
      public:
        PCState() : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
        {}

        void
        set(Addr val)
        {
            Base::set(val);
            npc(val + (thumb() ? 2 : 4));
        }

        PCState(Addr val) : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
        { set(val); }

        bool
        thumb() const
        {
            return flags & ThumbBit;
        }

        void
        thumb(bool val)
        {
            if (val)
                flags |= ThumbBit;
            else
                flags &= ~ThumbBit;
        }

        bool
        nextThumb() const
        {
            return nextFlags & ThumbBit;
        }

        void
        nextThumb(bool val)
        {
            if (val)
                nextFlags |= ThumbBit;
            else
                nextFlags &= ~ThumbBit;
        }

        bool
        jazelle() const
        {
            return flags & JazelleBit;
        }

        void
        jazelle(bool val)
        {
            if (val)
                flags |= JazelleBit;
            else
                flags &= ~JazelleBit;
        }

        bool
        nextJazelle() const
        {
            return nextFlags & JazelleBit;
        }

        void
        nextJazelle(bool val)
        {
            if (val)
                nextFlags |= JazelleBit;
            else
                nextFlags &= ~JazelleBit;
        }

        uint8_t
        forcedItState() const
        {
            return forcedItStateValue;
        }

        void
        forcedItState(uint8_t value)
        {
            forcedItStateValue = value;
            // Not valid unless the advance is called.
            forcedItStateValid = false;
        }

        bool
        forcedItStateIsValid() const
        {
            return forcedItStateValid;
        }

        void
        advance()
        {
            Base::advance();
            npc(pc() + (thumb() ? 2 : 4));
            flags = nextFlags;

            // Validate the itState
            if (forcedItStateValue != 0 && !forcedItStateValid) {
                forcedItStateValid = true;
            } else {
                forcedItStateValid = false;
                forcedItStateValue = 0;
            }
        }

        void
        uEnd()
        {
            advance();
            upc(0);
            nupc(1);
        }

        Addr
        instPC() const
        {
            return pc() + (thumb() ? 4 : 8);
        }

        void
        instNPC(uint32_t val)
        {
            npc(val &~ mask(nextThumb() ? 1 : 2));
        }

        Addr
        instNPC() const
        {
            return npc();
        }

        // Perform an interworking branch.
        void
        instIWNPC(uint32_t val)
        {
            bool thumbEE = (thumb() && jazelle());

            Addr newPC = val;
            if (thumbEE) {
                if (bits(newPC, 0)) {
                    newPC = newPC & ~mask(1);
                } else {
                    panic("Bad thumbEE interworking branch address %#x.\n",
                            newPC);
                }
            } else {
                if (bits(newPC, 0)) {
                    nextThumb(true);
                    newPC = newPC & ~mask(1);
                } else if (!bits(newPC, 1)) {
                    nextThumb(false);
                } else {
                    warn("Bad interworking branch address %#x.\n", newPC);
                    // This state is UNPREDICTABLE in the ARM architecture
                    // The easy thing to do is just mask off the bit and
                    // stay in the current mode, so we'll do that.
                    newPC &= ~mask(2);
                }
            }
            npc(newPC);
        }

        // Perform an interworking branch in ARM mode, a regular branch
        // otherwise.
        void
        instAIWNPC(uint32_t val)
        {
            if (!thumb() && !jazelle())
                instIWNPC(val);
            else
                instNPC(val);
        }

        bool
        operator == (const PCState &opc) const
        {
            return Base::operator == (opc) &&
                flags == opc.flags && nextFlags == opc.nextFlags;
        }

        void
        serialize(std::ostream &os)
        {
            Base::serialize(os);
            SERIALIZE_SCALAR(flags);
            SERIALIZE_SCALAR(nextFlags);
            SERIALIZE_SCALAR(forcedItStateValue);
            SERIALIZE_SCALAR(forcedItStateValid);
        }

        void
        unserialize(Checkpoint *cp, const std::string &section)
        {
            Base::unserialize(cp, section);
            UNSERIALIZE_SCALAR(flags);
            UNSERIALIZE_SCALAR(nextFlags);
            UNSERIALIZE_SCALAR(forcedItStateValue);
            UNSERIALIZE_SCALAR(forcedItStateValid);
        }
    };

    // Shift types for ARM instructions
    enum ArmShiftType {
        LSL = 0,
        LSR,
        ASR,
        ROR
    };

    typedef uint64_t LargestRead;
    // Need to use 64 bits to make sure that read requests get handled properly

    typedef int RegContextParam;
    typedef int RegContextVal;

    //used in FP convert & round function
    enum ConvertType{
        SINGLE_TO_DOUBLE,
        SINGLE_TO_WORD,
        SINGLE_TO_LONG,

        DOUBLE_TO_SINGLE,
        DOUBLE_TO_WORD,
        DOUBLE_TO_LONG,

        LONG_TO_SINGLE,
        LONG_TO_DOUBLE,
        LONG_TO_WORD,
        LONG_TO_PS,

        WORD_TO_SINGLE,
        WORD_TO_DOUBLE,
        WORD_TO_LONG,
        WORD_TO_PS,

        PL_TO_SINGLE,
        PU_TO_SINGLE
    };

    //used in FP convert & round function
    enum RoundMode{
        RND_ZERO,
        RND_DOWN,
        RND_UP,
        RND_NEAREST
    };

    enum OperatingMode {
        MODE_USER = 16,
        MODE_FIQ = 17,
        MODE_IRQ = 18,
        MODE_SVC = 19,
        MODE_MON = 22,
        MODE_ABORT = 23,
        MODE_UNDEFINED = 27,
        MODE_SYSTEM = 31,
        MODE_MAXMODE = MODE_SYSTEM
    };

    static inline bool
    badMode(OperatingMode mode)
    {
        switch (mode) {
          case MODE_USER:
          case MODE_FIQ:
          case MODE_IRQ:
          case MODE_SVC:
          case MODE_MON:
          case MODE_ABORT:
          case MODE_UNDEFINED:
          case MODE_SYSTEM:
            return false;
          default:
            return true;
        }
    }

    struct CoreSpecific {
        // Empty for now on the ARM
    };

} // namespace ArmISA

namespace __hash_namespace {
    template<>
    struct hash<ArmISA::ExtMachInst> : public hash<uint32_t> {
        size_t operator()(const ArmISA::ExtMachInst &emi) const {
            return hash<uint32_t>::operator()((uint32_t)emi);
        };
    };
}

#endif
<commit_msg>ARM: Bad interworking warn way to noisy when running real code w/misspeculation.<commit_after>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Stephen Hines
 */

#ifndef __ARCH_ARM_TYPES_HH__
#define __ARCH_ARM_TYPES_HH__

#include "arch/generic/types.hh"
#include "base/bitunion.hh"
#include "base/hashmap.hh"
#include "base/misc.hh"
#include "base/types.hh"

namespace ArmISA
{
    typedef uint32_t MachInst;

    BitUnion64(ExtMachInst)
        Bitfield<63, 56> newItstate;
        // ITSTATE bits
        Bitfield<55, 48> itstate;
        Bitfield<55, 52> itstateCond;
        Bitfield<51, 48> itstateMask;

        // FPSCR fields
        Bitfield<41, 40> fpscrStride;
        Bitfield<39, 37> fpscrLen;

        // Bitfields to select mode.
        Bitfield<36>     thumb;
        Bitfield<35>     bigThumb;

        // Made up bitfields that make life easier.
        Bitfield<33>     sevenAndFour;
        Bitfield<32>     isMisc;

        uint32_t         instBits;

        // All the different types of opcode fields.
        Bitfield<27, 25> encoding;
        Bitfield<25>     useImm;
        Bitfield<24, 21> opcode;
        Bitfield<24, 20> mediaOpcode;
        Bitfield<24>     opcode24;
        Bitfield<24, 23> opcode24_23;
        Bitfield<23, 20> opcode23_20;
        Bitfield<23, 21> opcode23_21;
        Bitfield<20>     opcode20;
        Bitfield<22>     opcode22;
        Bitfield<19, 16> opcode19_16;
        Bitfield<19>     opcode19;
        Bitfield<18>     opcode18;
        Bitfield<15, 12> opcode15_12;
        Bitfield<15>     opcode15;
        Bitfield<7,  4>  miscOpcode;
        Bitfield<7,5>    opc2;
        Bitfield<7>      opcode7;
        Bitfield<6>      opcode6;
        Bitfield<4>      opcode4;

        Bitfield<31, 28> condCode;
        Bitfield<20>     sField;
        Bitfield<19, 16> rn;
        Bitfield<15, 12> rd;
        Bitfield<15, 12> rt;
        Bitfield<11, 7>  shiftSize;
        Bitfield<6,  5>  shift;
        Bitfield<3,  0>  rm;

        Bitfield<11, 8>  rs;

        SubBitUnion(puswl, 24, 20)
            Bitfield<24> prepost;
            Bitfield<23> up;
            Bitfield<22> psruser;
            Bitfield<21> writeback;
            Bitfield<20> loadOp;
        EndSubBitUnion(puswl)

        Bitfield<24, 20> pubwl;

        Bitfield<7, 0> imm;

        Bitfield<11, 8>  rotate;

        Bitfield<11, 0>  immed11_0;
        Bitfield<7,  0>  immed7_0;

        Bitfield<11, 8>  immedHi11_8;
        Bitfield<3,  0>  immedLo3_0;

        Bitfield<15, 0>  regList;

        Bitfield<23, 0>  offset;

        Bitfield<23, 0>  immed23_0;

        Bitfield<11, 8>  cpNum;
        Bitfield<18, 16> fn;
        Bitfield<14, 12> fd;
        Bitfield<3>      fpRegImm;
        Bitfield<3,  0>  fm;
        Bitfield<2,  0>  fpImm;
        Bitfield<24, 20> punwl;

        Bitfield<15,  8>  m5Func;

        // 16 bit thumb bitfields
        Bitfield<15, 13> topcode15_13;
        Bitfield<13, 11> topcode13_11;
        Bitfield<12, 11> topcode12_11;
        Bitfield<12, 10> topcode12_10;
        Bitfield<11, 9>  topcode11_9;
        Bitfield<11, 8>  topcode11_8;
        Bitfield<10, 9>  topcode10_9;
        Bitfield<10, 8>  topcode10_8;
        Bitfield<9,  6>  topcode9_6;
        Bitfield<7>      topcode7;
        Bitfield<7, 6>   topcode7_6;
        Bitfield<7, 5>   topcode7_5;
        Bitfield<7, 4>   topcode7_4;
        Bitfield<3, 0>   topcode3_0;

        // 32 bit thumb bitfields
        Bitfield<28, 27> htopcode12_11;
        Bitfield<26, 25> htopcode10_9;
        Bitfield<25>     htopcode9;
        Bitfield<25, 24> htopcode9_8;
        Bitfield<25, 21> htopcode9_5;
        Bitfield<25, 20> htopcode9_4;
        Bitfield<24>     htopcode8;
        Bitfield<24, 23> htopcode8_7;
        Bitfield<24, 22> htopcode8_6;
        Bitfield<24, 21> htopcode8_5;
        Bitfield<23>     htopcode7;
        Bitfield<23, 21> htopcode7_5;
        Bitfield<22>     htopcode6;
        Bitfield<22, 21> htopcode6_5;
        Bitfield<21, 20> htopcode5_4;
        Bitfield<20>     htopcode4;

        Bitfield<19, 16> htrn;
        Bitfield<20>     hts;

        Bitfield<15>     ltopcode15;
        Bitfield<11, 8>  ltopcode11_8;
        Bitfield<7,  6>  ltopcode7_6;
        Bitfield<7,  4>  ltopcode7_4;
        Bitfield<4>      ltopcode4;

        Bitfield<11, 8>  ltrd;
        Bitfield<11, 8>  ltcoproc;
    EndBitUnion(ExtMachInst)

    class PCState : public GenericISA::UPCState<MachInst>
    {
      protected:

        typedef GenericISA::UPCState<MachInst> Base;

        enum FlagBits {
            ThumbBit = (1 << 0),
            JazelleBit = (1 << 1)
        };
        uint8_t flags;
        uint8_t nextFlags;
        uint8_t forcedItStateValue;
        bool forcedItStateValid;
      public:
        PCState() : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
        {}

        void
        set(Addr val)
        {
            Base::set(val);
            npc(val + (thumb() ? 2 : 4));
        }

        PCState(Addr val) : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
        { set(val); }

        bool
        thumb() const
        {
            return flags & ThumbBit;
        }

        void
        thumb(bool val)
        {
            if (val)
                flags |= ThumbBit;
            else
                flags &= ~ThumbBit;
        }

        bool
        nextThumb() const
        {
            return nextFlags & ThumbBit;
        }

        void
        nextThumb(bool val)
        {
            if (val)
                nextFlags |= ThumbBit;
            else
                nextFlags &= ~ThumbBit;
        }

        bool
        jazelle() const
        {
            return flags & JazelleBit;
        }

        void
        jazelle(bool val)
        {
            if (val)
                flags |= JazelleBit;
            else
                flags &= ~JazelleBit;
        }

        bool
        nextJazelle() const
        {
            return nextFlags & JazelleBit;
        }

        void
        nextJazelle(bool val)
        {
            if (val)
                nextFlags |= JazelleBit;
            else
                nextFlags &= ~JazelleBit;
        }

        uint8_t
        forcedItState() const
        {
            return forcedItStateValue;
        }

        void
        forcedItState(uint8_t value)
        {
            forcedItStateValue = value;
            // Not valid unless the advance is called.
            forcedItStateValid = false;
        }

        bool
        forcedItStateIsValid() const
        {
            return forcedItStateValid;
        }

        void
        advance()
        {
            Base::advance();
            npc(pc() + (thumb() ? 2 : 4));
            flags = nextFlags;

            // Validate the itState
            if (forcedItStateValue != 0 && !forcedItStateValid) {
                forcedItStateValid = true;
            } else {
                forcedItStateValid = false;
                forcedItStateValue = 0;
            }
        }

        void
        uEnd()
        {
            advance();
            upc(0);
            nupc(1);
        }

        Addr
        instPC() const
        {
            return pc() + (thumb() ? 4 : 8);
        }

        void
        instNPC(uint32_t val)
        {
            npc(val &~ mask(nextThumb() ? 1 : 2));
        }

        Addr
        instNPC() const
        {
            return npc();
        }

        // Perform an interworking branch.
        void
        instIWNPC(uint32_t val)
        {
            bool thumbEE = (thumb() && jazelle());

            Addr newPC = val;
            if (thumbEE) {
                if (bits(newPC, 0)) {
                    newPC = newPC & ~mask(1);
                } else {
                    panic("Bad thumbEE interworking branch address %#x.\n",
                            newPC);
                }
            } else {
                if (bits(newPC, 0)) {
                    nextThumb(true);
                    newPC = newPC & ~mask(1);
                } else if (!bits(newPC, 1)) {
                    nextThumb(false);
                } else {
                    // This state is UNPREDICTABLE in the ARM architecture
                    // The easy thing to do is just mask off the bit and
                    // stay in the current mode, so we'll do that.
                    newPC &= ~mask(2);
                }
            }
            npc(newPC);
        }

        // Perform an interworking branch in ARM mode, a regular branch
        // otherwise.
        void
        instAIWNPC(uint32_t val)
        {
            if (!thumb() && !jazelle())
                instIWNPC(val);
            else
                instNPC(val);
        }

        bool
        operator == (const PCState &opc) const
        {
            return Base::operator == (opc) &&
                flags == opc.flags && nextFlags == opc.nextFlags;
        }

        void
        serialize(std::ostream &os)
        {
            Base::serialize(os);
            SERIALIZE_SCALAR(flags);
            SERIALIZE_SCALAR(nextFlags);
            SERIALIZE_SCALAR(forcedItStateValue);
            SERIALIZE_SCALAR(forcedItStateValid);
        }

        void
        unserialize(Checkpoint *cp, const std::string &section)
        {
            Base::unserialize(cp, section);
            UNSERIALIZE_SCALAR(flags);
            UNSERIALIZE_SCALAR(nextFlags);
            UNSERIALIZE_SCALAR(forcedItStateValue);
            UNSERIALIZE_SCALAR(forcedItStateValid);
        }
    };

    // Shift types for ARM instructions
    enum ArmShiftType {
        LSL = 0,
        LSR,
        ASR,
        ROR
    };

    typedef uint64_t LargestRead;
    // Need to use 64 bits to make sure that read requests get handled properly

    typedef int RegContextParam;
    typedef int RegContextVal;

    //used in FP convert & round function
    enum ConvertType{
        SINGLE_TO_DOUBLE,
        SINGLE_TO_WORD,
        SINGLE_TO_LONG,

        DOUBLE_TO_SINGLE,
        DOUBLE_TO_WORD,
        DOUBLE_TO_LONG,

        LONG_TO_SINGLE,
        LONG_TO_DOUBLE,
        LONG_TO_WORD,
        LONG_TO_PS,

        WORD_TO_SINGLE,
        WORD_TO_DOUBLE,
        WORD_TO_LONG,
        WORD_TO_PS,

        PL_TO_SINGLE,
        PU_TO_SINGLE
    };

    //used in FP convert & round function
    enum RoundMode{
        RND_ZERO,
        RND_DOWN,
        RND_UP,
        RND_NEAREST
    };

    enum OperatingMode {
        MODE_USER = 16,
        MODE_FIQ = 17,
        MODE_IRQ = 18,
        MODE_SVC = 19,
        MODE_MON = 22,
        MODE_ABORT = 23,
        MODE_UNDEFINED = 27,
        MODE_SYSTEM = 31,
        MODE_MAXMODE = MODE_SYSTEM
    };

    static inline bool
    badMode(OperatingMode mode)
    {
        switch (mode) {
          case MODE_USER:
          case MODE_FIQ:
          case MODE_IRQ:
          case MODE_SVC:
          case MODE_MON:
          case MODE_ABORT:
          case MODE_UNDEFINED:
          case MODE_SYSTEM:
            return false;
          default:
            return true;
        }
    }

    struct CoreSpecific {
        // Empty for now on the ARM
    };

} // namespace ArmISA

namespace __hash_namespace {
    template<>
    struct hash<ArmISA::ExtMachInst> : public hash<uint32_t> {
        size_t operator()(const ArmISA::ExtMachInst &emi) const {
            return hash<uint32_t>::operator()((uint32_t)emi);
        };
    };
}

#endif
<|endoftext|>


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

#include <batchedlogger.h>

CBatchedLogger::CBatchedLogger(BCLog::LogFlags _category, const std::string& _header) :
    accept(LogAcceptCategory(_category)), header(_header)
{
}

CBatchedLogger::~CBatchedLogger()
{
    Flush();
}

void CBatchedLogger::Flush()
{
    if (!accept || msg.empty()) {
        return;
    }
    LogInstance().LogPrintStr(strprintf("%s:\n%s", header, msg), "", "" 0);
    msg.clear();
}
<commit_msg>Update batchedlogger.cpp<commit_after>// Copyright (c) 2018-2019 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <batchedlogger.h>

CBatchedLogger::CBatchedLogger(BCLog::LogFlags _category, const std::string& _header) :
    accept(LogAcceptCategory(_category)), header(_header)
{
}

CBatchedLogger::~CBatchedLogger()
{
    Flush();
}

void CBatchedLogger::Flush()
{
    if (!accept || msg.empty()) {
        return;
    }
    LogInstance().LogPrintStr(strprintf("%s:\n%s", header, msg), "", "", 0);
    msg.clear();
}
<|endoftext|>