<commit_before>/*
 Utility tests.

 Copyright (c) 2012-2014, Victor Zverovich
 All rights reserved.

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

 1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
 2. 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 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.
 */

#include <cstring>
#include <limits>
#include "gtest-extra.h"
#include "util.h"

// Check if format.h compiles with windows.h included.
#ifdef _WIN32
# include <windows.h>
#endif

#include "format.h"

#undef max

using fmt::StringRef;

namespace {
std::string GetSystemErrorMessage(int error_code) {
#if defined(__MINGW32__) || !defined(_WIN32)
  return strerror(error_code);
#else
  enum { BUFFER_SIZE = 200 };
  char buffer[BUFFER_SIZE];
  EXPECT_EQ(0, strerror_s(buffer, BUFFER_SIZE, error_code));
  std::size_t max_len = BUFFER_SIZE - 1;
  EXPECT_LT(std::strlen(buffer), max_len);
  return buffer;
#endif
}
}

TEST(UtilTest, Increment) {
  char s[10] = "123";
  Increment(s);
  EXPECT_STREQ("124", s);
  s[2] = '8';
  Increment(s);
  EXPECT_STREQ("129", s);
  Increment(s);
  EXPECT_STREQ("130", s);
  s[1] = s[2] = '9';
  Increment(s);
  EXPECT_STREQ("200", s);
}

// Tests fmt::internal::CountDigits for integer type Int.
template <typename Int>
void TestCountDigits(Int) {
  for (Int i = 0; i < 10; ++i)
          EXPECT_EQ(1u, fmt::internal::CountDigits(i));
  for (Int i = 1, n = 1,
               end = std::numeric_limits<Int>::max() / 10; n <= end; ++i) {
    n *= 10;
    EXPECT_EQ(i, fmt::internal::CountDigits(n - 1));
    EXPECT_EQ(i + 1, fmt::internal::CountDigits(n));
  }
}

TEST(UtilTest, CountDigits) {
  TestCountDigits(uint32_t());
  TestCountDigits(uint64_t());
}

#ifdef _WIN32
TEST(UtilTest, UTF16ToUTF8) {
  std::string s = "ёжик";
  fmt::internal::UTF16ToUTF8 u(L"\x0451\x0436\x0438\x043A");
  EXPECT_EQ(s, fmt::str(u));
  EXPECT_EQ(s.size(), u.size());
}

TEST(UtilTest, UTF8ToUTF16) {
  std::string s = "лошадка";
  fmt::internal::UTF8ToUTF16 u(s.c_str());
  EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", fmt::str(u));
  EXPECT_EQ(7, u.size());
}

template <typename Converter>
void CheckUTFConversionError(const char *message) {
  fmt::Writer out;
  fmt::internal::FormatWinErrorMessage(out, ERROR_INVALID_PARAMETER, message);
  fmt::SystemError error("", 0);
  try {
    Converter(0);
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code());
  EXPECT_EQ(out.str(), error.what());
}

TEST(UtilTest, UTF16ToUTF8Error) {
  CheckUTFConversionError<fmt::internal::UTF16ToUTF8>(
      "cannot convert string from UTF-16 to UTF-8");
}

TEST(UtilTest, UTF8ToUTF16Error) {
  CheckUTFConversionError<fmt::internal::UTF8ToUTF16>(
      "cannot convert string from UTF-8 to UTF-16");
}

TEST(UtilTest, UTF16ToUTF8Convert) {
  fmt::internal::UTF16ToUTF8 u;
  EXPECT_EQ(ERROR_INVALID_PARAMETER, u.Convert(0));
}
#endif  // _WIN32

TEST(UtilTest, StrError) {
  using fmt::internal::StrError;
  char *message = 0;
  char buffer[BUFFER_SIZE];
#ifndef NDEBUG
  EXPECT_DEBUG_DEATH(StrError(EDOM, message = 0, 0), "Assertion");
  EXPECT_DEBUG_DEATH(StrError(EDOM, message = buffer, 0), "Assertion");
#endif
  buffer[0] = 'x';
#ifdef _GNU_SOURCE
  // Use invalid error code to make sure that StrError returns an error
  // message in the buffer rather than a pointer to a static string.
  int error_code = -1;
#else
  int error_code = EDOM;
#endif
  int result = StrError(error_code, message = buffer, 1);
  EXPECT_EQ(buffer, message);  // Message should point to buffer.
  EXPECT_EQ(ERANGE, result);
  EXPECT_STREQ("", message);
  result = StrError(error_code, message = buffer, BUFFER_SIZE);
  EXPECT_EQ(0, result);
  std::size_t message_size = std::strlen(message);
  EXPECT_GE(BUFFER_SIZE - 1u, message_size);
  EXPECT_EQ(GetSystemErrorMessage(error_code), message);
  result = StrError(error_code, message = buffer, message_size);
  EXPECT_EQ(ERANGE, result);
}

TEST(UtilTest, SystemError) {
  fmt::SystemError e(EDOM, "test");
  EXPECT_EQ(fmt::format("test: {}", GetSystemErrorMessage(EDOM)), e.what());
  EXPECT_EQ(EDOM, e.error_code());
}

typedef void (*FormatErrorMessage)(
        fmt::Writer &out, int error_code, StringRef message);

template <typename Sink>
void CheckErrorSink(int error_code, FormatErrorMessage format) {
  fmt::SystemError error(0, "");
  Sink sink(error_code);
  fmt::Writer w;
  w << "test";
  try {
    sink(w);
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  fmt::Writer message;
  format(message, error_code, "test");
  EXPECT_EQ(message.str(), error.what());
  EXPECT_EQ(error_code, error.error_code());
}

template <typename Error>
void CheckThrowError(int error_code, FormatErrorMessage format) {
  fmt::SystemError error(0, "");
  try {
    throw Error(error_code, "test {}", "error");
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  fmt::Writer message;
  format(message, error_code, "test error");
  EXPECT_EQ(message.str(), error.what());
  EXPECT_EQ(error_code, error.error_code());
}

TEST(UtilTest, FormatSystemErrorMessage) {
  fmt::Writer message;
  fmt::internal::FormatSystemErrorMessage(message, EDOM, "test");
  EXPECT_EQ(fmt::format("test: {}",
          GetSystemErrorMessage(EDOM)), message.str());
}

TEST(UtilTest, SystemErrorSink) {
  CheckErrorSink<fmt::SystemErrorSink>(
          EDOM, fmt::internal::FormatSystemErrorMessage);
}

TEST(UtilTest, ThrowSystemError) {
  CheckThrowError<fmt::SystemError>(EDOM, fmt::internal::FormatSystemErrorMessage);
}

TEST(UtilTest, ReportSystemError) {
  fmt::Writer out;
  fmt::internal::FormatSystemErrorMessage(out, EDOM, "test error");
  out << '\n';
  EXPECT_WRITE(stderr, fmt::ReportSystemError(EDOM, "test error"), out.str());
}

#ifdef _WIN32

TEST(UtilTest, FormatWinErrorMessage) {
  LPWSTR message = 0;
  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
      ERROR_FILE_EXISTS, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      reinterpret_cast<LPWSTR>(&message), 0, 0);
  fmt::internal::UTF16ToUTF8 utf8_message(message);
  LocalFree(message);
  fmt::Writer actual_message;
  fmt::internal::FormatWinErrorMessage(
      actual_message, ERROR_FILE_EXISTS, "test");
  EXPECT_EQ(fmt::format("test: {}", fmt::str(utf8_message)),
      fmt::str(actual_message));
}

TEST(UtilTest, WinErrorSink) {
  CheckErrorSink<fmt::WinErrorSink>(
      ERROR_FILE_EXISTS, fmt::internal::FormatWinErrorMessage);
}

TEST(UtilTest, ThrowWinError) {
  CheckThrowError<fmt::WindowsError>(
      ERROR_FILE_EXISTS, fmt::internal::FormatWinErrorMessage);
}

TEST(UtilTest, ReportWinError) {
  fmt::Writer out;
  fmt::internal::FormatWinErrorMessage(out, ERROR_FILE_EXISTS, "test error");
  out << '\n';
  EXPECT_WRITE(stderr,
      fmt::ReportWinError(ERROR_FILE_EXISTS, "test error"), out.str());
}

#endif  // _WIN32
<commit_msg>Fix one more Windows issue.<commit_after>/*
 Utility tests.

 Copyright (c) 2012-2014, Victor Zverovich
 All rights reserved.

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

 1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
 2. 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 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.
 */

#include <cstring>
#include <limits>
#include "gtest-extra.h"
#include "util.h"

// Check if format.h compiles with windows.h included.
#ifdef _WIN32
# include <windows.h>
#endif

#include "format.h"

#undef max

using fmt::StringRef;

namespace {
std::string GetSystemErrorMessage(int error_code) {
#if defined(__MINGW32__) || !defined(_WIN32)
  return strerror(error_code);
#else
  enum { BUFFER_SIZE = 200 };
  char buffer[BUFFER_SIZE];
  EXPECT_EQ(0, strerror_s(buffer, BUFFER_SIZE, error_code));
  std::size_t max_len = BUFFER_SIZE - 1;
  EXPECT_LT(std::strlen(buffer), max_len);
  return buffer;
#endif
}
}

TEST(UtilTest, Increment) {
  char s[10] = "123";
  Increment(s);
  EXPECT_STREQ("124", s);
  s[2] = '8';
  Increment(s);
  EXPECT_STREQ("129", s);
  Increment(s);
  EXPECT_STREQ("130", s);
  s[1] = s[2] = '9';
  Increment(s);
  EXPECT_STREQ("200", s);
}

// Tests fmt::internal::CountDigits for integer type Int.
template <typename Int>
void TestCountDigits(Int) {
  for (Int i = 0; i < 10; ++i)
          EXPECT_EQ(1u, fmt::internal::CountDigits(i));
  for (Int i = 1, n = 1,
               end = std::numeric_limits<Int>::max() / 10; n <= end; ++i) {
    n *= 10;
    EXPECT_EQ(i, fmt::internal::CountDigits(n - 1));
    EXPECT_EQ(i + 1, fmt::internal::CountDigits(n));
  }
}

TEST(UtilTest, CountDigits) {
  TestCountDigits(uint32_t());
  TestCountDigits(uint64_t());
}

#ifdef _WIN32
TEST(UtilTest, UTF16ToUTF8) {
  std::string s = "ёжик";
  fmt::internal::UTF16ToUTF8 u(L"\x0451\x0436\x0438\x043A");
  EXPECT_EQ(s, fmt::str(u));
  EXPECT_EQ(s.size(), u.size());
}

TEST(UtilTest, UTF8ToUTF16) {
  std::string s = "лошадка";
  fmt::internal::UTF8ToUTF16 u(s.c_str());
  EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", fmt::str(u));
  EXPECT_EQ(7, u.size());
}

template <typename Converter>
void CheckUTFConversionError(const char *message) {
  fmt::Writer out;
  fmt::internal::FormatWinErrorMessage(out, ERROR_INVALID_PARAMETER, message);
  fmt::SystemError error(0, "");
  try {
    Converter(0);
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code());
  EXPECT_EQ(out.str(), error.what());
}

TEST(UtilTest, UTF16ToUTF8Error) {
  CheckUTFConversionError<fmt::internal::UTF16ToUTF8>(
      "cannot convert string from UTF-16 to UTF-8");
}

TEST(UtilTest, UTF8ToUTF16Error) {
  CheckUTFConversionError<fmt::internal::UTF8ToUTF16>(
      "cannot convert string from UTF-8 to UTF-16");
}

TEST(UtilTest, UTF16ToUTF8Convert) {
  fmt::internal::UTF16ToUTF8 u;
  EXPECT_EQ(ERROR_INVALID_PARAMETER, u.Convert(0));
}
#endif  // _WIN32

TEST(UtilTest, StrError) {
  using fmt::internal::StrError;
  char *message = 0;
  char buffer[BUFFER_SIZE];
#ifndef NDEBUG
  EXPECT_DEBUG_DEATH(StrError(EDOM, message = 0, 0), "Assertion");
  EXPECT_DEBUG_DEATH(StrError(EDOM, message = buffer, 0), "Assertion");
#endif
  buffer[0] = 'x';
#ifdef _GNU_SOURCE
  // Use invalid error code to make sure that StrError returns an error
  // message in the buffer rather than a pointer to a static string.
  int error_code = -1;
#else
  int error_code = EDOM;
#endif
  int result = StrError(error_code, message = buffer, 1);
  EXPECT_EQ(buffer, message);  // Message should point to buffer.
  EXPECT_EQ(ERANGE, result);
  EXPECT_STREQ("", message);
  result = StrError(error_code, message = buffer, BUFFER_SIZE);
  EXPECT_EQ(0, result);
  std::size_t message_size = std::strlen(message);
  EXPECT_GE(BUFFER_SIZE - 1u, message_size);
  EXPECT_EQ(GetSystemErrorMessage(error_code), message);
  result = StrError(error_code, message = buffer, message_size);
  EXPECT_EQ(ERANGE, result);
}

TEST(UtilTest, SystemError) {
  fmt::SystemError e(EDOM, "test");
  EXPECT_EQ(fmt::format("test: {}", GetSystemErrorMessage(EDOM)), e.what());
  EXPECT_EQ(EDOM, e.error_code());
}

typedef void (*FormatErrorMessage)(
        fmt::Writer &out, int error_code, StringRef message);

template <typename Sink>
void CheckErrorSink(int error_code, FormatErrorMessage format) {
  fmt::SystemError error(0, "");
  Sink sink(error_code);
  fmt::Writer w;
  w << "test";
  try {
    sink(w);
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  fmt::Writer message;
  format(message, error_code, "test");
  EXPECT_EQ(message.str(), error.what());
  EXPECT_EQ(error_code, error.error_code());
}

template <typename Error>
void CheckThrowError(int error_code, FormatErrorMessage format) {
  fmt::SystemError error(0, "");
  try {
    throw Error(error_code, "test {}", "error");
  } catch (const fmt::SystemError &e) {
    error = e;
  }
  fmt::Writer message;
  format(message, error_code, "test error");
  EXPECT_EQ(message.str(), error.what());
  EXPECT_EQ(error_code, error.error_code());
}

TEST(UtilTest, FormatSystemErrorMessage) {
  fmt::Writer message;
  fmt::internal::FormatSystemErrorMessage(message, EDOM, "test");
  EXPECT_EQ(fmt::format("test: {}",
          GetSystemErrorMessage(EDOM)), message.str());
}

TEST(UtilTest, SystemErrorSink) {
  CheckErrorSink<fmt::SystemErrorSink>(
          EDOM, fmt::internal::FormatSystemErrorMessage);
}

TEST(UtilTest, ThrowSystemError) {
  CheckThrowError<fmt::SystemError>(EDOM, fmt::internal::FormatSystemErrorMessage);
}

TEST(UtilTest, ReportSystemError) {
  fmt::Writer out;
  fmt::internal::FormatSystemErrorMessage(out, EDOM, "test error");
  out << '\n';
  EXPECT_WRITE(stderr, fmt::ReportSystemError(EDOM, "test error"), out.str());
}

#ifdef _WIN32

TEST(UtilTest, FormatWinErrorMessage) {
  LPWSTR message = 0;
  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
      ERROR_FILE_EXISTS, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      reinterpret_cast<LPWSTR>(&message), 0, 0);
  fmt::internal::UTF16ToUTF8 utf8_message(message);
  LocalFree(message);
  fmt::Writer actual_message;
  fmt::internal::FormatWinErrorMessage(
      actual_message, ERROR_FILE_EXISTS, "test");
  EXPECT_EQ(fmt::format("test: {}", fmt::str(utf8_message)),
      fmt::str(actual_message));
}

TEST(UtilTest, WinErrorSink) {
  CheckErrorSink<fmt::WinErrorSink>(
      ERROR_FILE_EXISTS, fmt::internal::FormatWinErrorMessage);
}

TEST(UtilTest, ThrowWinError) {
  CheckThrowError<fmt::WindowsError>(
      ERROR_FILE_EXISTS, fmt::internal::FormatWinErrorMessage);
}

TEST(UtilTest, ReportWinError) {
  fmt::Writer out;
  fmt::internal::FormatWinErrorMessage(out, ERROR_FILE_EXISTS, "test error");
  out << '\n';
  EXPECT_WRITE(stderr,
      fmt::ReportWinError(ERROR_FILE_EXISTS, "test error"), out.str());
}

#endif  // _WIN32
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file InverseMouseArea.cpp
 * @author Yann yann@ethdev.com
 * @date 2015
 * Ethereum IDE client.
 */

#include <QQuickWindow>
#include <QDebug>
#include <QQuickItem>
#include <QGraphicsSceneMouseEvent>
#include "InverseMouseArea.h"

using namespace dev::mix;

void InverseMouseArea::itemChange(ItemChange _c, const ItemChangeData& _v)
{
	if (!this->m_active)
		return;
	Q_UNUSED(_v);
	if (_c == ItemSceneChange && window())
		window()->installEventFilter(this);
}

bool InverseMouseArea::eventFilter(QObject* _obj, QEvent* _ev)
{
	if (!this->m_active)
		return false;
	Q_UNUSED(_obj);
	if (_ev->type() == QEvent::MouseButtonPress && !this->contains(static_cast<QMouseEvent*>(_ev)->pos()))
		emit clickedOutside();
	return false;
}

bool InverseMouseArea::contains(const QPoint& _point) const
{
	if (!this->m_active)
		return false;
	QPointF global = this->parentItem()->mapToItem(0, QPointF(0, 0));
	return QRectF(global.x(), global.y(), this->parentItem()->width(), this->parentItem()->height()).contains(_point);
}

void InverseMouseArea::setActive(bool _v)
{
	m_active = _v;
	if (m_active && window())
		window()->installEventFilter(this);
}
<commit_msg>small changes<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file InverseMouseArea.cpp
 * @author Yann yann@ethdev.com
 * @date 2015
 * Ethereum IDE client.
 */

#include <QQuickWindow>
#include <QDebug>
#include <QQuickItem>
#include <QGraphicsSceneMouseEvent>
#include "InverseMouseArea.h"

using namespace dev::mix;

void InverseMouseArea::itemChange(ItemChange _c, const ItemChangeData& _v)
{
	Q_UNUSED(_v);
	if (this->m_active && _c == ItemSceneChange && window())
		window()->installEventFilter(this);
}

bool InverseMouseArea::eventFilter(QObject* _obj, QEvent* _ev)
{
	Q_UNUSED(_obj);
	if (this->m_active && _ev->type() == QEvent::MouseButtonPress && !this->contains(static_cast<QMouseEvent*>(_ev)->pos()))
		emit clickedOutside();
	return false;
}

bool InverseMouseArea::contains(const QPoint& _point) const
{
	if (!this->m_active)
		return false;
	QPointF global = this->parentItem()->mapToItem(0, QPointF(0, 0));
	return QRectF(global.x(), global.y(), this->parentItem()->width(), this->parentItem()->height()).contains(_point);
}

void InverseMouseArea::setActive(bool _v)
{
	m_active = _v;
	if (m_active && window())
		window()->installEventFilter(this);
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SoundData.h"
#include "core/Engine.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace audio
    {
        SoundData::SoundData()
        {
        }

        SoundData::~SoundData()
        {
        }

        void SoundData::free()
        {
            data.clear();

            ready = false;
        }

        bool SoundData::initFromFile(const std::string& newFilename)
        {
            filename = newFilename;

            std::vector<uint8_t> newData;
            if (!sharedEngine->getFileSystem()->loadFile(newFilename, newData))
            {
                return false;
            }

            return initFromBuffer(newData);
        }

        bool SoundData::initFromBuffer(const std::vector<uint8_t>& newData)
        {
            ready = false;

            uint32_t offset = 0;

            if (newData.size() < 16) // RIFF + size + WAVE
            {
                log("Failed to load sound file. File too small");
                return false;
            }

            if (newData[offset + 0] != 'R' ||
                newData[offset + 1] != 'I' ||
                newData[offset + 2] != 'F' ||
                newData[offset + 3] != 'F')
            {
                log("Failed to load sound file. Not a RIFF format.");
                return false;
            }

            offset += 4;

            uint32_t length = *reinterpret_cast<const uint32_t*>(newData.data() + offset);

            offset += 4;

            if (newData.size() != length + 8)
            {
                log("Failed to load sound file. Size mismatch.");
            }

            if (newData[offset + 0] != 'W' ||
                newData[offset + 1] != 'A' ||
                newData[offset + 2] != 'V' ||
                newData[offset + 3] != 'E')
            {
                log("Failed to load sound file. Not a WAVE file.");
                return false;
            }

            offset += 4;

            bool foundChunkFound = false;

            for (uint32_t i = offset; i < newData.size();)
            {
                if (newData.size() < i + 8)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                char chunkHeader[4];
                chunkHeader[0] = newData[i + 0];
                chunkHeader[1] = newData[i + 1];
                chunkHeader[2] = newData[i + 2];
                chunkHeader[3] = newData[i + 3];

                i += 4;

                uint32_t chunkSize = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                i += 4;

                if (newData.size() < i + chunkSize)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                if (chunkHeader[0] == 'f' &&
                    chunkHeader[1] == 'm' &&
                    chunkHeader[2] == 't' &&
                    chunkHeader[3] == ' ')
                {
                    if (chunkSize < 16)
                    {
                        log("Failed to load sound file. Not enough data to read chunk.");
                        return false;
                    }

                    formatTag = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    if (formatTag != 1)
                    {
                        log("Failed to load sound file. Bad format tag.");
                        return false;
                    }

                    channels = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    samplesPerSecond = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                    i += 4;

                    averageBytesPerSecond = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                    i += 4;

                    blockAlign = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    bitsPerSample = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    foundChunkFound = true;
                    break;
                }

                i += (chunkSize + 1) & 0xFFFFFFFE;
            }

            if (!foundChunkFound)
            {
                log("Failed to load sound file. Failed to find a format chunk.");
                return false;
            }

            bool dataChunkFound = false;

            for (uint32_t i = offset; i < newData.size();)
            {
                if (newData.size() < i + 8)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                char chunkHeader[4];
                chunkHeader[0] = newData[i + 0];
                chunkHeader[1] = newData[i + 1];
                chunkHeader[2] = newData[i + 2];
                chunkHeader[3] = newData[i + 3];

                i += 4;

                uint32_t chunkSize = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                i += 4;

                if (newData.size() < i + chunkSize)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                if (chunkHeader[0] == 'd' &&
                    chunkHeader[1] == 'a' &&
                    chunkHeader[2] == 't' &&
                    chunkHeader[3] == 'a')
                {
                    data.assign(newData.begin() + i, newData.begin() + i + chunkSize);

                    dataChunkFound = true;
                    break;
                }

                i += (chunkSize + 1) & 0xFFFFFFFE;
            }

            if (!dataChunkFound)
            {
                log("Failed to load sound file. Failed to find a data chunk.");
                return false;
            }

            ready = true;

            return true;
        }
    } // namespace audio
} // namespace ouzel
<commit_msg>Simplify wav loading code<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SoundData.h"
#include "core/Engine.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace audio
    {
        SoundData::SoundData()
        {
        }

        SoundData::~SoundData()
        {
        }

        void SoundData::free()
        {
            data.clear();

            ready = false;
        }

        bool SoundData::initFromFile(const std::string& newFilename)
        {
            filename = newFilename;

            std::vector<uint8_t> newData;
            if (!sharedEngine->getFileSystem()->loadFile(newFilename, newData))
            {
                return false;
            }

            return initFromBuffer(newData);
        }

        bool SoundData::initFromBuffer(const std::vector<uint8_t>& newData)
        {
            ready = false;

            uint32_t offset = 0;

            if (newData.size() < 16) // RIFF + size + WAVE
            {
                log("Failed to load sound file. File too small");
                return false;
            }

            if (newData[offset + 0] != 'R' ||
                newData[offset + 1] != 'I' ||
                newData[offset + 2] != 'F' ||
                newData[offset + 3] != 'F')
            {
                log("Failed to load sound file. Not a RIFF format.");
                return false;
            }

            offset += 4;

            uint32_t length = *reinterpret_cast<const uint32_t*>(newData.data() + offset);

            offset += 4;

            if (newData.size() != length + 8)
            {
                log("Failed to load sound file. Size mismatch.");
            }

            if (newData[offset + 0] != 'W' ||
                newData[offset + 1] != 'A' ||
                newData[offset + 2] != 'V' ||
                newData[offset + 3] != 'E')
            {
                log("Failed to load sound file. Not a WAVE file.");
                return false;
            }

            offset += 4;

            bool foundChunkFound = false;
            bool dataChunkFound = false;

            for (; offset < newData.size();)
            {
                if (newData.size() < offset + 8)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                char chunkHeader[4];
                chunkHeader[0] = newData[offset + 0];
                chunkHeader[1] = newData[offset + 1];
                chunkHeader[2] = newData[offset + 2];
                chunkHeader[3] = newData[offset + 3];

                offset += 4;

                uint32_t chunkSize = *reinterpret_cast<const uint32_t*>(newData.data() + offset);
                offset += 4;

                if (newData.size() < offset + chunkSize)
                {
                    log("Failed to load sound file. Not enough data to read chunk.");
                    return false;
                }

                if (chunkHeader[0] == 'f' && chunkHeader[1] == 'm' && chunkHeader[2] == 't' && chunkHeader[3] == ' ')
                {
                    if (chunkSize < 16)
                    {
                        log("Failed to load sound file. Not enough data to read chunk.");
                        return false;
                    }

                    uint32_t i = offset;

                    formatTag = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    if (formatTag != 1)
                    {
                        log("Failed to load sound file. Bad format tag.");
                        return false;
                    }

                    channels = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    samplesPerSecond = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                    i += 4;

                    averageBytesPerSecond = *reinterpret_cast<const uint32_t*>(newData.data() + i);
                    i += 4;

                    blockAlign = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    bitsPerSample = *reinterpret_cast<const uint16_t*>(newData.data() + i);
                    i += 2;

                    foundChunkFound = true;
                }
                else if (chunkHeader[0] == 'd' && chunkHeader[1] == 'a' && chunkHeader[2] == 't' && chunkHeader[3] == 'a')
                {
                    data.assign(newData.begin() + offset, newData.begin() + offset + chunkSize);

                    dataChunkFound = true;
                }

                offset += ((chunkSize + 1) & 0xFFFFFFFE);
            }

            if (!foundChunkFound)
            {
                log("Failed to load sound file. Failed to find a format chunk.");
                return false;
            }

            if (!dataChunkFound)
            {
                log("Failed to load sound file. Failed to find a data chunk.");
                return false;
            }

            ready = true;

            return true;
        }
    } // namespace audio
} // namespace ouzel
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "chromeos/dbus/session_manager_client.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/string_util.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

// The SessionManagerClient implementation used in production.
class SessionManagerClientImpl : public SessionManagerClient {
 public:
  explicit SessionManagerClientImpl(dbus::Bus* bus)
      : session_manager_proxy_(NULL),
        screen_locked_(false),
        weak_ptr_factory_(this) {
    session_manager_proxy_ = bus->GetObjectProxy(
        login_manager::kSessionManagerServiceName,
        dbus::ObjectPath(login_manager::kSessionManagerServicePath));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kOwnerKeySetSignal,
        base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kPropertyChangeCompleteSignal,
        base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kLockScreenSignal,
        base::Bind(&SessionManagerClientImpl::ScreenLockReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kUnlockScreenSignal,
        base::Bind(&SessionManagerClientImpl::ScreenUnlockReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual ~SessionManagerClientImpl() {
  }

  // SessionManagerClient overrides:
  virtual void AddObserver(Observer* observer) OVERRIDE {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    observers_.RemoveObserver(observer);
  }

  virtual bool HasObserver(Observer* observer) OVERRIDE {
    return observers_.HasObserver(observer);
  }

  virtual void EmitLoginPromptReady() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerEmitLoginPromptReady);
  }

  virtual void EmitLoginPromptVisible() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerEmitLoginPromptVisible);
  }

  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerRestartJob);
    dbus::MessageWriter writer(&method_call);
    writer.AppendInt32(pid);
    writer.AppendString(command_line);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnRestartJob,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void RestartEntd() OVERRIDE {
    SimpleMethodCallToSessionManager(login_manager::kSessionManagerRestartEntd);
  }

  virtual void StartSession(const std::string& user_email) OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerStartSession);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(user_email);
    writer.AppendString("");  // Unique ID is deprecated
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStartSession,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void StopSession() OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerStopSession);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString("");  // Unique ID is deprecated
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStopSession,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void RequestLockScreen() OVERRIDE {
    SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
  }

  virtual void RequestUnlockScreen() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerUnlockScreen);
  }

  virtual bool GetIsScreenLocked() OVERRIDE {
    return screen_locked_;
  }

  virtual void RetrieveDevicePolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    CallRetrievePolicy(login_manager::kSessionManagerRetrievePolicy,
                       callback);
  }

  virtual void RetrieveUserPolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    CallRetrievePolicy(login_manager::kSessionManagerRetrieveUserPolicy,
                       callback);
  }

  virtual void StoreDevicePolicy(const std::string& policy_blob,
                                 const StorePolicyCallback& callback) OVERRIDE {
    CallStorePolicy(login_manager::kSessionManagerStorePolicy,
                    policy_blob, callback);
  }

  virtual void StoreUserPolicy(const std::string& policy_blob,
                               const StorePolicyCallback& callback) OVERRIDE {
    CallStorePolicy(login_manager::kSessionManagerStoreUserPolicy,
                    policy_blob, callback);
  }

 private:
  // Makes a method call to the session manager with no arguments and no
  // response.
  void SimpleMethodCallToSessionManager(const std::string& method_name) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        dbus::ObjectProxy::EmptyResponseCallback());
  }

  // Helper for Retrieve{User,Device}Policy.
  virtual void CallRetrievePolicy(const std::string& method_name,
                                  const RetrievePolicyCallback& callback) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
                   weak_ptr_factory_.GetWeakPtr(),
                   method_name,
                   callback));
  }

  // Helper for Store{User,Device}Policy.
  virtual void CallStorePolicy(const std::string& method_name,
                               const std::string& policy_blob,
                               const StorePolicyCallback& callback) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    dbus::MessageWriter writer(&method_call);
    // static_cast does not work due to signedness.
    writer.AppendArrayOfBytes(
        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStorePolicy,
                   weak_ptr_factory_.GetWeakPtr(),
                   method_name,
                   callback));
  }

  // Called when kSessionManagerRestartJob method is complete.
  void OnRestartJob(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerRestartJob;
  }

  // Called when kSessionManagerStartSession method is complete.
  void OnStartSession(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerStartSession;
  }

  // Called when kSessionManagerStopSession method is complete.
  void OnStopSession(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerStopSession;
  }

  // Called when kSessionManagerRetrievePolicy or
  // kSessionManagerRetrieveUserPolicy  method is complete.
  void OnRetrievePolicy(const std::string& method_name,
                        const RetrievePolicyCallback& callback,
                        dbus::Response* response) {
    if (!response) {
      LOG(ERROR) << "Failed to call " << method_name;
      callback.Run("");
      return;
    }
    dbus::MessageReader reader(response);
    uint8* values = NULL;
    size_t length = 0;
    if (!reader.PopArrayOfBytes(&values, &length)) {
      LOG(ERROR) << "Invalid response: " << response->ToString();
      callback.Run("");
      return;
    }
    // static_cast does not work due to signedness.
    std::string serialized_proto(reinterpret_cast<char*>(values), length);
    callback.Run(serialized_proto);
  }

  // Called when kSessionManagerStorePolicy or kSessionManagerStoreUserPolicy
  // method is complete.
  void OnStorePolicy(const std::string& method_name,
                     const StorePolicyCallback& callback,
                     dbus::Response* response) {
    bool success = false;
    if (!response) {
      LOG(ERROR) << "Failed to call " << method_name;
    } else {
      dbus::MessageReader reader(response);
      if (!reader.PopBool(&success))
        LOG(ERROR) << "Invalid response: " << response->ToString();
    }
    callback.Run(success);
  }

  // Called when the owner key set signal is received.
  void OwnerKeySetReceived(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    std::string result_string;
    if (!reader.PopString(&result_string)) {
      LOG(ERROR) << "Invalid signal: " << signal->ToString();
      return;
    }
    const bool success = StartsWithASCII(result_string, "success", false);
    FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
  }

  // Called when the property change complete signal is received.
  void PropertyChangeCompleteReceived(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    std::string result_string;
    if (!reader.PopString(&result_string)) {
      LOG(ERROR) << "Invalid signal: " << signal->ToString();
      return;
    }
    const bool success = StartsWithASCII(result_string, "success", false);
    FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
  }

  void ScreenLockReceived(dbus::Signal* signal) {
    screen_locked_ = true;
    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
  }

  void ScreenUnlockReceived(dbus::Signal* signal) {
    screen_locked_ = false;
    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
  }

  // Called when the object is connected to the signal.
  void SignalConnected(const std::string& interface_name,
                       const std::string& signal_name,
                       bool success) {
    LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
  }

  dbus::ObjectProxy* session_manager_proxy_;
  ObserverList<Observer> observers_;
  bool screen_locked_;
  base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
};

// The SessionManagerClient implementation used on Linux desktop,
// which does nothing.
class SessionManagerClientStubImpl : public SessionManagerClient {
  // SessionManagerClient overrides.
  virtual void AddObserver(Observer* observer) OVERRIDE {}
  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
  virtual bool HasObserver(Observer* observer) OVERRIDE { return false; }
  virtual void EmitLoginPromptReady() OVERRIDE {}
  virtual void EmitLoginPromptVisible() OVERRIDE {}
  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
  virtual void RestartEntd() OVERRIDE {}
  virtual void StartSession(const std::string& user_email) OVERRIDE {}
  virtual void StopSession() OVERRIDE {}
  virtual void RequestLockScreen() OVERRIDE {}
  virtual void RequestUnlockScreen() OVERRIDE {}
  virtual bool GetIsScreenLocked() OVERRIDE { return false; }
  virtual void RetrieveDevicePolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    callback.Run("");
  }
  virtual void RetrieveUserPolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    callback.Run("");
  }
  virtual void StoreDevicePolicy(const std::string& policy_blob,
                                 const StorePolicyCallback& callback) OVERRIDE {
    callback.Run(true);
  }
  virtual void StoreUserPolicy(const std::string& policy_blob,
                               const StorePolicyCallback& callback) OVERRIDE {
    callback.Run(true);
  }
};

SessionManagerClient::SessionManagerClient() {
}

SessionManagerClient::~SessionManagerClient() {
}

SessionManagerClient* SessionManagerClient::Create(
    DBusClientImplementationType type,
    dbus::Bus* bus) {
  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
    return new SessionManagerClientImpl(bus);
  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
  return new SessionManagerClientStubImpl();
}

}  // namespace chromeos
<commit_msg>chromeos: Make SessionManagerClientStubImpl notify re lock.<commit_after>// Copyright (c) 2012 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 "chromeos/dbus/session_manager_client.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/string_util.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

// The SessionManagerClient implementation used in production.
class SessionManagerClientImpl : public SessionManagerClient {
 public:
  explicit SessionManagerClientImpl(dbus::Bus* bus)
      : session_manager_proxy_(NULL),
        screen_locked_(false),
        weak_ptr_factory_(this) {
    session_manager_proxy_ = bus->GetObjectProxy(
        login_manager::kSessionManagerServiceName,
        dbus::ObjectPath(login_manager::kSessionManagerServicePath));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kOwnerKeySetSignal,
        base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kPropertyChangeCompleteSignal,
        base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kLockScreenSignal,
        base::Bind(&SessionManagerClientImpl::ScreenLockReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    session_manager_proxy_->ConnectToSignal(
        chromium::kChromiumInterface,
        chromium::kUnlockScreenSignal,
        base::Bind(&SessionManagerClientImpl::ScreenUnlockReceived,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&SessionManagerClientImpl::SignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual ~SessionManagerClientImpl() {
  }

  // SessionManagerClient overrides:
  virtual void AddObserver(Observer* observer) OVERRIDE {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    observers_.RemoveObserver(observer);
  }

  virtual bool HasObserver(Observer* observer) OVERRIDE {
    return observers_.HasObserver(observer);
  }

  virtual void EmitLoginPromptReady() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerEmitLoginPromptReady);
  }

  virtual void EmitLoginPromptVisible() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerEmitLoginPromptVisible);
  }

  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerRestartJob);
    dbus::MessageWriter writer(&method_call);
    writer.AppendInt32(pid);
    writer.AppendString(command_line);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnRestartJob,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void RestartEntd() OVERRIDE {
    SimpleMethodCallToSessionManager(login_manager::kSessionManagerRestartEntd);
  }

  virtual void StartSession(const std::string& user_email) OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerStartSession);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(user_email);
    writer.AppendString("");  // Unique ID is deprecated
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStartSession,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void StopSession() OVERRIDE {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 login_manager::kSessionManagerStopSession);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString("");  // Unique ID is deprecated
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStopSession,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  virtual void RequestLockScreen() OVERRIDE {
    SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
  }

  virtual void RequestUnlockScreen() OVERRIDE {
    SimpleMethodCallToSessionManager(
        login_manager::kSessionManagerUnlockScreen);
  }

  virtual bool GetIsScreenLocked() OVERRIDE {
    return screen_locked_;
  }

  virtual void RetrieveDevicePolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    CallRetrievePolicy(login_manager::kSessionManagerRetrievePolicy,
                       callback);
  }

  virtual void RetrieveUserPolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    CallRetrievePolicy(login_manager::kSessionManagerRetrieveUserPolicy,
                       callback);
  }

  virtual void StoreDevicePolicy(const std::string& policy_blob,
                                 const StorePolicyCallback& callback) OVERRIDE {
    CallStorePolicy(login_manager::kSessionManagerStorePolicy,
                    policy_blob, callback);
  }

  virtual void StoreUserPolicy(const std::string& policy_blob,
                               const StorePolicyCallback& callback) OVERRIDE {
    CallStorePolicy(login_manager::kSessionManagerStoreUserPolicy,
                    policy_blob, callback);
  }

 private:
  // Makes a method call to the session manager with no arguments and no
  // response.
  void SimpleMethodCallToSessionManager(const std::string& method_name) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        dbus::ObjectProxy::EmptyResponseCallback());
  }

  // Helper for Retrieve{User,Device}Policy.
  virtual void CallRetrievePolicy(const std::string& method_name,
                                  const RetrievePolicyCallback& callback) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
                   weak_ptr_factory_.GetWeakPtr(),
                   method_name,
                   callback));
  }

  // Helper for Store{User,Device}Policy.
  virtual void CallStorePolicy(const std::string& method_name,
                               const std::string& policy_blob,
                               const StorePolicyCallback& callback) {
    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                 method_name);
    dbus::MessageWriter writer(&method_call);
    // static_cast does not work due to signedness.
    writer.AppendArrayOfBytes(
        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
    session_manager_proxy_->CallMethod(
        &method_call,
        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::Bind(&SessionManagerClientImpl::OnStorePolicy,
                   weak_ptr_factory_.GetWeakPtr(),
                   method_name,
                   callback));
  }

  // Called when kSessionManagerRestartJob method is complete.
  void OnRestartJob(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerRestartJob;
  }

  // Called when kSessionManagerStartSession method is complete.
  void OnStartSession(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerStartSession;
  }

  // Called when kSessionManagerStopSession method is complete.
  void OnStopSession(dbus::Response* response) {
    LOG_IF(ERROR, !response)
        << "Failed to call "
        << login_manager::kSessionManagerStopSession;
  }

  // Called when kSessionManagerRetrievePolicy or
  // kSessionManagerRetrieveUserPolicy  method is complete.
  void OnRetrievePolicy(const std::string& method_name,
                        const RetrievePolicyCallback& callback,
                        dbus::Response* response) {
    if (!response) {
      LOG(ERROR) << "Failed to call " << method_name;
      callback.Run("");
      return;
    }
    dbus::MessageReader reader(response);
    uint8* values = NULL;
    size_t length = 0;
    if (!reader.PopArrayOfBytes(&values, &length)) {
      LOG(ERROR) << "Invalid response: " << response->ToString();
      callback.Run("");
      return;
    }
    // static_cast does not work due to signedness.
    std::string serialized_proto(reinterpret_cast<char*>(values), length);
    callback.Run(serialized_proto);
  }

  // Called when kSessionManagerStorePolicy or kSessionManagerStoreUserPolicy
  // method is complete.
  void OnStorePolicy(const std::string& method_name,
                     const StorePolicyCallback& callback,
                     dbus::Response* response) {
    bool success = false;
    if (!response) {
      LOG(ERROR) << "Failed to call " << method_name;
    } else {
      dbus::MessageReader reader(response);
      if (!reader.PopBool(&success))
        LOG(ERROR) << "Invalid response: " << response->ToString();
    }
    callback.Run(success);
  }

  // Called when the owner key set signal is received.
  void OwnerKeySetReceived(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    std::string result_string;
    if (!reader.PopString(&result_string)) {
      LOG(ERROR) << "Invalid signal: " << signal->ToString();
      return;
    }
    const bool success = StartsWithASCII(result_string, "success", false);
    FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
  }

  // Called when the property change complete signal is received.
  void PropertyChangeCompleteReceived(dbus::Signal* signal) {
    dbus::MessageReader reader(signal);
    std::string result_string;
    if (!reader.PopString(&result_string)) {
      LOG(ERROR) << "Invalid signal: " << signal->ToString();
      return;
    }
    const bool success = StartsWithASCII(result_string, "success", false);
    FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
  }

  void ScreenLockReceived(dbus::Signal* signal) {
    screen_locked_ = true;
    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
  }

  void ScreenUnlockReceived(dbus::Signal* signal) {
    screen_locked_ = false;
    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
  }

  // Called when the object is connected to the signal.
  void SignalConnected(const std::string& interface_name,
                       const std::string& signal_name,
                       bool success) {
    LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
  }

  dbus::ObjectProxy* session_manager_proxy_;
  ObserverList<Observer> observers_;
  bool screen_locked_;
  base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
};

// The SessionManagerClient implementation used on Linux desktop,
// which does nothing.
class SessionManagerClientStubImpl : public SessionManagerClient {
 public:
  SessionManagerClientStubImpl() : screen_locked_(false) {}
  virtual ~SessionManagerClientStubImpl() {}

  // SessionManagerClient overrides.
  virtual void AddObserver(Observer* observer) OVERRIDE {
    observers_.AddObserver(observer);
  }
  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    observers_.RemoveObserver(observer);
  }
  virtual bool HasObserver(Observer* observer) OVERRIDE {
    return observers_.HasObserver(observer);
  }
  virtual void EmitLoginPromptReady() OVERRIDE {}
  virtual void EmitLoginPromptVisible() OVERRIDE {}
  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
  virtual void RestartEntd() OVERRIDE {}
  virtual void StartSession(const std::string& user_email) OVERRIDE {}
  virtual void StopSession() OVERRIDE {}
  virtual void RequestLockScreen() OVERRIDE {
    screen_locked_ = true;
    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
  }
  virtual void RequestUnlockScreen() OVERRIDE {
    screen_locked_ = false;
    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
  }
  virtual bool GetIsScreenLocked() OVERRIDE { return screen_locked_; }
  virtual void RetrieveDevicePolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    callback.Run("");
  }
  virtual void RetrieveUserPolicy(
      const RetrievePolicyCallback& callback) OVERRIDE {
    callback.Run("");
  }
  virtual void StoreDevicePolicy(const std::string& policy_blob,
                                 const StorePolicyCallback& callback) OVERRIDE {
    callback.Run(true);
  }
  virtual void StoreUserPolicy(const std::string& policy_blob,
                               const StorePolicyCallback& callback) OVERRIDE {
    callback.Run(true);
  }

 private:
  ObserverList<Observer> observers_;
  bool screen_locked_;

  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
};

SessionManagerClient::SessionManagerClient() {
}

SessionManagerClient::~SessionManagerClient() {
}

SessionManagerClient* SessionManagerClient::Create(
    DBusClientImplementationType type,
    dbus::Bus* bus) {
  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
    return new SessionManagerClientImpl(bus);
  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
  return new SessionManagerClientStubImpl();
}

}  // namespace chromeos
<|endoftext|>


<commit_before>//===-- Use.cpp - Implement the Use class ---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include <new>

namespace llvm {

void Use::swap(Use &RHS) {
  if (Val == RHS.Val)
    return;

  if (Val)
    removeFromList();

  Value *OldVal = Val;
  if (RHS.Val) {
    RHS.removeFromList();
    Val = RHS.Val;
    Val->addUse(*this);
  } else {
    Val = nullptr;
  }

  if (OldVal) {
    RHS.Val = OldVal;
    RHS.Val->addUse(RHS);
  } else {
    RHS.Val = nullptr;
  }
}

User *Use::getUser() const {
  const Use *End = getImpliedUser();
  const UserRef *ref = reinterpret_cast<const UserRef *>(End);
  return ref->getInt() ? ref->getPointer()
                       : reinterpret_cast<User *>(const_cast<Use *>(End));
}

unsigned Use::getOperandNo() const {
  return this - getUser()->op_begin();
}

// Sets up the waymarking algorithm's tags for a series of Uses. See the
// algorithm details here:
//
//   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
//
Use *Use::initTags(Use *const Start, Use *Stop) {
  ptrdiff_t Done = 0;
  while (Done < 20) {
    if (Start == Stop--)
      return Start;
    static const PrevPtrTag tags[20] = {
        fullStopTag,  oneDigitTag,  stopTag,      oneDigitTag, oneDigitTag,
        stopTag,      zeroDigitTag, oneDigitTag,  oneDigitTag, stopTag,
        zeroDigitTag, oneDigitTag,  zeroDigitTag, oneDigitTag, stopTag,
        oneDigitTag,  oneDigitTag,  oneDigitTag,  oneDigitTag, stopTag};
    new (Stop) Use(tags[Done++]);
  }

  ptrdiff_t Count = Done;
  while (Start != Stop) {
    --Stop;
    if (!Count) {
      new (Stop) Use(stopTag);
      ++Done;
      Count = Done;
    } else {
      new (Stop) Use(PrevPtrTag(Count & 1));
      Count >>= 1;
      ++Done;
    }
  }

  return Start;
}

void Use::zap(Use *Start, const Use *Stop, bool del) {
  while (Start != Stop)
    (--Stop)->~Use();
  if (del)
    ::operator delete(Start);
}

const Use *Use::getImpliedUser() const {
  const Use *Current = this;

  while (true) {
    unsigned Tag = (Current++)->Prev.getInt();
    switch (Tag) {
    case zeroDigitTag:
    case oneDigitTag:
      continue;

    case stopTag: {
      ++Current;
      ptrdiff_t Offset = 1;
      while (true) {
        unsigned Tag = Current->Prev.getInt();
        switch (Tag) {
        case zeroDigitTag:
        case oneDigitTag:
          ++Current;
          Offset = (Offset << 1) + Tag;
          continue;
        default:
          return Current + Offset;
        }
      }
    }

    case fullStopTag:
      return Current;
    }
  }
}

} // End llvm namespace
<commit_msg>Fix a URL (NFC)<commit_after>//===-- Use.cpp - Implement the Use class ---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include <new>

namespace llvm {

void Use::swap(Use &RHS) {
  if (Val == RHS.Val)
    return;

  if (Val)
    removeFromList();

  Value *OldVal = Val;
  if (RHS.Val) {
    RHS.removeFromList();
    Val = RHS.Val;
    Val->addUse(*this);
  } else {
    Val = nullptr;
  }

  if (OldVal) {
    RHS.Val = OldVal;
    RHS.Val->addUse(RHS);
  } else {
    RHS.Val = nullptr;
  }
}

User *Use::getUser() const {
  const Use *End = getImpliedUser();
  const UserRef *ref = reinterpret_cast<const UserRef *>(End);
  return ref->getInt() ? ref->getPointer()
                       : reinterpret_cast<User *>(const_cast<Use *>(End));
}

unsigned Use::getOperandNo() const {
  return this - getUser()->op_begin();
}

// Sets up the waymarking algorithm's tags for a series of Uses. See the
// algorithm details here:
//
//   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
//
Use *Use::initTags(Use *const Start, Use *Stop) {
  ptrdiff_t Done = 0;
  while (Done < 20) {
    if (Start == Stop--)
      return Start;
    static const PrevPtrTag tags[20] = {
        fullStopTag,  oneDigitTag,  stopTag,      oneDigitTag, oneDigitTag,
        stopTag,      zeroDigitTag, oneDigitTag,  oneDigitTag, stopTag,
        zeroDigitTag, oneDigitTag,  zeroDigitTag, oneDigitTag, stopTag,
        oneDigitTag,  oneDigitTag,  oneDigitTag,  oneDigitTag, stopTag};
    new (Stop) Use(tags[Done++]);
  }

  ptrdiff_t Count = Done;
  while (Start != Stop) {
    --Stop;
    if (!Count) {
      new (Stop) Use(stopTag);
      ++Done;
      Count = Done;
    } else {
      new (Stop) Use(PrevPtrTag(Count & 1));
      Count >>= 1;
      ++Done;
    }
  }

  return Start;
}

void Use::zap(Use *Start, const Use *Stop, bool del) {
  while (Start != Stop)
    (--Stop)->~Use();
  if (del)
    ::operator delete(Start);
}

const Use *Use::getImpliedUser() const {
  const Use *Current = this;

  while (true) {
    unsigned Tag = (Current++)->Prev.getInt();
    switch (Tag) {
    case zeroDigitTag:
    case oneDigitTag:
      continue;

    case stopTag: {
      ++Current;
      ptrdiff_t Offset = 1;
      while (true) {
        unsigned Tag = Current->Prev.getInt();
        switch (Tag) {
        case zeroDigitTag:
        case oneDigitTag:
          ++Current;
          Offset = (Offset << 1) + Tag;
          continue;
        default:
          return Current + Offset;
        }
      }
    }

    case fullStopTag:
      return Current;
    }
  }
}

} // End llvm namespace
<|endoftext|>


<commit_before>#include "common.h"

/*
struct Pregridded
{
  short u;
  short v;
  short gcf_layer_index;
  short half_supp_size;
}; */

template <
    int w_planes
  , int half_supp_step
  , int grid_size
  , int over
  >
Pregridded pregrid(const Double3 & uvw, const TaskCfg & cfg) {
  const int max_supp = (w_planes - 1) * half_supp_step * 2;
  double
      us = uvw.u * cfg.scaleWL
    , vs = uvw.v * cfg.scaleWL
    ;
  int
      u = int(us)
    , v = int(vs)
    , wplane = int((uvw.w + cfg.w_shift)/ cfg.w_step)
    , uv_shift_in_pixels = (max_supp + grid_size) / 2
    ;
  short
      fracu = short(double(over) * (us - double(u)))
    , fracv = short(double(over) * (vs - double(v)))
    ;
  const int overu = over;
  const int overv = over;
  return {u + uv_shift_in_pixels, v + uv_shift_in_pixels, (wplane * overu + fracu) * overv + fracv, wplane * half_supp_step};
}

template <
    int w_planes
  , int half_supp_step
  , int grid_size
  , int over

  , int baselines
  , int timesteps
  , int channels
  >
// grid must be initialized to 0s.
void gridKernel_scatter(
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
    const complexd * gcf
  , Double4c grid[grid_size][grid_size]
  // , const Pregridded uvw[baselines][timesteps][channels]
  // , const Double4c vis[baselines][timesteps][channels]
  , const Pregridded uvw[baselines * timesteps * channels]
  , const Double4c vis[baselines * timesteps * channels]
  ) {
  for (int sv = 0; /* see CHECK_SUPP comment */ ; sv++) { // Moved from 2-levels below according to Romein
    for (int i = 0; i < baselines * timesteps * channels; i++) {
      const int
        max_supp_here = uvw[i].half_supp_size * 2;

      if (sv > max_supp_here)
        return; // CHECK_SUPP

      const complexd * gcf_layer = gcf + uvw[i].gcf_layer_index;

#ifdef __AVX__
      // We port Romein CPU code to doubles here (for MS2 we didn't)
      // vis0 covers XX and XY, vis1 -- YX and YY
      __m256d vis0 = _mm256_load_pd((const double *) &vis[i].XX);
      __m256d vis1 = _mm256_load_pd((const double *) &vis[i].YX);
#endif

      for (int su = 0; su <= max_supp_here; su++) {
      // NOTE: Romein writes about moving this to the very outer scope
      // (2 levels up) to make things more cache-friendly.
      // I don't know whether it is cache frendly
      // but what I definitely see gcc generates 4-times shorter code for it!
      // We need to investigate this!
      // for (int sv = 0; sv < max_supp_here; sv++) {
        int gsu, gsv;
        gsu = uvw[i].u + su - uvw[i].half_supp_size;
        gsv = uvw[i].v + sv - uvw[i].half_supp_size;

        int gcf_index = su * max_supp_here + sv;

#ifdef __AVX__
        __m256d weight_r = _mm256_set1_pd(gcf_layer[gcf_index].real());
        __m256d weight_i = _mm256_set1_pd(gcf_layer[gcf_index].imag());

        /* _mm256_permute_pd(x, 5) swaps adjacent doubles pairs of x:
           d0, d1, d2, d3 goes to d1, d0, d3, d2
         */
        #define __DO(p,f)                                     \
        __m256d * gridptr##p = (__m256d *) &grid[gsu][gsv].f; \
        __m256d tr##p = _mm256_mul_pd(weight_r, vis##p);      \
        __m256d ti##p = _mm256_mul_pd(weight_i, vis##p);      \
        __m256d tp##p = _mm256_permute_pd(ti##p, 5);          \
        __m256d t##p = _mm256_addsub_pd(tr##p, tp##p);        \
        gridptr##p[p] = _mm256_add_pd(gridptr##p[p], t##p)

        __DO(0, XX);
        __DO(1, YX);
#else
        #define __GRID_POL(pol) grid[gsu][gsv].pol += vis[i].pol * gcf_layer[gcf_index]
        __GRID_POL(XX);
        __GRID_POL(XY);
        __GRID_POL(YX);
        __GRID_POL(YY);
#endif
      }
    }
  }
}

// Test instantiation
template void gridKernel_scatter<32, 4, 2048, 8, 50*99, 20, 1>(
    const complexd * gcf
  , Double4c grid[2048][2048]
  , const Pregridded uvw[(50*90) * 20 * 1]
  , const Double4c vis[(50*90) * 20 * 1]
  );
<commit_msg>Adapt CPU gridder.<commit_after>#include "common.h"
#include "metrix.h"

template <
    int grid_size

  , int baselines
  , int timesteps
  , int channels
  , bool is_half_gcf
  >
// grid must be initialized to 0s.
void gridKernel_scatter(
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
    const complexd * gcf
  , Double4c grid[grid_size][grid_size]
  // , const Pregridded uvw[baselines][timesteps][channels]
  // , const Double4c vis[baselines][timesteps][channels]
  , const Pregridded uvw[baselines * timesteps * channels]
  , const Double4c vis[baselines * timesteps * channels]
  ) {
  for (int sv = 0; /* see CHECK_SUPP comment */ ; sv++) { // Moved from 2-levels below according to Romein
    for (int i = 0; i < baselines * timesteps * channels; i++) {
      const int
        max_supp_here = uvw[i].gcf_layer_supp;

      if (sv > max_supp_here)
        return; // CHECK_SUPP

#ifdef __AVX__
      // We port Romein CPU code to doubles here (for MS2 we didn't)
      // vis0 covers XX and XY, vis1 -- YX and YY
      __m256d vis0 = _mm256_load_pd((const double *) &vis[i].XX);
      __m256d vis1 = _mm256_load_pd((const double *) &vis[i].YX);
#endif

      for (int su = 0; su <= max_supp_here; su++) {
      // NOTE: Romein writes about moving this to the very outer scope
      // (2 levels up) to make things more cache-friendly.
      // I don't know whether it is cache frendly
      // but what I definitely see gcc generates 4-times shorter code for it!
      // We need to investigate this!
      // for (int sv = 0; sv < max_supp_here; sv++) {
        // Don't forget our u v are already translated by -max_supp_here/2
        int gsu, gsv;
        gsu = uvw[i].u + su;
        gsv = uvw[i].v + sv;

        complexd supportPixel;
        #define __layeroff su * max_supp_here + sv
        if (is_half_gcf) {
          int index = uvw[i].gcf_layer_index;
          // Negative index indicates that original w was mirrored
          // and we shall negate the index to obtain correct
          // offset *and* conjugate the result.
          if (index < 0) {
            supportPixel = conj((gcf - index)[__layeroff]);
          } else {
            supportPixel = (gcf + index)[__layeroff];
          }
        } else {
            supportPixel = (gcf + uvw[i].gcf_layer_index)[__layeroff];
        }

#ifdef __AVX__
        __m256d weight_r = _mm256_set1_pd(supportPixel.real());
        __m256d weight_i = _mm256_set1_pd(supportPixel.imag());

        /* _mm256_permute_pd(x, 5) swaps adjacent doubles pairs of x:
           d0, d1, d2, d3 goes to d1, d0, d3, d2
         */
        #define __DO(p,f)                                     \
        __m256d * gridptr##p = (__m256d *) &grid[gsu][gsv].f; \
        __m256d tr##p = _mm256_mul_pd(weight_r, vis##p);      \
        __m256d ti##p = _mm256_mul_pd(weight_i, vis##p);      \
        __m256d tp##p = _mm256_permute_pd(ti##p, 5);          \
        __m256d t##p = _mm256_addsub_pd(tr##p, tp##p);        \
        gridptr##p[p] = _mm256_add_pd(gridptr##p[p], t##p)

        __DO(0, XX);
        __DO(1, YX);
#else
        #define __GRID_POL(pol) grid[gsu][gsv].pol += vis[i].pol * supportPixel
        __GRID_POL(XX);
        __GRID_POL(XY);
        __GRID_POL(YX);
        __GRID_POL(YY);
#endif
      }
    }
  }
}

// Test instantiation
void gridKernel_scatter1(
    const complexd * gcf
  , Double4c grid[GRID_SIZE][GRID_SIZE]
  , const Pregridded uvw[BASELINES * TIMESTEPS * CHANNELS]
  , const Double4c vis[BASELINES * TIMESTEPS * CHANNELS]
  ){
  gridKernel_scatter<GRID_SIZE, BASELINES, TIMESTEPS, CHANNELS, false>(gcf, grid, uvw, vis);
  }
<|endoftext|>


<commit_before>#include "MainSceneMaker.h"
#include "AutoBinder.hpp"

using namespace Rendering;
using namespace Device;
using namespace Rendering::Shader;
using namespace Rendering::Manager;
using namespace Rendering::Texture;
using namespace Rendering::RenderState;
using namespace Rendering::PostProcessing;

void MainSceneMaker::Initialize(DirectX& dx, ShaderManager& shaderMgr, const Size<uint>& renderSize)
{
	std::vector<ShaderMacro> macros{ dx.GetMSAAShaderMacro() };

	FullScreen::InitParam param;
	{
		param.shaderFileName	= "MainSceneMaker";
		param.psName			= "PS";
		param.psMacros			= &macros;
	}

	_screen.Initialize(dx, param, shaderMgr);
}

void MainSceneMaker::Render(DirectX& dx, RenderTexture& output, const RenderParam&& param)
{
	AutoBinderSRV<PixelShader>	colorMap(dx,		TextureBindIndex(0),			param.opaqueMap.GetShaderResourceView());
	AutoBinderSRV<PixelShader>	giMap(dx,			TextureBindIndex(1),			param.giMap.GetShaderResourceView());

	AutoBinderCB<PixelShader>	tbrParmCB(dx,		ConstBufferBindIndex::TBRParam,	param.tbrCB);

	AutoBinderSampler<PixelShader> sampler(dx,		SamplerStateBindIndex(0),		SamplerState::Linear);

	_screen.Render(dx, output, true);
}
<commit_msg>에러 수정<commit_after>#include "MainSceneMaker.h"
#include "AutoBinder.hpp"

using namespace Rendering;
using namespace Device;
using namespace Rendering::Shader;
using namespace Rendering::Manager;
using namespace Rendering::Texture;
using namespace Rendering::RenderState;
using namespace Rendering::PostProcessing;

void MainSceneMaker::Initialize(DirectX& dx, ShaderManager& shaderMgr, const Size<uint>& renderSize)
{
	std::vector<ShaderMacro> macros{ dx.GetMSAAShaderMacro() };

	FullScreen::InitParam param;
	{
		param.shaderFileName	= "MainSceneMaker";
		param.psName			= "PS";
		param.psMacros			= &macros;
	}

	_screen.Initialize(dx, param, shaderMgr);
}

void MainSceneMaker::Render(DirectX& dx, RenderTexture& output, const RenderParam&& param)
{
	AutoBinderSRV<PixelShader>	colorMap(dx,		TextureBindIndex(0),			param.opaqueMap.GetShaderResourceView());
	AutoBinderSRV<PixelShader>	giMap(dx,			TextureBindIndex(1),			param.giMap.GetShaderResourceView());

	AutoBinderSampler<PixelShader> sampler(dx,		SamplerStateBindIndex(0),		SamplerState::Linear);

	_screen.Render(dx, output, true);
}
<|endoftext|>


<commit_before>#include "musicsongssummarizied.h"
#include "musicsongsListwidget.h"
#include "musicsongstoolitemrenamedwidget.h"
#include "musicsettingmanager.h"
#include "musicuiobject.h"
#include "musicmessagebox.h"
#include "musicconnectionpool.h"
#include "musicsongtag.h"
#include "musicprogresswidget.h"

#include <QScrollBar>
#include <QTableWidgetItem>
#include <QLayout>
#include <QDebug>

MusicSongsSummarizied::MusicSongsSummarizied(QWidget *parent)
    : QToolBox(parent), m_renameLine(nullptr)
{
    setAttribute(Qt::WA_TranslucentBackground, true);
    setStyleSheet(MusicUIObject::MToolBoxStyle01);
    for(int i=0; i<3; ++i)
    {
        MusicSongsListWidget* w = new MusicSongsListWidget(this);
        m_mainSongLists.append(w);
    }
    addItem(m_mainSongLists[0], tr("myDefaultPlayItem"));
    addItem(m_mainSongLists[1], tr("myLoveSongItem"));
    addItem(m_mainSongLists[2], tr("myNetSongItem"));
    layout()->setSpacing(0);
    changeItemIcon();
    m_currentIndexs = 0;
    m_searchFileListIndex = -1;
    m_renameIndex = -1;

    for(int i=0; i<3; ++i)
    {
        connect(m_mainSongLists[i], SIGNAL(cellDoubleClicked(int,int)), parent, SLOT(musicPlayIndex(int,int)));
        connect(m_mainSongLists[i], SIGNAL(musicPlayOrder()), parent, SLOT(musicPlayOrder()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayRandom()), parent, SLOT(musicPlayRandom()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayListLoop()), parent, SLOT(musicPlayListLoop()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayOneLoop()), parent, SLOT(musicPlayOneLoop()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayItemOnce()), parent, SLOT(musicPlayItemOnce()));
        connect(m_mainSongLists[i], SIGNAL(musicAddNewFiles()), parent, SLOT(musicImportSongsOnlyFile()));
        connect(m_mainSongLists[i], SIGNAL(musicAddNewDir()), parent, SLOT(musicImportSongsOnlyDir()));
        connect(m_mainSongLists[i], SIGNAL(isCurrentIndexs(bool&)), SLOT(isCurrentIndexs(bool&)));
        connect(m_mainSongLists[i], SIGNAL(isSearchFileListEmpty(bool&)), SLOT(isSearchFileListEmpty(bool&)));
        connect(m_mainSongLists[i], SIGNAL(deleteItemAt(MIntList,bool)), SLOT(setDeleteItemAt(MIntList,bool)));
        connect(m_mainSongLists[i], SIGNAL(getMusicIndexSwaped(int,int,int,QStringList&)),
                                    SLOT(setMusicIndexSwaped(int,int,int,QStringList&)));
    }

    connect(this, SIGNAL(showCurrentSong(int)), parent, SLOT(showCurrentSong(int)));
    connect(m_mainSongLists[0], SIGNAL(musicSongToLovestListAt(int)), SLOT(addMusicSongToLovestListAt(int)));
    connect(m_mainSongLists[2], SIGNAL(musicSongToLovestListAt(int)), SLOT(addMusicSongToLovestListAt(int)));

    connect(this, SIGNAL(currentChanged(int)), SLOT(currentIndexChanged(int)));

    M_CONNECTION->setValue("MusicSongsSummarizied", this);
    M_CONNECTION->poolConnect("MusicSongSearchOnlineTableWidget", "MusicSongsSummarizied");
}

MusicSongsSummarizied::~MusicSongsSummarizied()
{
    clearAllLists();
}

void MusicSongsSummarizied::setMusicLists(const MusicSongsList &names)
{
    m_musicFileNames = names;
    for(int i=0; i<m_musicFileNames.count(); ++i)
    {
        m_mainSongLists[i]->setSongsFileName(&m_musicFileNames[i]);
    }
}

void MusicSongsSummarizied::setMusicSongsSearchedFileName(const MIntList &fileIndexs)
{
    MusicSongs songs;
    foreach(int index, fileIndexs)
    {
        songs << m_musicFileNames[currentIndex()][index];
    }
    m_mainSongLists[currentIndex()]->clearAllItems();
    m_mainSongLists[currentIndex()]->updateSongsFileName(songs);
}

void MusicSongsSummarizied::searchFileListCache(int index, const QString &text)
{
    MIntList searchResult;
    QStringList searchedSongs(getMusicSongsFileName(currentIndex()));
    for(int j=0; j<searchedSongs.count(); ++j)
    if(searchedSongs[j].contains(text, Qt::CaseInsensitive))
    {
        searchResult << j;
    }
    m_searchFileListIndex = text.count();
    m_searchfileListCache.insert(index, searchResult);
    setMusicSongsSearchedFileName(searchResult);

    if(index == 0)
    {
        m_searchfileListCache.clear();
    }
}

bool MusicSongsSummarizied::searchFileListEmpty() const
{
    return m_searchfileListCache.isEmpty();
}

int MusicSongsSummarizied::getsearchFileListIndex(int row)
{
    MIntList list = m_searchfileListCache.value(m_searchFileListIndex);
    if(row >= list.count())
    {
        return -1;
    }
    return row >= 0 ? list[row] : -1;
}

int MusicSongsSummarizied::getsearchFileListIndexAndClear(int row)
{
    row = getsearchFileListIndex(row);
    m_searchfileListCache.clear();
    emit clearSearchText();
    return row;
}

void MusicSongsSummarizied::importOtherMusicSongs(const QStringList &filelist)
{
    MusicProgressWidget progress;
    progress.show();
    progress.setTitle(tr("Import File Mode"));
    progress.setRange(0, filelist.count());

    MusicSongTag tag;
    for(int i=0; i<filelist.count(); ++i)
    {
        if(tag.readFile(filelist[i]))
        {
            QString time(tag.getLengthString());
            m_musicFileNames[0] << MusicSong(filelist[i], 0, time.left(time.lastIndexOf(':')), QString());
        }
        progress.setValue(i + 1);
    }
    m_mainSongLists[0]->updateSongsFileName(m_musicFileNames[0]);
}

QStringList MusicSongsSummarizied::getMusicSongsFileName(int index) const
{
    QStringList list;
    foreach(MusicSong song, m_musicFileNames[index])
    {
        list << song.getMusicName();
    }
    return list;
}

QStringList MusicSongsSummarizied::getMusicSongsFilePath(int index) const
{
    QStringList list;
    foreach(MusicSong song, m_musicFileNames[index])
    {
        list << song.getMusicPath();
    }
    return list;
}

void MusicSongsSummarizied::selectRow(int index)
{
    QToolBox::setCurrentIndex(m_currentIndexs);
    m_mainSongLists[m_currentIndexs]->selectRow(index);
}

void MusicSongsSummarizied::setTimerLabel(const QString &time) const
{
    m_mainSongLists[m_currentIndexs]->setTimerLabel(time);
}

void MusicSongsSummarizied::setTransparent(int alpha)
{
    alpha = alpha*2.55;
    foreach(MusicSongsListWidget *item, m_mainSongLists)
    {
        item->setTransparent(alpha);
        item->update();
    }

    alpha += 40;
    setStyleSheet(MusicUIObject::MToolBoxStyle01 + \
                  QString("QToolBox::tab{background-color:rgba(255,255,255,%1);}")
                  .arg(alpha > 255 ? 255 : alpha) );

}

void MusicSongsSummarizied::setMusicPlayCount(int index)
{
    MusicSongs *songs = &m_musicFileNames[m_currentIndexs];
    if(!songs->isEmpty())
    {
        int countNumber = (*songs)[index].getMusicPlayCount();
        (*songs)[index].setMusicPlayCount(++countNumber);
    }
}

void MusicSongsSummarizied::clearAllLists()
{
    while(!m_mainSongLists.isEmpty())
    {
        MusicSongsListWidget *w = m_mainSongLists.takeLast();
        delete w;
        w = nullptr;
    }
}

void MusicSongsSummarizied::setDeleteItemAt(const MIntList &index, bool fileRemove)
{
    if(index.count() == 0)
    {
        return;
    }

    for(int i=index.count()-1; i>=0; --i)
    {
        MusicSong song = m_musicFileNames[currentIndex()].takeAt(index[i]);
        if(fileRemove)
        {
            QFile::remove(song.getMusicPath());
        }
    }
    if(currentIndex() == m_currentIndexs)
    {
        emit deleteItemAt(index);
    }
}

void MusicSongsSummarizied::addNewItem()
{
    if(m_mainSongLists.count() > 8)
    {
        return;
    }

    MusicSongsListWidget *w = new MusicSongsListWidget(this);
    m_mainSongLists.append(w);
    addItem(w, tr("newSongItem"));
    changeItemIcon();
}

void MusicSongsSummarizied::addMusicSongToLovestListAt(int row)
{
    if(!searchFileListEmpty())
    {
        row = getsearchFileListIndex(row);
    }

    MusicSong song = m_musicFileNames[currentIndex()][row];
    m_musicFileNames[1] << song;
    m_mainSongLists[1]->updateSongsFileName(m_musicFileNames[1]);
    if(m_currentIndexs == 1)
    {
        emit updatePlayLists(song.getMusicPath());
    }
    MusicMessageBox message;
    message.setText(tr("add music to lovest list done!"));
    message.exec();
}

void MusicSongsSummarizied::addNetMusicSongToList(const QString &name, const QString &time,
                                                  const QString &format)
{
    const QString path = QString("%1%2.%3").arg(MUSIC_DOWNLOAD_AL).arg(name).arg(format);
    m_musicFileNames[2] << MusicSong(path, 0, time, name);
    m_mainSongLists[2]->updateSongsFileName(m_musicFileNames[2]);
    if(m_currentIndexs == 2)
    {
        emit updatePlayLists(path);
    }
}

void MusicSongsSummarizied::deleteItem()
{
    int index = currentIndex();
    if(index == 0 || index == 1 || index == 2)
    {
        MusicMessageBox message;
        message.setText(tr("The origin one can't delete!"));
        message.exec();
        return;//Not allow to delete the origin three item
    }
    removeItem(index);
}

void MusicSongsSummarizied::changItemName()
{
    int index = currentIndex();
    if(index == 0 || index == 1 || index == 2)
    {
        MusicMessageBox message;
        message.setText(tr("The origin one can't rename!"));
        message.exec();
        return;//Not allow to change name for the origin three item
    }
    if(!m_renameLine)
    {
        m_renameIndex = currentIndex();
        m_renameLine =new MusicSongsToolItemRenamedWidget(m_renameIndex*26,
                                  QToolBox::itemText(m_renameIndex), this);
        connect(m_renameLine, SIGNAL(renameFinished(QString)), SLOT(setChangItemName(QString)));
        m_renameLine->show();
    }
}

void MusicSongsSummarizied::setChangItemName(const QString &name)
{
    setItemText(m_renameIndex, name);
    delete m_renameLine;
    m_renameLine = nullptr;
}

void MusicSongsSummarizied::currentIndexChanged(int)
{
    if(currentIndex() == -1)
    {
        return;
    }
    changeItemIcon();
    if(m_renameLine)
    {
        m_renameLine->renameFinished();
    }
}

void MusicSongsSummarizied::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.setStyleSheet(MusicUIObject::MMenuStyle02);
    menu.addAction(QIcon(":/contextMenu/delete"), tr("deleteItem"), this, SLOT(deleteItem()));
    menu.addAction(QIcon(":/contextMenu/add"), tr("addNewItem"), this, SLOT(addNewItem()));
    menu.addAction(tr("changItemName"), this, SLOT(changItemName()));
    menu.exec(event->globalPos());
}

void MusicSongsSummarizied::changeItemIcon()
{
    for(int i=0; i<count(); ++i)
    {
        setItemIcon(i, QIcon(":/image/arrowup"));
    }
    setItemIcon(currentIndex(), QIcon(":/image/arrowdown"));
}

void MusicSongsSummarizied::setPlaybackMode(MusicObject::SongPlayType mode) const
{
    foreach(MusicSongsListWidget *m, m_mainSongLists)
    {
        m->setPlaybackMode(mode);
    }
}

void MusicSongsSummarizied::setMusicIndexSwaped(int before, int after, int play, QStringList &list)
{
    MusicSongs *names = &m_musicFileNames[currentIndex()];
    if(before > after)
    {
        for(int i=before; i>after; --i)
        {
            names->swap(i, i - 1);
        }
    }
    else
    {
        for(int i=before; i<after; ++i)
        {
            names->swap(i, i + 1);
        }
    }

    list = getMusicSongsFileName(currentIndex());
    if(currentIndex() == m_currentIndexs)
    {
        emit updateMediaLists(getMusicSongsFilePath(m_currentIndexs), play);
    }
}

void MusicSongsSummarizied::isCurrentIndexs(bool &state)
{
    state = ( currentIndex() == m_currentIndexs );
}

void MusicSongsSummarizied::isSearchFileListEmpty(bool &empty)
{
    empty = searchFileListEmpty();
}

void MusicSongsSummarizied::currentMusicSongTreeIndexChanged(int index)
{
    m_mainSongLists[m_currentIndexs]->replacePlayWidgetRow();
    m_currentIndexs = index;
}

void MusicSongsSummarizied::setCurrentIndex()
{
    QStringList keyList = M_SETTING->value(MusicSettingManager::LastPlayIndexChoiced).toStringList();
    m_currentIndexs = keyList[1].toInt();
    int index = keyList[2].toInt();
    QToolBox::setCurrentIndex(index);
    setMusicPlayCount(index);
    emit showCurrentSong(index);
}
<commit_msg>clean code[441576]<commit_after>#include "musicsongssummarizied.h"
#include "musicsongsListwidget.h"
#include "musicsongstoolitemrenamedwidget.h"
#include "musicsettingmanager.h"
#include "musicuiobject.h"
#include "musicmessagebox.h"
#include "musicconnectionpool.h"
#include "musicsongtag.h"
#include "musicprogresswidget.h"

#include <QScrollBar>
#include <QTableWidgetItem>
#include <QLayout>

MusicSongsSummarizied::MusicSongsSummarizied(QWidget *parent)
    : QToolBox(parent), m_renameLine(nullptr)
{
    setAttribute(Qt::WA_TranslucentBackground, true);
    setStyleSheet(MusicUIObject::MToolBoxStyle01);
    for(int i=0; i<3; ++i)
    {
        MusicSongsListWidget* w = new MusicSongsListWidget(this);
        m_mainSongLists.append(w);
    }
    addItem(m_mainSongLists[0], tr("myDefaultPlayItem"));
    addItem(m_mainSongLists[1], tr("myLoveSongItem"));
    addItem(m_mainSongLists[2], tr("myNetSongItem"));
    layout()->setSpacing(0);
    changeItemIcon();
    m_currentIndexs = 0;
    m_searchFileListIndex = -1;
    m_renameIndex = -1;

    for(int i=0; i<3; ++i)
    {
        connect(m_mainSongLists[i], SIGNAL(cellDoubleClicked(int,int)), parent, SLOT(musicPlayIndex(int,int)));
        connect(m_mainSongLists[i], SIGNAL(musicPlayOrder()), parent, SLOT(musicPlayOrder()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayRandom()), parent, SLOT(musicPlayRandom()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayListLoop()), parent, SLOT(musicPlayListLoop()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayOneLoop()), parent, SLOT(musicPlayOneLoop()));
        connect(m_mainSongLists[i], SIGNAL(musicPlayItemOnce()), parent, SLOT(musicPlayItemOnce()));
        connect(m_mainSongLists[i], SIGNAL(musicAddNewFiles()), parent, SLOT(musicImportSongsOnlyFile()));
        connect(m_mainSongLists[i], SIGNAL(musicAddNewDir()), parent, SLOT(musicImportSongsOnlyDir()));
        connect(m_mainSongLists[i], SIGNAL(isCurrentIndexs(bool&)), SLOT(isCurrentIndexs(bool&)));
        connect(m_mainSongLists[i], SIGNAL(isSearchFileListEmpty(bool&)), SLOT(isSearchFileListEmpty(bool&)));
        connect(m_mainSongLists[i], SIGNAL(deleteItemAt(MIntList,bool)), SLOT(setDeleteItemAt(MIntList,bool)));
        connect(m_mainSongLists[i], SIGNAL(getMusicIndexSwaped(int,int,int,QStringList&)),
                                    SLOT(setMusicIndexSwaped(int,int,int,QStringList&)));
    }

    connect(this, SIGNAL(showCurrentSong(int)), parent, SLOT(showCurrentSong(int)));
    connect(m_mainSongLists[0], SIGNAL(musicSongToLovestListAt(int)), SLOT(addMusicSongToLovestListAt(int)));
    connect(m_mainSongLists[2], SIGNAL(musicSongToLovestListAt(int)), SLOT(addMusicSongToLovestListAt(int)));

    connect(this, SIGNAL(currentChanged(int)), SLOT(currentIndexChanged(int)));

    M_CONNECTION->setValue("MusicSongsSummarizied", this);
    M_CONNECTION->poolConnect("MusicSongSearchOnlineTableWidget", "MusicSongsSummarizied");
}

MusicSongsSummarizied::~MusicSongsSummarizied()
{
    clearAllLists();
}

void MusicSongsSummarizied::setMusicLists(const MusicSongsList &names)
{
    m_musicFileNames = names;
    for(int i=0; i<m_musicFileNames.count(); ++i)
    {
        m_mainSongLists[i]->setSongsFileName(&m_musicFileNames[i]);
    }
}

void MusicSongsSummarizied::setMusicSongsSearchedFileName(const MIntList &fileIndexs)
{
    MusicSongs songs;
    foreach(int index, fileIndexs)
    {
        songs << m_musicFileNames[currentIndex()][index];
    }
    m_mainSongLists[currentIndex()]->clearAllItems();
    m_mainSongLists[currentIndex()]->updateSongsFileName(songs);
}

void MusicSongsSummarizied::searchFileListCache(int index, const QString &text)
{
    MIntList searchResult;
    QStringList searchedSongs(getMusicSongsFileName(currentIndex()));
    for(int j=0; j<searchedSongs.count(); ++j)
    if(searchedSongs[j].contains(text, Qt::CaseInsensitive))
    {
        searchResult << j;
    }
    m_searchFileListIndex = text.count();
    m_searchfileListCache.insert(index, searchResult);
    setMusicSongsSearchedFileName(searchResult);

    if(index == 0)
    {
        m_searchfileListCache.clear();
    }
}

bool MusicSongsSummarizied::searchFileListEmpty() const
{
    return m_searchfileListCache.isEmpty();
}

int MusicSongsSummarizied::getsearchFileListIndex(int row)
{
    MIntList list = m_searchfileListCache.value(m_searchFileListIndex);
    if(row >= list.count())
    {
        return -1;
    }
    return row >= 0 ? list[row] : -1;
}

int MusicSongsSummarizied::getsearchFileListIndexAndClear(int row)
{
    row = getsearchFileListIndex(row);
    m_searchfileListCache.clear();
    emit clearSearchText();
    return row;
}

void MusicSongsSummarizied::importOtherMusicSongs(const QStringList &filelist)
{
    MusicProgressWidget progress;
    progress.show();
    progress.setTitle(tr("Import File Mode"));
    progress.setRange(0, filelist.count());

    MusicSongTag tag;
    for(int i=0; i<filelist.count(); ++i)
    {
        if(tag.readFile(filelist[i]))
        {
            QString time(tag.getLengthString());
            m_musicFileNames[0] << MusicSong(filelist[i], 0, time.left(time.lastIndexOf(':')), QString());
        }
        progress.setValue(i + 1);
    }
    m_mainSongLists[0]->updateSongsFileName(m_musicFileNames[0]);
}

QStringList MusicSongsSummarizied::getMusicSongsFileName(int index) const
{
    QStringList list;
    foreach(MusicSong song, m_musicFileNames[index])
    {
        list << song.getMusicName();
    }
    return list;
}

QStringList MusicSongsSummarizied::getMusicSongsFilePath(int index) const
{
    QStringList list;
    foreach(MusicSong song, m_musicFileNames[index])
    {
        list << song.getMusicPath();
    }
    return list;
}

void MusicSongsSummarizied::selectRow(int index)
{
    QToolBox::setCurrentIndex(m_currentIndexs);
    m_mainSongLists[m_currentIndexs]->selectRow(index);
}

void MusicSongsSummarizied::setTimerLabel(const QString &time) const
{
    m_mainSongLists[m_currentIndexs]->setTimerLabel(time);
}

void MusicSongsSummarizied::setTransparent(int alpha)
{
    alpha = alpha*2.55;
    foreach(MusicSongsListWidget *item, m_mainSongLists)
    {
        item->setTransparent(alpha);
        item->update();
    }

    alpha += 40;
    setStyleSheet(MusicUIObject::MToolBoxStyle01 + \
                  QString("QToolBox::tab{background-color:rgba(255,255,255,%1);}")
                  .arg(alpha > 255 ? 255 : alpha) );

}

void MusicSongsSummarizied::setMusicPlayCount(int index)
{
    MusicSongs *songs = &m_musicFileNames[m_currentIndexs];
    if(!songs->isEmpty())
    {
        int countNumber = (*songs)[index].getMusicPlayCount();
        (*songs)[index].setMusicPlayCount(++countNumber);
    }
}

void MusicSongsSummarizied::clearAllLists()
{
    while(!m_mainSongLists.isEmpty())
    {
        MusicSongsListWidget *w = m_mainSongLists.takeLast();
        delete w;
        w = nullptr;
    }
}

void MusicSongsSummarizied::setDeleteItemAt(const MIntList &index, bool fileRemove)
{
    if(index.count() == 0)
    {
        return;
    }

    for(int i=index.count()-1; i>=0; --i)
    {
        MusicSong song = m_musicFileNames[currentIndex()].takeAt(index[i]);
        if(fileRemove)
        {
            QFile::remove(song.getMusicPath());
        }
    }
    if(currentIndex() == m_currentIndexs)
    {
        emit deleteItemAt(index);
    }
}

void MusicSongsSummarizied::addNewItem()
{
    if(m_mainSongLists.count() > 8)
    {
        return;
    }

    MusicSongsListWidget *w = new MusicSongsListWidget(this);
    m_mainSongLists.append(w);
    addItem(w, tr("newSongItem"));
    changeItemIcon();
}

void MusicSongsSummarizied::addMusicSongToLovestListAt(int row)
{
    if(!searchFileListEmpty())
    {
        row = getsearchFileListIndex(row);
    }

    MusicSong song = m_musicFileNames[currentIndex()][row];
    m_musicFileNames[1] << song;
    m_mainSongLists[1]->updateSongsFileName(m_musicFileNames[1]);
    if(m_currentIndexs == 1)
    {
        emit updatePlayLists(song.getMusicPath());
    }
    MusicMessageBox message;
    message.setText(tr("add music to lovest list done!"));
    message.exec();
}

void MusicSongsSummarizied::addNetMusicSongToList(const QString &name, const QString &time,
                                                  const QString &format)
{
    const QString path = QString("%1%2.%3").arg(MUSIC_DOWNLOAD_AL).arg(name).arg(format);
    m_musicFileNames[2] << MusicSong(path, 0, time, name);
    m_mainSongLists[2]->updateSongsFileName(m_musicFileNames[2]);
    if(m_currentIndexs == 2)
    {
        emit updatePlayLists(path);
    }
}

void MusicSongsSummarizied::deleteItem()
{
    int index = currentIndex();
    if(index == 0 || index == 1 || index == 2)
    {
        MusicMessageBox message;
        message.setText(tr("The origin one can't delete!"));
        message.exec();
        return;//Not allow to delete the origin three item
    }
    removeItem(index);
}

void MusicSongsSummarizied::changItemName()
{
    int index = currentIndex();
    if(index == 0 || index == 1 || index == 2)
    {
        MusicMessageBox message;
        message.setText(tr("The origin one can't rename!"));
        message.exec();
        return;//Not allow to change name for the origin three item
    }
    if(!m_renameLine)
    {
        m_renameIndex = currentIndex();
        m_renameLine =new MusicSongsToolItemRenamedWidget(m_renameIndex*26,
                                  QToolBox::itemText(m_renameIndex), this);
        connect(m_renameLine, SIGNAL(renameFinished(QString)), SLOT(setChangItemName(QString)));
        m_renameLine->show();
    }
}

void MusicSongsSummarizied::setChangItemName(const QString &name)
{
    setItemText(m_renameIndex, name);
    delete m_renameLine;
    m_renameLine = nullptr;
}

void MusicSongsSummarizied::currentIndexChanged(int)
{
    if(currentIndex() == -1)
    {
        return;
    }
    changeItemIcon();
    if(m_renameLine)
    {
        m_renameLine->renameFinished();
    }
}

void MusicSongsSummarizied::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.setStyleSheet(MusicUIObject::MMenuStyle02);
    menu.addAction(QIcon(":/contextMenu/delete"), tr("deleteItem"), this, SLOT(deleteItem()));
    menu.addAction(QIcon(":/contextMenu/add"), tr("addNewItem"), this, SLOT(addNewItem()));
    menu.addAction(tr("changItemName"), this, SLOT(changItemName()));
    menu.exec(event->globalPos());
}

void MusicSongsSummarizied::changeItemIcon()
{
    for(int i=0; i<count(); ++i)
    {
        setItemIcon(i, QIcon(":/image/arrowup"));
    }
    setItemIcon(currentIndex(), QIcon(":/image/arrowdown"));
}

void MusicSongsSummarizied::setPlaybackMode(MusicObject::SongPlayType mode) const
{
    foreach(MusicSongsListWidget *m, m_mainSongLists)
    {
        m->setPlaybackMode(mode);
    }
}

void MusicSongsSummarizied::setMusicIndexSwaped(int before, int after, int play, QStringList &list)
{
    MusicSongs *names = &m_musicFileNames[currentIndex()];
    if(before > after)
    {
        for(int i=before; i>after; --i)
        {
            names->swap(i, i - 1);
        }
    }
    else
    {
        for(int i=before; i<after; ++i)
        {
            names->swap(i, i + 1);
        }
    }

    list = getMusicSongsFileName(currentIndex());
    if(currentIndex() == m_currentIndexs)
    {
        emit updateMediaLists(getMusicSongsFilePath(m_currentIndexs), play);
    }
}

void MusicSongsSummarizied::isCurrentIndexs(bool &state)
{
    state = ( currentIndex() == m_currentIndexs );
}

void MusicSongsSummarizied::isSearchFileListEmpty(bool &empty)
{
    empty = searchFileListEmpty();
}

void MusicSongsSummarizied::currentMusicSongTreeIndexChanged(int index)
{
    m_mainSongLists[m_currentIndexs]->replacePlayWidgetRow();
    m_currentIndexs = index;
}

void MusicSongsSummarizied::setCurrentIndex()
{
    QStringList keyList = M_SETTING->value(MusicSettingManager::LastPlayIndexChoiced).toStringList();
    m_currentIndexs = keyList[1].toInt();
    int index = keyList[2].toInt();
    QToolBox::setCurrentIndex(index);
    setMusicPlayCount(index);
    emit showCurrentSong(index);
}
<|endoftext|>