<commit_before>
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <QCoreApplication>

#include <fiff/fiff.h>
#include <mne/mne.h>

#include <fiff/fiff_io.h>
#include <fiff/fiff_stream.h>
#include <fiff/c/fiff_digitizer_data.h>

////////////////////////

#include <connectivity/network/network.h>

#include <fiff/fiff_ch_info.h>
#include <fiff/c/fiff_digitizer_data.h>

#include <mne/c/mne_msh_display_surface_set.h>
#include <mne/c/mne_surface_or_volume.h>
//////////////////////

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QCommandLineParser>
#include <QBuffer>
#include <QtEndian>

//=============================================================================================================
// MAIN
//=============================================================================================================

using namespace CONNECTIVITYLIB;
using namespace MNELIB;
using namespace FIFFLIB;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QCommandLineParser parser;
    parser.setApplicationDescription("Disp Example");
    parser.addHelpOption();

    QCommandLineOption inputOption({"file", "f"}, "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QCommandLineOption endianOption({"endian", "e", "en"}, "The file's endianness. 'little' or 'big'", "endian", "big");
    QCommandLineOption padEndOption("pad", "Adds -1 to end of stream to account for unfinished file (use for neuromag2ft)");

    parser.addOption(inputOption);
    parser.addOption(endianOption);
    parser.addOption(padEndOption);

    parser.process(a);

    bool littleEndian = false;
    if (parser.value(endianOption) == "little"){
        littleEndian = true;
    }

    QFile t_fileRaw(parser.value(inputOption));

    std::cout << "\n------------ Fiff Sniffer ------------\n";
    std::cout << "Input file : " << t_fileRaw.fileName().toStdString() << "\n";

    if(!t_fileRaw.exists())
    {
        std::cout << "File cannot be found.\n";
        std::cout << "\nBye!\n";

    } else { //file found
        QBuffer buffer;
        buffer.open(QIODevice::ReadWrite);
        t_fileRaw.open(QIODevice::ReadOnly);
        buffer.write(t_fileRaw.readAll());

        t_fileRaw.close();

        qint32_le iIntToChar;
        char cCharFromInt[sizeof (qint32)];

        if (parser.isSet(padEndOption)){
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
        }

        buffer.reset();

        FIFFLIB::FiffStream stream(&buffer);
        if(littleEndian){
            stream.setByteOrder(QDataStream::LittleEndian);
        }else {
            stream.setByteOrder(QDataStream::BigEndian);
        }

        stream.open();

        FIFFLIB::FiffInfo FifInfo;
        FIFFLIB::FiffDirNode::SPtr DirNode;

        FIFFLIB::FiffDigitizerData digData;

        if(stream.read_meas_info(stream.dirtree(), FifInfo, DirNode)) {

            FIFFLIB::FiffIO p_fiffIO(t_fileRaw);

            std::cout << "Num. raw dat sets: " << p_fiffIO.m_qlistRaw.size() << "\n";
            std::cout << "Num. evoked sets: " << p_fiffIO.m_qlistEvoked.size() << "\n";

            int count = 0;
            for (auto& data : p_fiffIO.m_qlistRaw){
                std::cout << "--- \n";
                std::cout << "Raw Set " << count << "\n";
                std::cout << "Sample frequency: " << data->info.sfreq << "\n";
                std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
                std::cout << "First sample: " << data->first_samp << " | Last sample: " << data->last_samp << "\n";
                std::cout << "Number of samples: " << data->last_samp - data->first_samp << " | Time: " << (data->last_samp - data->first_samp) / data->info.sfreq << " sec. \n";
                std::cout << "Number of digitizer points: " << data->info.dig.size() << "\n";
                for (auto& point : data->info.dig){
                    if (point.kind == FIFFV_POINT_HPI){
                        std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
                    }
                }
            }
            count = 0;
            for (auto& data : p_fiffIO.m_qlistEvoked){
                std::cout << "--- \n";
                std::cout << "Evoked Set " << count << "\n";
                std::cout << "Sample frequency: " << data->info.sfreq << "\n";
                std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
                std::cout << "Num. averaged epochs: " << data->nave << "\n";
            }
            std::cout << "--- \n";
            std::cout << "--------------------------------------\n";
        }
        if(stream.read_digitizer_data(stream.dirtree(), digData)) {
            std::cout << "Digitizer data found.\n";
            std::cout << "Number of digitizer points: " << digData.points.size() << "\n";
            for (auto& point : digData.points){
                if (point.kind == FIFFV_POINT_HPI){
                    std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
                }
            }
        }
    }

    return 0;
}
<commit_msg>MAINT: add guard to open<commit_after>
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <QCoreApplication>

#include <fiff/fiff.h>
#include <mne/mne.h>

#include <fiff/fiff_io.h>
#include <fiff/fiff_stream.h>
#include <fiff/c/fiff_digitizer_data.h>

////////////////////////

#include <connectivity/network/network.h>

#include <fiff/fiff_ch_info.h>
#include <fiff/c/fiff_digitizer_data.h>

#include <mne/c/mne_msh_display_surface_set.h>
#include <mne/c/mne_surface_or_volume.h>
//////////////////////

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QCommandLineParser>
#include <QBuffer>
#include <QtEndian>

//=============================================================================================================
// MAIN
//=============================================================================================================

using namespace CONNECTIVITYLIB;
using namespace MNELIB;
using namespace FIFFLIB;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QCommandLineParser parser;
    parser.setApplicationDescription("Disp Example");
    parser.addHelpOption();

    QCommandLineOption inputOption({"file", "f"}, "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QCommandLineOption endianOption({"endian", "e", "en"}, "The file's endianness. 'little' or 'big'", "endian", "big");
    QCommandLineOption padEndOption("pad", "Adds -1 to end of stream to account for unfinished file (use for neuromag2ft)");

    parser.addOption(inputOption);
    parser.addOption(endianOption);
    parser.addOption(padEndOption);

    parser.process(a);

    bool littleEndian = false;
    if (parser.value(endianOption) == "little"){
        littleEndian = true;
    }

    QFile t_fileRaw(parser.value(inputOption));

    std::cout << "\n------------ Fiff Sniffer ------------\n";
    std::cout << "Input file : " << t_fileRaw.fileName().toStdString() << "\n";

    if(!t_fileRaw.exists())
    {
        std::cout << "File cannot be found.\n";
        std::cout << "\nBye!\n";

    } else { //file found
        QBuffer buffer;
        buffer.open(QIODevice::ReadWrite);
        t_fileRaw.open(QIODevice::ReadOnly);
        buffer.write(t_fileRaw.readAll());

        t_fileRaw.close();

        qint32_le iIntToChar;
        char cCharFromInt[sizeof (qint32)];

        if (parser.isSet(padEndOption)){
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
            iIntToChar = -1;
            memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
            buffer.write(cCharFromInt);
        }

        buffer.reset();

        FIFFLIB::FiffStream stream(&buffer);
        if(littleEndian){
            stream.setByteOrder(QDataStream::LittleEndian);
        }else {
            stream.setByteOrder(QDataStream::BigEndian);
        }

        if(stream.open()){
            FIFFLIB::FiffInfo FifInfo;
            FIFFLIB::FiffDirNode::SPtr DirNode;

            FIFFLIB::FiffDigitizerData digData;

            if(stream.read_meas_info(stream.dirtree(), FifInfo, DirNode)) {

                FIFFLIB::FiffIO p_fiffIO(t_fileRaw);

                std::cout << "Num. raw dat sets: " << p_fiffIO.m_qlistRaw.size() << "\n";
                std::cout << "Num. evoked sets: " << p_fiffIO.m_qlistEvoked.size() << "\n";

                int count = 0;
                for (auto& data : p_fiffIO.m_qlistRaw){
                    std::cout << "--- \n";
                    std::cout << "Raw Set " << count << "\n";
                    std::cout << "Sample frequency: " << data->info.sfreq << "\n";
                    std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
                    std::cout << "First sample: " << data->first_samp << " | Last sample: " << data->last_samp << "\n";
                    std::cout << "Number of samples: " << data->last_samp - data->first_samp << " | Time: " << (data->last_samp - data->first_samp) / data->info.sfreq << " sec. \n";
                    std::cout << "Number of digitizer points: " << data->info.dig.size() << "\n";
                    for (auto& point : data->info.dig){
                        if (point.kind == FIFFV_POINT_HPI){
                            std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
                        }
                    }
                }
                count = 0;
                for (auto& data : p_fiffIO.m_qlistEvoked){
                    std::cout << "--- \n";
                    std::cout << "Evoked Set " << count << "\n";
                    std::cout << "Sample frequency: " << data->info.sfreq << "\n";
                    std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
                    std::cout << "Num. averaged epochs: " << data->nave << "\n";
                }
                std::cout << "--- \n";
                std::cout << "--------------------------------------\n";
            }
            if(stream.read_digitizer_data(stream.dirtree(), digData)) {
                std::cout << "Digitizer data found.\n";
                std::cout << "Number of digitizer points: " << digData.points.size() << "\n";
                for (auto& point : digData.points){
                    if (point.kind == FIFFV_POINT_HPI){
                        std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
                    }
                }
            }
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <boost/exception/diagnostic_information.hpp>
#include <jni.h>

#include "com_cruzdb_Log.h"
#include "portal.h"

void Java_com_cruzdb_Log_disposeInternal(
    JNIEnv *env, jobject jobj, jlong jhandle)
{
  std::cout << "delete" << std::endl;
  delete reinterpret_cast<LogWrapper*>(jhandle);
}

void Java_com_cruzdb_Log_openNative(JNIEnv *env, jobject jobj, jstring jpool,
    jstring jseqr_server, jint jseqr_port, jstring jlog_name)
{
  std::stringstream port;
  const char *seqr_server;
  const char *log_name;
  const char *pool;
  LogWrapper *log = new LogWrapper;

  /*
   * Connect to RADOS
   */
  int ret = log->rados.init(NULL);
  if (ret)
    goto out;

  ret = log->rados.conf_read_file(NULL);
  if (ret)
    goto out;

  ret = log->rados.conf_parse_env(NULL);
  if (ret)
    goto out;

  ret = log->rados.connect();
  if (ret)
    goto out;

  pool = env->GetStringUTFChars(jpool, 0);
  ret = log->rados.ioctx_create(pool, log->ioctx);
  env->ReleaseStringUTFChars(jpool, pool);
  if (ret)
    goto out;

  /*
   * Connect to sequencer
   */
  port << jseqr_port;
  seqr_server = env->GetStringUTFChars(jseqr_server, 0);
  log->seqr_client = new zlog::SeqrClient(seqr_server, port.str().c_str());
  env->ReleaseStringUTFChars(jseqr_server, seqr_server);
  try {
    log->seqr_client->Connect();
  } catch (...) {
    ZlogExceptionJni::ThrowNew(env,
        boost::current_exception_diagnostic_information());
    goto out_noexcept;
  }

  log_name = env->GetStringUTFChars(jlog_name, 0);
  ret = zlog::Log::OpenOrCreate(log->ioctx, log_name, log->seqr_client, &log->log);
  env->ReleaseStringUTFChars(jlog_name, log_name);
  if (ret)
    goto out;

  ZlogJni::setHandle(env, jobj, log);
  return;

out:
  ZlogExceptionJni::ThrowNew(env, ret);

out_noexcept:
  delete log;
}

jlong Java_com_cruzdb_Log_append(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jbyteArray jdata, jint jdata_len)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  jbyte *data = env->GetByteArrayElements(jdata, 0);

  uint64_t position;
  int ret = log->log->Append(Slice((char*)data, jdata_len), &position);
  ZlogExceptionJni::ThrowNew(env, ret);
  env->ReleaseByteArrayElements(jdata, data, JNI_ABORT);

  return position;
}

jbyteArray Java_com_cruzdb_Log_read(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  std::string entry;

  int ret = log->log->Read(position, &entry);
  if (ret) {
    if (ret == -ENODEV)
      NotWrittenExceptionJni::ThrowNew(env, ret);
    else if (ret == -EFAULT)
      FilledExceptionJni::ThrowNew(env, ret);
    else
      ZlogExceptionJni::ThrowNew(env, ret);
    return nullptr;
  }

  jbyteArray result = env->NewByteArray(static_cast<jsize>(entry.size()));
  env->SetByteArrayRegion(result, 0, static_cast<jsize>(entry.size()),
      reinterpret_cast<const jbyte*>(entry.data()));
  return result;
}

void Java_com_cruzdb_Log_fill(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  int ret = log->log->Fill(position);
  if (ret == -EROFS)
    ReadOnlyExceptionJni::ThrowNew(env, ret);
  else
    ZlogExceptionJni::ThrowNew(env, ret);
}

void Java_com_cruzdb_Log_trim(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  int ret = log->log->Trim(position);
  ZlogExceptionJni::ThrowNew(env, ret);
}

jlong Java_com_cruzdb_Log_tail(JNIEnv *env, jobject jlog,
    jlong jlog_handle)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position;
  int ret = log->log->CheckTail(&position);
  ZlogExceptionJni::ThrowNew(env, ret);
  return position;
}
<commit_msg>java: fix backend<commit_after>#include <iostream>
#include <boost/exception/diagnostic_information.hpp>
#include <jni.h>

#include "com_cruzdb_Log.h"
#include "portal.h"
#include "zlog/ceph_backend.h"

void Java_com_cruzdb_Log_disposeInternal(
    JNIEnv *env, jobject jobj, jlong jhandle)
{
  std::cout << "delete" << std::endl;
  delete reinterpret_cast<LogWrapper*>(jhandle);
}

void Java_com_cruzdb_Log_openNative(JNIEnv *env, jobject jobj, jstring jpool,
    jstring jseqr_server, jint jseqr_port, jstring jlog_name)
{
  std::stringstream port;
  const char *seqr_server;
  const char *log_name;
  const char *pool;
  LogWrapper *log = new LogWrapper;

  /*
   * Connect to RADOS
   */
  int ret = log->rados.init(NULL);
  if (ret)
    goto out;

  ret = log->rados.conf_read_file(NULL);
  if (ret)
    goto out;

  ret = log->rados.conf_parse_env(NULL);
  if (ret)
    goto out;

  ret = log->rados.connect();
  if (ret)
    goto out;

  pool = env->GetStringUTFChars(jpool, 0);
  ret = log->rados.ioctx_create(pool, log->ioctx);
  env->ReleaseStringUTFChars(jpool, pool);
  if (ret)
    goto out;

  /*
   * Connect to sequencer
   */
  port << jseqr_port;
  seqr_server = env->GetStringUTFChars(jseqr_server, 0);
  log->seqr_client = new zlog::SeqrClient(seqr_server, port.str().c_str());
  env->ReleaseStringUTFChars(jseqr_server, seqr_server);
  try {
    log->seqr_client->Connect();
  } catch (...) {
    ZlogExceptionJni::ThrowNew(env,
        boost::current_exception_diagnostic_information());
    goto out_noexcept;
  }

  // FIXME: this is a memory leak!
  CephBackend *be = new CephBackend(&log->ioctx);

  log_name = env->GetStringUTFChars(jlog_name, 0);
  ret = zlog::Log::OpenOrCreate(be, log_name, log->seqr_client, &log->log);
  env->ReleaseStringUTFChars(jlog_name, log_name);
  if (ret)
    goto out;

  ZlogJni::setHandle(env, jobj, log);
  return;

out:
  ZlogExceptionJni::ThrowNew(env, ret);

out_noexcept:
  delete log;
}

jlong Java_com_cruzdb_Log_append(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jbyteArray jdata, jint jdata_len)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  jbyte *data = env->GetByteArrayElements(jdata, 0);

  uint64_t position;
  int ret = log->log->Append(Slice((char*)data, jdata_len), &position);
  ZlogExceptionJni::ThrowNew(env, ret);
  env->ReleaseByteArrayElements(jdata, data, JNI_ABORT);

  return position;
}

jbyteArray Java_com_cruzdb_Log_read(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  std::string entry;

  int ret = log->log->Read(position, &entry);
  if (ret) {
    if (ret == -ENODEV)
      NotWrittenExceptionJni::ThrowNew(env, ret);
    else if (ret == -EFAULT)
      FilledExceptionJni::ThrowNew(env, ret);
    else
      ZlogExceptionJni::ThrowNew(env, ret);
    return nullptr;
  }

  jbyteArray result = env->NewByteArray(static_cast<jsize>(entry.size()));
  env->SetByteArrayRegion(result, 0, static_cast<jsize>(entry.size()),
      reinterpret_cast<const jbyte*>(entry.data()));
  return result;
}

void Java_com_cruzdb_Log_fill(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  int ret = log->log->Fill(position);
  if (ret == -EROFS)
    ReadOnlyExceptionJni::ThrowNew(env, ret);
  else
    ZlogExceptionJni::ThrowNew(env, ret);
}

void Java_com_cruzdb_Log_trim(JNIEnv *env, jobject jlog,
    jlong jlog_handle, jlong jpos)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position = jpos;
  int ret = log->log->Trim(position);
  ZlogExceptionJni::ThrowNew(env, ret);
}

jlong Java_com_cruzdb_Log_tail(JNIEnv *env, jobject jlog,
    jlong jlog_handle)
{
  auto log = reinterpret_cast<LogWrapper*>(jlog_handle);

  uint64_t position;
  int ret = log->log->CheckTail(&position);
  ZlogExceptionJni::ThrowNew(env, ret);
  return position;
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 nyorain
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt

///  file Contains the Span template class for not-owned contigous ranges.

#pragma once

#ifndef NYTL_INCLUDE_SPAN
#define NYTL_INCLUDE_SPAN

#include <nytl/fwd/span.hpp> // nytl::Span default template parameter
#include <nytl/scalar.hpp> // nytl::constants::dynamicSize

#include <cstdlib> // std::size_t
#include <stdexcept> // std::out_of_range
#include <initializer_list> // std::initializer_list
#include <array> // std::array

namespace nytl {
namespace detail {
	template<typename T, typename C, typename = void> struct ValidContainerT;
	template<typename T, typename C> using ValidContainer = typename ValidContainerT<T, C>::type;
} // namespace nytl::detail

/// The underlaying storage type of spans that is specialized for dyanmic size.
template<typename T, std::size_t N> struct SpanStorage;

/// \brief Describes a contigous, non-owned range of elements of type 'T'.
/// \details Spans can be used to pass sequences of elements around in a lightweight manner.
/// Its main use are function parameters sine instead of a std::vector it will not allocate
/// any memory or copy any elements but instead just reference them.
/// \tparam T The type the range is defined over. Use const types for non-mutable ranges.
/// \tparam N The size of the range. If not known at compile
/// time, use nytl::constants::dynamicSize (also defaulted to dynamicSize).
///
/// Some examples below. Note that Spans must be used carefully outside of temporary
/// expressions since they are only valid as long the object they reference is valid.
/// ```cpp
/// void foo(nytl::Span<std::string> names); // takes dyanmic amount of strings, might modify it
/// void bar(nytl::Span<const std::string, 3> names); // takes exactly 3 const strings
/// void baz(nytl::Span<const std::string, 5> names); // takes exactly 5 const strings
///
/// int main()
/// {
///		std::array<std::string, 3> namesArray {"foo", "bar", "baz"};
///		foo(namesArray); // works
/// 	bar(namesArray); // works
///		baz(namesArray); // will throw std::logic_error since baz requires exactly 5 strings
///
///		std::vector<std::string> namesVector {"foo", "bar", "baz", "abz", "bla"};
///		foo(namesVector); // works
///		bar(namesVector); // will throw std::logic_error since bar requires exactly 3 strings
///		baz(namesVector); // works
///
/// 	// If we only want the first 3 elements from namesVector as range we can do it like this
///		bar({namesVector.data(), 3}); // works, takes the first 3 elements
///		foo({*namesVector.data(), 4}); // we can also use references
///
///		// careful when using span outside of temporary expressions
///		auto span = nytl::Span<int>(std::vector<int>{4, 1, 2, 0});
/// 	// std::cout << span[0] << "\n"; // undefined behaviour!
/// }
///
/// void foo(nytl::Span<std::string> names)
/// {
///		// Some usage possibilities for span.
////	// The main usage is iterating over it:
///		for(auto& name : names)
///			std::cout << name << "\n";
///
///		// We might alternatively do this with a traditional for loop
///		for(auto i = 0u; i < names.size(); ++i)
///			std::cout << name << "\n";
///
///		// In this case we have a span of std::string, not const std::string,
///		// therefore we might also change it. This will change the names in the actual
///		// sequence this span references. Usually nytl::Span<const T> is used when the
///		// span is only read
///		if(!names.empty()) {
///			names.front() = "first name";
///			names.back() = "last name";
///		}
///
///		// A span can additionally be sliced into a subspan. This can either be
///		// done with a size known at compile time (which will result in a fixed-size span)
///		// or dynamically for a dynamic-sized span.
///		if(names.size() <= 2) return;
///		for(auto& name : names.slice(2, names.size() - 2)) // output everything but the first two
///			std::cout << name << "\n";
///
///		for(auto& name : names.slice<2>(0)) // output only the first two names
///			std::cout << name << "\n";
/// }
/// ```
template<typename T, std::size_t N>
class Span : public SpanStorage<T, N> {
public:
	using Value = T;
	using Iterator = T*;
	using ReverseIterator = std::reverse_iterator<T*>;
	using Reference = T&;
	using Pointer = T*;
	using Difference = std::ptrdiff_t;
	using Size = std::size_t;

public:
	using SpanStorage<T, N>::SpanStorage;
	constexpr Span() noexcept = default;
	constexpr Span(std::nullptr_t) noexcept : Span(nullptr, 0) {}

	template<typename C, typename = detail::ValidContainer<T, C>>
	constexpr Span(C& c) : Span(c.data(), c.size()) {}

	template<typename C, typename = detail::ValidContainer<T, C>, std::size_t S = C::size()>
	constexpr Span(C& c) : Span(c.data()) {}

	constexpr Pointer data() const noexcept { return this->data_; }
	constexpr Size size() const noexcept { return this->size_; }
	constexpr bool empty() const noexcept { return size() == 0; }

	constexpr Iterator begin() const noexcept { return data(); }
	constexpr Iterator end() const noexcept { return data() + size(); }

	constexpr ReverseIterator rbegin() const noexcept { return {end()}; }
	constexpr ReverseIterator rend() const noexcept { return {begin()}; }

	constexpr Reference operator[](Size i) const noexcept { return *(data() + i); }
	constexpr Reference at(Size i) const { checkThrow(i); return data()[i]; }

	constexpr Reference front() const noexcept { return *data(); }
	constexpr Reference back() const noexcept { return *(data() + size() - 1); }

	constexpr Span<T> slice(Size pos, Size size) const { return {data() + pos, size}; }
	template<Size S> constexpr Span<T, S> slice(Size pos) const { return {data() + pos}; }

protected:
	void checkThrow(Size i) const { if(i >= size()) throw std::out_of_range("nytl::Span::at"); }
};

// Default SpanStorage implementation for compile-time size
template<typename T, std::size_t N>
struct SpanStorage {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(T* pointer, std::size_t size = N) : data_(pointer)
	{
		if(size != N) throw std::logic_error("nytl::Span:: invalid size");
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(T& ref, std::size_t size = N) : SpanStorage(&ref, size) {}
	constexpr SpanStorage(T (&arr)[N]) : SpanStorage(arr, N) {}

	T* data_ {};
	constexpr static auto size_ = N;
};

// SpanStorage specialization for runtime size. Stored an extra size value.
template<typename T>
struct SpanStorage<T, constants::dynamicSize> {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(T* pointer, std::size_t size = 1) : data_(pointer), size_(size)
	{
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(T& ref, std::size_t size = 1) : SpanStorage(&ref, size) {}
	template<std::size_t S> constexpr SpanStorage(T (&arr)[S]) : SpanStorage(arr, S) {}

	T* data_ {};
	std::size_t size_ {};
};

// SpanStorage specialization for runtime size with const parameter.
// Allows constrsuction from initializer list.
template<typename T>
struct SpanStorage<const T, 0> {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(const T* pointer, std::size_t size = 1) : data_(pointer), size_(size)
	{
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(const T& ref, std::size_t size = 1) : SpanStorage(&ref, size) {}
	template<std::size_t S> constexpr SpanStorage(T (&arr)[S]) : SpanStorage(arr, S) {}
	constexpr SpanStorage(const std::initializer_list<T>& l) : SpanStorage(l.begin(), l.size()) {}

	const T* data_ {};
	std::size_t size_ {};
};

namespace detail {

// Returns whether 'C' is a valid container to construct a Span<T> from
template<typename T, typename C>
struct ValidContainerT<T, C,
	typename std::enable_if<
		std::is_convertible<
			decltype(std::declval<C>().data()),
			T*
		>::value &&
		std::is_convertible<
			decltype(std::declval<C>().size()),
			std::size_t
		>::value
	>::type
> { using type = void; };

} // namespace detail
} // namespace nytl

#endif // header guard
<commit_msg>Update span.hpp<commit_after>// Copyright (c) 2017 nyorain
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt

///  file Contains the Span template class for not-owned contigous ranges.

#pragma once

#ifndef NYTL_INCLUDE_SPAN
#define NYTL_INCLUDE_SPAN

#include <nytl/fwd/span.hpp> // nytl::Span default template parameter
#include <nytl/scalar.hpp> // nytl::constants::dynamicSize

#include <cstdlib> // std::size_t
#include <stdexcept> // std::out_of_range
#include <initializer_list> // std::initializer_list
#include <array> // std::array

namespace nytl {
namespace detail {
	template<typename T, typename C, typename = void> struct ValidContainerT;
	template<typename T, typename C> using ValidContainer = typename ValidContainerT<T, C>::type;
} // namespace nytl::detail

/// The underlaying storage type of spans that is specialized for dyanmic size.
template<typename T, std::size_t N> struct SpanStorage;

/// \brief Describes a contigous, non-owned range of elements of type 'T'.
/// \details Spans can be used to pass sequences of elements around in a lightweight manner.
/// Its main use are function parameters sine instead of a std::vector it will not allocate
/// any memory or copy any elements but instead just reference them.
/// \tparam T The type the range is defined over. Use const types for non-mutable ranges.
/// \tparam N The size of the range. If not known at compile
/// time, use nytl::constants::dynamicSize (also defaulted to dynamicSize).
///
/// Some examples below. Note that Spans must be used carefully outside of temporary
/// expressions since they are only valid as long the object they reference is valid.
/// ```cpp
/// void foo(nytl::Span<std::string> names); // takes dyanmic amount of strings, might modify it
/// void bar(nytl::Span<const std::string, 3> names); // takes exactly 3 const strings
/// void baz(nytl::Span<const std::string, 5> names); // takes exactly 5 const strings
///
/// int main()
/// {
///		std::array<std::string, 3> namesArray {"foo", "bar", "baz"};
///		foo(namesArray); // works
/// 	bar(namesArray); // works
///		baz(namesArray); // will throw std::logic_error since baz requires exactly 5 strings
///
///		std::vector<std::string> namesVector {"foo", "bar", "baz", "abz", "bla"};
///		foo(namesVector); // works
///		bar(namesVector); // will throw std::logic_error since bar requires exactly 3 strings
///		baz(namesVector); // works
///
/// 	// If we only want the first 3 elements from namesVector as range we can do it like this
///		bar({namesVector.data(), 3}); // works, takes the first 3 elements
///		foo({*namesVector.data(), 4}); // we can also use references
///
///		// careful when using span outside of temporary expressions
///		auto span = nytl::Span<int>(std::vector<int>{4, 1, 2, 0});
/// 	// std::cout << span[0] << "\n"; // undefined behaviour!
/// }
///
/// void foo(nytl::Span<std::string> names)
/// {
///		// Some usage possibilities for span.
////	// The main usage is iterating over it:
///		for(auto& name : names)
///			std::cout << name << "\n";
///
///		// We might alternatively do this with a traditional for loop
///		for(auto i = 0u; i < names.size(); ++i)
///			std::cout << name << "\n";
///
///		// In this case we have a span of std::string, not const std::string,
///		// therefore we might also change it. This will change the names in the actual
///		// sequence this span references. Usually nytl::Span<const T> is used when the
///		// span is only read
///		if(!names.empty()) {
///			names.front() = "first name";
///			names.back() = "last name";
///		}
///
///		// A span can additionally be sliced into a subspan. This can either be
///		// done with a size known at compile time (which will result in a fixed-size span)
///		// or dynamically for a dynamic-sized span.
///		if(names.size() <= 2) return;
///		for(auto& name : names.slice(2, names.size() - 2)) // output everything but the first two
///			std::cout << name << "\n";
///
///		for(auto& name : names.slice<2>(0)) // output only the first two names
///			std::cout << name << "\n";
/// }
/// ```
template<typename T, std::size_t N>
class Span : public SpanStorage<T, N> {
public:
	using Value = T;
	using Iterator = T*;
	using ReverseIterator = std::reverse_iterator<T*>;
	using Reference = T&;
	using Pointer = T*;
	using Difference = std::ptrdiff_t;
	using Size = std::size_t;

public:
	using SpanStorage<T, N>::SpanStorage;
	constexpr Span() noexcept = default;
	constexpr Span(std::nullptr_t) noexcept : Span(nullptr, 0) {}

	template<typename C, typename = detail::ValidContainer<T, C>>
	constexpr Span(C& c) : Span(c.data(), c.size()) {}

	template<typename C, typename = detail::ValidContainer<T, C>, std::size_t S = C::size()>
	constexpr Span(C& c) : Span(c.data()) {}

	constexpr Pointer data() const noexcept { return this->data_; }
	constexpr Size size() const noexcept { return this->size_; }
	constexpr bool empty() const noexcept { return size() == 0; }

	constexpr Iterator begin() const noexcept { return data(); }
	constexpr Iterator end() const noexcept { return data() + size(); }

	constexpr ReverseIterator rbegin() const noexcept { return {end()}; }
	constexpr ReverseIterator rend() const noexcept { return {begin()}; }

	constexpr Reference operator[](Size i) const noexcept { return *(data() + i); }
	constexpr Reference at(Size i) const { checkThrow(i); return data()[i]; }

	constexpr Reference front() const noexcept { return *data(); }
	constexpr Reference back() const noexcept { return *(data() + size() - 1); }

	constexpr Span<T> slice(Size pos, Size size) const { return {data() + pos, size}; }
	template<Size S> constexpr Span<T, S> slice(Size pos) const { return {data() + pos}; }

protected:
	void checkThrow(Size i) const { if(i >= size()) throw std::out_of_range("nytl::Span::at"); }
};

// Default SpanStorage implementation for compile-time size
template<typename T, std::size_t N>
struct SpanStorage {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(T* pointer, std::size_t size = N) : data_(pointer)
	{
		if(size != N) throw std::logic_error("nytl::Span:: invalid size");
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(T& ref, std::size_t size = N) : SpanStorage(&ref, size) {}
	constexpr SpanStorage(T (&arr)[N]) : SpanStorage(arr, N) {}

	T* data_ {};
	constexpr static auto size_ = N;
};

// SpanStorage specialization for runtime size. Stored an extra size value.
template<typename T>
struct SpanStorage<T, constants::dynamicSize> {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(T* pointer, std::size_t size = 1) : data_(pointer), size_(size)
	{
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(T& ref, std::size_t size = 1) : SpanStorage(&ref, size) {}
	template<std::size_t S> constexpr SpanStorage(T (&arr)[S]) : SpanStorage(arr, S) {}

	T* data_ {};
	std::size_t size_ {};
};

// SpanStorage specialization for runtime size with const parameter.
// Allows constrsuction from initializer list.
template<typename T>
struct SpanStorage<const T, constants::dynamicSize> {
	constexpr SpanStorage() noexcept = default;
	constexpr SpanStorage(const T* pointer, std::size_t size = 1) : data_(pointer), size_(size)
	{
		if(!pointer && size != 0) throw std::logic_error("nytl::Span:: invalid data");
	}
	constexpr SpanStorage(const T& ref, std::size_t size = 1) : SpanStorage(&ref, size) {}
	template<std::size_t S> constexpr SpanStorage(T (&arr)[S]) : SpanStorage(arr, S) {}
	constexpr SpanStorage(const std::initializer_list<T>& l) : SpanStorage(l.begin(), l.size()) {}

	const T* data_ {};
	std::size_t size_ {};
};

namespace detail {

// Returns whether 'C' is a valid container to construct a Span<T> from
template<typename T, typename C>
struct ValidContainerT<T, C,
	typename std::enable_if<
		std::is_convertible<
			decltype(std::declval<C>().data()),
			T*
		>::value &&
		std::is_convertible<
			decltype(std::declval<C>().size()),
			std::size_t
		>::value
	>::type
> { using type = void; };

} // namespace detail
} // namespace nytl

#endif // header guard
<|endoftext|>


<commit_before>/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: mdsteele@google.com (Matthew D. Steele)

#include "net/instaweb/htmlparse/public/html_parse_test_base.h"
#include "net/instaweb/http/public/content_type.h"
#include "net/instaweb/util/public/mock_message_handler.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/resource_manager_test_base.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"

namespace net_instaweb {

namespace {

class CssInlineFilterTest : public ResourceManagerTestBase,
                            public ::testing::WithParamInterface<bool> {
 public:
  CssInlineFilterTest() : filters_added_(false) {}

 protected:
  virtual void SetUp() {
    ResourceManagerTestBase::SetUp();
  }

  void TestInlineCssWithOutputUrl(
                     const GoogleString& html_url,
                     const GoogleString& css_url,
                     const GoogleString& css_out_url,
                     const GoogleString& other_attrs,
                     const GoogleString& css_original_body,
                     bool expect_inline,
                     const GoogleString& css_rewritten_body) {
    if (!filters_added_) {
      AddFilter(RewriteOptions::kInlineCss);
      filters_added_ = true;
    }

    GoogleString html_template = StrCat(
        "\n",
        "  <link rel=\"stylesheet\" href=\"%s\"",
        (other_attrs.empty() ? "" : " " + other_attrs) + ">\n",
        "\n",
        "Hello, world!\n");

    const GoogleString html_input =
        StringPrintf(html_template.c_str(), css_url.c_str());

    const GoogleString outline_html_output =
        StringPrintf(html_template.c_str(), css_out_url.c_str());

    // Put original CSS file into our fetcher.
    ResponseHeaders default_css_header;
    SetDefaultLongCacheHeaders(&kContentTypeCss, &default_css_header);
    SetFetchResponse(css_url, default_css_header, css_original_body);

    // Rewrite the HTML page.
    ParseUrl(html_url, html_input);

    const GoogleString expected_output =
        (!expect_inline ? outline_html_output :
         "\n"
         "  \n"
         "\n"
         "Hello, world!\n");
    EXPECT_EQ(AddHtmlBody(expected_output), output_buffer_);
  }

  void TestInlineCss(const GoogleString& html_url,
                     const GoogleString& css_url,
                     const GoogleString& other_attrs,
                     const GoogleString& css_original_body,
                     bool expect_inline,
                     const GoogleString& css_rewritten_body) {
    TestInlineCssWithOutputUrl(
        html_url, css_url, css_url, other_attrs, css_original_body,
        expect_inline, css_rewritten_body);
  }

 private:
  bool filters_added_;
};

TEST_P(CssInlineFilterTest, InlineCssSimple) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, InlineCss404) {
  // Test to make sure that a missing input is handled well.
  SetFetchResponse404("404.css");
  ValidateNoChanges("404", "<link rel=stylesheet href='404.css'>");

  // Second time, to make sure caching doesn't break it.
  ValidateNoChanges("404", "<link rel=stylesheet href='404.css'>");
}

TEST_P(CssInlineFilterTest, InlineCssCached) {
  // Doing it twice should be safe, too.
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, InlineCssRewriteUrls1) {
  // CSS with a relative URL that needs to be changed:
  const GoogleString css1 =
      "BODY { background-image: url('bg.png'); }\n";
  const GoogleString css2 =
      "BODY { background-image: url('foo/bar/bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/foo/bar/baz.css",
                "", css1, true, css2);
}

TEST_P(CssInlineFilterTest, InlineCssRewriteUrls2) {
  // CSS with a relative URL, this time with ".." in it:
  const GoogleString css1 =
      "BODY { background-image: url('../quux/bg.png'); }\n";
  const GoogleString css2 =
      "BODY { background-image: url('foo/quux/bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/foo/bar/baz.css",
                "", css1, true, css2);
}

TEST_P(CssInlineFilterTest, NoRewriteUrlsSameDir) {
  const GoogleString css = "BODY { background-image: url('bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/baz.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, ShardSubresources) {
  UseMd5Hasher();
  DomainLawyer* lawyer = options()->domain_lawyer();
  lawyer->AddShard("www.example.com", "shard1.com,shard2.com",
                   &message_handler_);

  const GoogleString css_in =
      ".p1 { background-image: url('b1.png'); }"
      ".p2 { background-image: url('b2.png'); }";
  const GoogleString css_out =
      ".p1 { background-image: url('http://shard2.com/b1.png'); }"
      ".p2 { background-image: url('http://shard1.com/b2.png'); }";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/baz.css",
                "", css_in, true, css_out);
}

TEST_P(CssInlineFilterTest, DoNotInlineCssWithMediaAttr) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "media=\"print\"", css, false, "");
}

TEST_P(CssInlineFilterTest, DoInlineCssWithMediaAll) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "media=\"all\"", css, true, css);
}

TEST_P(CssInlineFilterTest, DoNotInlineCssTooBig) {
  // CSS too large to inline:
  const int64 length = 2 * RewriteOptions::kDefaultCssInlineMaxBytes;
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css", "",
                ("BODY { background-image: url('" +
                 GoogleString(length, 'z') + ".png'); }\n"),
                false, "");
}

TEST_P(CssInlineFilterTest, DoNotInlineCssDifferentDomain) {
  // Note: This only fails because we haven't autorized www.example.org
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.org/styles.css",
                "", "BODY { color: red; }\n", false, "");
}

TEST_P(CssInlineFilterTest, CorrectlyInlineCssWithImports) {
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/dir/styles.css", "",
                "@import \"foo.css\"; BODY { color: red; }\n", true,
                "@import \"dir/foo.css\"; BODY { color: red; }\n");
}

// http://code.google.com/p/modpagespeed/issues/detail?q=css&id=252
TEST_P(CssInlineFilterTest, ClaimsXhtmlButHasUnclosedLink) {
  // XHTML text should not have unclosed links.  But if they do, like
  // in Issue 252, then we should leave them alone.
  static const char html_format[] =
      "\n"
      "  %s\n"
      "  %s\n"
      "  "     // 'in' <link>
      "\n"
      "

\n"
      "  Yellow on Blue

";

  static const char unclosed_css[] =
      "  <link rel='stylesheet' href='a.css' type='text/css'>\n";  // unclosed
  static const char inlined_css[] = "  \n";

  // Put original CSS files into our fetcher.
  ResponseHeaders default_css_header;
  SetDefaultLongCacheHeaders(&kContentTypeCss, &default_css_header);
  SetFetchResponse(StrCat(kTestDomain, "a.css"), default_css_header, ".a {}");
  AddFilter(RewriteOptions::kInlineCss);
  ValidateExpected("claims_xhtml_but_has_unclosed_links",
                   StringPrintf(html_format, kXhtmlDtd, unclosed_css),
                   StringPrintf(html_format, kXhtmlDtd, inlined_css));
}

TEST_P(CssInlineFilterTest, InlineCombined) {
  // Make sure we interact with CSS combiner properly, including in cached
  // case.
  options()->EnableFilter(RewriteOptions::kInlineCss);
  options()->EnableFilter(RewriteOptions::kCombineCss);
  rewrite_driver()->AddFilters();

  const char kCssUrl[] = "a.css";
  const char kCss[] = "div {display:block;}";

  InitResponseHeaders(kCssUrl, kContentTypeCss, kCss, 3000);

  GoogleString html_input =
      StrCat("<link rel=stylesheet href=\"", kCssUrl, "\">",
             "<link rel=stylesheet href=\"", kCssUrl, "\">");
  GoogleString html_output= StrCat("");

  ValidateExpected("inline_combined", html_input, html_output);
  ValidateExpected("inline_combined", html_input, html_output);
}

TEST_P(CssInlineFilterTest, InlineMinimizeInteraction) {
  // There was a bug in async mode where we would accidentally prevent
  // minification results from rendering when inlining was not to be done.
  options()->EnableFilter(RewriteOptions::kRewriteCss);
  options()->set_css_inline_max_bytes(4);

  TestInlineCssWithOutputUrl(
      StrCat(kTestDomain, "minimize_but_not_inline.html"),
      StrCat(kTestDomain, "a.css"),
      Encode(kTestDomain, "cf", "0", "a.css", "css"),
      "", /* no other attributes*/
      "div{display: none;}",
      false,
      "div{display: none}");
}

INSTANTIATE_TEST_CASE_P(CssInlineFilterTestInstance,
                        CssInlineFilterTest,
                        ::testing::Bool());

}  // namespace

}  // namespace net_instaweb
<commit_msg>Spelling<commit_after>/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: mdsteele@google.com (Matthew D. Steele)

#include "net/instaweb/htmlparse/public/html_parse_test_base.h"
#include "net/instaweb/http/public/content_type.h"
#include "net/instaweb/util/public/mock_message_handler.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/resource_manager_test_base.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"

namespace net_instaweb {

namespace {

class CssInlineFilterTest : public ResourceManagerTestBase,
                            public ::testing::WithParamInterface<bool> {
 public:
  CssInlineFilterTest() : filters_added_(false) {}

 protected:
  virtual void SetUp() {
    ResourceManagerTestBase::SetUp();
  }

  void TestInlineCssWithOutputUrl(
                     const GoogleString& html_url,
                     const GoogleString& css_url,
                     const GoogleString& css_out_url,
                     const GoogleString& other_attrs,
                     const GoogleString& css_original_body,
                     bool expect_inline,
                     const GoogleString& css_rewritten_body) {
    if (!filters_added_) {
      AddFilter(RewriteOptions::kInlineCss);
      filters_added_ = true;
    }

    GoogleString html_template = StrCat(
        "\n",
        "  <link rel=\"stylesheet\" href=\"%s\"",
        (other_attrs.empty() ? "" : " " + other_attrs) + ">\n",
        "\n",
        "Hello, world!\n");

    const GoogleString html_input =
        StringPrintf(html_template.c_str(), css_url.c_str());

    const GoogleString outline_html_output =
        StringPrintf(html_template.c_str(), css_out_url.c_str());

    // Put original CSS file into our fetcher.
    ResponseHeaders default_css_header;
    SetDefaultLongCacheHeaders(&kContentTypeCss, &default_css_header);
    SetFetchResponse(css_url, default_css_header, css_original_body);

    // Rewrite the HTML page.
    ParseUrl(html_url, html_input);

    const GoogleString expected_output =
        (!expect_inline ? outline_html_output :
         "\n"
         "  \n"
         "\n"
         "Hello, world!\n");
    EXPECT_EQ(AddHtmlBody(expected_output), output_buffer_);
  }

  void TestInlineCss(const GoogleString& html_url,
                     const GoogleString& css_url,
                     const GoogleString& other_attrs,
                     const GoogleString& css_original_body,
                     bool expect_inline,
                     const GoogleString& css_rewritten_body) {
    TestInlineCssWithOutputUrl(
        html_url, css_url, css_url, other_attrs, css_original_body,
        expect_inline, css_rewritten_body);
  }

 private:
  bool filters_added_;
};

TEST_P(CssInlineFilterTest, InlineCssSimple) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, InlineCss404) {
  // Test to make sure that a missing input is handled well.
  SetFetchResponse404("404.css");
  ValidateNoChanges("404", "<link rel=stylesheet href='404.css'>");

  // Second time, to make sure caching doesn't break it.
  ValidateNoChanges("404", "<link rel=stylesheet href='404.css'>");
}

TEST_P(CssInlineFilterTest, InlineCssCached) {
  // Doing it twice should be safe, too.
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, InlineCssRewriteUrls1) {
  // CSS with a relative URL that needs to be changed:
  const GoogleString css1 =
      "BODY { background-image: url('bg.png'); }\n";
  const GoogleString css2 =
      "BODY { background-image: url('foo/bar/bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/foo/bar/baz.css",
                "", css1, true, css2);
}

TEST_P(CssInlineFilterTest, InlineCssRewriteUrls2) {
  // CSS with a relative URL, this time with ".." in it:
  const GoogleString css1 =
      "BODY { background-image: url('../quux/bg.png'); }\n";
  const GoogleString css2 =
      "BODY { background-image: url('foo/quux/bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/foo/bar/baz.css",
                "", css1, true, css2);
}

TEST_P(CssInlineFilterTest, NoRewriteUrlsSameDir) {
  const GoogleString css = "BODY { background-image: url('bg.png'); }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/baz.css",
                "", css, true, css);
}

TEST_P(CssInlineFilterTest, ShardSubresources) {
  UseMd5Hasher();
  DomainLawyer* lawyer = options()->domain_lawyer();
  lawyer->AddShard("www.example.com", "shard1.com,shard2.com",
                   &message_handler_);

  const GoogleString css_in =
      ".p1 { background-image: url('b1.png'); }"
      ".p2 { background-image: url('b2.png'); }";
  const GoogleString css_out =
      ".p1 { background-image: url('http://shard2.com/b1.png'); }"
      ".p2 { background-image: url('http://shard1.com/b2.png'); }";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/baz.css",
                "", css_in, true, css_out);
}

TEST_P(CssInlineFilterTest, DoNotInlineCssWithMediaAttr) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "media=\"print\"", css, false, "");
}

TEST_P(CssInlineFilterTest, DoInlineCssWithMediaAll) {
  const GoogleString css = "BODY { color: red; }\n";
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css",
                "media=\"all\"", css, true, css);
}

TEST_P(CssInlineFilterTest, DoNotInlineCssTooBig) {
  // CSS too large to inline:
  const int64 length = 2 * RewriteOptions::kDefaultCssInlineMaxBytes;
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/styles.css", "",
                ("BODY { background-image: url('" +
                 GoogleString(length, 'z') + ".png'); }\n"),
                false, "");
}

TEST_P(CssInlineFilterTest, DoNotInlineCssDifferentDomain) {
  // Note: This only fails because we haven't authorized www.example.org
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.org/styles.css",
                "", "BODY { color: red; }\n", false, "");
}

TEST_P(CssInlineFilterTest, CorrectlyInlineCssWithImports) {
  TestInlineCss("http://www.example.com/index.html",
                "http://www.example.com/dir/styles.css", "",
                "@import \"foo.css\"; BODY { color: red; }\n", true,
                "@import \"dir/foo.css\"; BODY { color: red; }\n");
}

// http://code.google.com/p/modpagespeed/issues/detail?q=css&id=252
TEST_P(CssInlineFilterTest, ClaimsXhtmlButHasUnclosedLink) {
  // XHTML text should not have unclosed links.  But if they do, like
  // in Issue 252, then we should leave them alone.
  static const char html_format[] =
      "\n"
      "  %s\n"
      "  %s\n"
      "  "     // 'in' <link>
      "\n"
      "

\n"
      "  Yellow on Blue

";

  static const char unclosed_css[] =
      "  <link rel='stylesheet' href='a.css' type='text/css'>\n";  // unclosed
  static const char inlined_css[] = "  \n";

  // Put original CSS files into our fetcher.
  ResponseHeaders default_css_header;
  SetDefaultLongCacheHeaders(&kContentTypeCss, &default_css_header);
  SetFetchResponse(StrCat(kTestDomain, "a.css"), default_css_header, ".a {}");
  AddFilter(RewriteOptions::kInlineCss);
  ValidateExpected("claims_xhtml_but_has_unclosed_links",
                   StringPrintf(html_format, kXhtmlDtd, unclosed_css),
                   StringPrintf(html_format, kXhtmlDtd, inlined_css));
}

TEST_P(CssInlineFilterTest, InlineCombined) {
  // Make sure we interact with CSS combiner properly, including in cached
  // case.
  options()->EnableFilter(RewriteOptions::kInlineCss);
  options()->EnableFilter(RewriteOptions::kCombineCss);
  rewrite_driver()->AddFilters();

  const char kCssUrl[] = "a.css";
  const char kCss[] = "div {display:block;}";

  InitResponseHeaders(kCssUrl, kContentTypeCss, kCss, 3000);

  GoogleString html_input =
      StrCat("<link rel=stylesheet href=\"", kCssUrl, "\">",
             "<link rel=stylesheet href=\"", kCssUrl, "\">");
  GoogleString html_output= StrCat("");

  ValidateExpected("inline_combined", html_input, html_output);
  ValidateExpected("inline_combined", html_input, html_output);
}

TEST_P(CssInlineFilterTest, InlineMinimizeInteraction) {
  // There was a bug in async mode where we would accidentally prevent
  // minification results from rendering when inlining was not to be done.
  options()->EnableFilter(RewriteOptions::kRewriteCss);
  options()->set_css_inline_max_bytes(4);

  TestInlineCssWithOutputUrl(
      StrCat(kTestDomain, "minimize_but_not_inline.html"),
      StrCat(kTestDomain, "a.css"),
      Encode(kTestDomain, "cf", "0", "a.css", "css"),
      "", /* no other attributes*/
      "div{display: none;}",
      false,
      "div{display: none}");
}

INSTANTIATE_TEST_CASE_P(CssInlineFilterTestInstance,
                        CssInlineFilterTest,
                        ::testing::Bool());

}  // namespace

}  // namespace net_instaweb
<|endoftext|>


<commit_before>/*******************************************************************************
*    ALMA - Atacama Large Millimiter Array
*    (c) European Southern Observatory, 2002
*    Copyright by ESO (in the framework of the ALMA collaboration)
*    and Cosylab 2002, All rights reserved
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@$Id: acscontainerdaemon.cpp,v 1.6 2007/11/13 19:49:30 agrimstrup Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* msekoran 2006-06-21 created
* agrimstr 2007-11-07 refactored to use daemon implementation template class
*/

static char *rcsId="@ $Id: acscontainerdaemon.cpp,v 1.6 2007/11/13 19:49:30 agrimstrup Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

#include <acsDaemonImpl.h>
#include <acsContainerHandlerImpl.h>

acsDaemonImpl<ACSContainerHandlerImpl>* g_daemon = 0;  // Reference used by signal handler

void TerminationSignalHandler(int)
{
    if (g_daemon)
	g_daemon->shutdown();
}

int
main (int argc, char *argv[])
{
    acsDaemonImpl<ACSContainerHandlerImpl> daemon(argc,argv);

    // Daemon is to be shutdown on receipt of SIGINT or SIGTERM
    g_daemon = &daemon;
    ACE_OS::signal(SIGINT, TerminationSignalHandler);  // Ctrl+C
    ACE_OS::signal(SIGTERM, TerminationSignalHandler); // termination request

    return daemon.run();
}
<commit_msg>termination logger<commit_after>/*******************************************************************************
*    ALMA - Atacama Large Millimiter Array
*    (c) European Southern Observatory, 2002
*    Copyright by ESO (in the framework of the ALMA collaboration)
*    and Cosylab 2002, All rights reserved
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@$Id: acscontainerdaemon.cpp,v 1.7 2008/11/19 11:02:44 msekoran Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* msekoran 2006-06-21 created
* agrimstr 2007-11-07 refactored to use daemon implementation template class
*/

static char *rcsId="@ $Id: acscontainerdaemon.cpp,v 1.7 2008/11/19 11:02:44 msekoran Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

#include <acsDaemonImpl.h>
#include <acsContainerHandlerImpl.h>

acsDaemonImpl<ACSContainerHandlerImpl>* g_daemon = 0;  // Reference used by signal handler

void TerminationSignalHandler(int)
{
    LoggingProxy * logger = new LoggingProxy(0, 0, 31);
    LoggingProxy::init(logger);
    LoggingProxy::ThreadName("termination");
    if (g_daemon)
	g_daemon->shutdown();
}

int
main (int argc, char *argv[])
{
    acsDaemonImpl<ACSContainerHandlerImpl> daemon(argc,argv);

    // Daemon is to be shutdown on receipt of SIGINT or SIGTERM
    g_daemon = &daemon;
    ACE_OS::signal(SIGINT, TerminationSignalHandler);  // Ctrl+C
    ACE_OS::signal(SIGTERM, TerminationSignalHandler); // termination request

    return daemon.run();
}
<|endoftext|>


<commit_before>#include <babylon/engines/extensions/multi_render_extension.h>

#include <babylon/core/logging.h>
#include <babylon/engines/thin_engine.h>
#include <babylon/materials/textures/imulti_render_target_options.h>
#include <babylon/materials/textures/internal_texture.h>
#include <babylon/maths/isize.h>

namespace BABYLON {

MultiRenderExtension::MultiRenderExtension(ThinEngine* engine) : _this{engine}
{
}

MultiRenderExtension::~MultiRenderExtension() = default;

void MultiRenderExtension::unBindMultiColorAttachmentFramebuffer(
  const std::vector<InternalTexturePtr>& textures, bool disableGenerateMipMaps,
  const std::function<void()>& onBeforeUnbind)
{
  _this->_currentRenderTarget = nullptr;

  // If MSAA, we need to bitblt back to main texture
  auto& gl = *_this->_gl;

  if (textures[0]->_MSAAFramebuffer) {
    gl.bindFramebuffer(GL::READ_FRAMEBUFFER, textures[0]->_MSAAFramebuffer.get());
    gl.bindFramebuffer(GL::DRAW_FRAMEBUFFER, textures[0]->_framebuffer.get());

    auto& attachments = textures[0]->_attachments;
    if (attachments.empty()) {
      attachments               = Uint32Array(textures.size());
      textures[0]->_attachments = attachments;
    }

    for (size_t i = 0; i < textures.size(); ++i) {
      const auto iStr = std::to_string(i);
      auto& texture   = textures[i];

      for (size_t j = 0; j < attachments.size(); ++j) {
        attachments[j] = GL::NONE;
      }

      attachments[i] = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                        "COLOR_ATTACHMENT" + iStr + "_WEBGL"];
      gl.readBuffer(attachments[i]);
      gl.drawBuffers(attachments);
      gl.blitFramebuffer(0, 0, texture->width, texture->height, 0, 0, texture->width,
                         texture->height, GL::COLOR_BUFFER_BIT, GL::NEAREST);
    }
    for (size_t i = 0; i < attachments.size(); i++) {
      const auto iStr = std::to_string(i);
      attachments[i]  = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                        "COLOR_ATTACHMENT" + iStr + "_WEBGL"];
    }
    gl.drawBuffers(attachments);
  }

  for (const auto& texture : textures) {
    if (texture->generateMipMaps && !disableGenerateMipMaps && !texture->isCube) {
      _this->_bindTextureDirectly(GL::TEXTURE_2D, texture);
      gl.generateMipmap(GL::TEXTURE_2D);
      _this->_bindTextureDirectly(GL::TEXTURE_2D, nullptr);
    }
  }

  if (onBeforeUnbind) {
    if (textures[0]->_MSAAFramebuffer) {
      // Bind the correct framebuffer
      _this->_bindUnboundFramebuffer(textures[0]->_framebuffer);
    }
    onBeforeUnbind();
  }

  _this->_bindUnboundFramebuffer(nullptr);
}

std::vector<InternalTexturePtr>
MultiRenderExtension::createMultipleRenderTarget(ISize size,
                                                 const IMultiRenderTargetOptions& options)
{
  auto generateMipMaps       = options.generateMipMaps.value_or(false);
  auto generateDepthBuffer   = options.generateDepthBuffer.value_or(true);
  auto generateStencilBuffer = options.generateStencilBuffer.value_or(false);
  auto generateDepthTexture  = options.generateDepthTexture.value_or(false);
  auto textureCount          = options.textureCount.value_or(1);

  auto defaultType         = Constants::TEXTURETYPE_UNSIGNED_INT;
  auto defaultSamplingMode = Constants::TEXTURE_TRILINEAR_SAMPLINGMODE;

  const auto& types         = options.types;
  const auto& samplingModes = options.samplingModes;

  auto width  = size.width;
  auto height = size.height;

  auto& gl = *_this->_gl;
  // Create the framebuffer
  auto framebuffer = gl.createFramebuffer();
  _this->_bindUnboundFramebuffer(framebuffer);

  std::vector<InternalTexturePtr> textures;
  std::vector<GL::GLenum> attachments;

  auto depthStencilBuffer = _this->_setupFramebufferDepthAttachments(
    generateStencilBuffer, generateDepthBuffer, width, height);

  for (unsigned int i = 0; i < textureCount; ++i) {
    const auto iStr   = std::to_string(i);
    auto samplingMode = (i < samplingModes.size()) ? samplingModes[i] : defaultSamplingMode;
    auto type         = (i < types.size()) ? types[i] : defaultType;

    if (type == Constants::TEXTURETYPE_FLOAT && !_this->_caps.textureFloatLinearFiltering) {
      // if floating point linear (GL::FLOAT) then force to NEAREST_SAMPLINGMODE
      samplingMode = Constants::TEXTURE_NEAREST_SAMPLINGMODE;
    }
    else if (type == Constants::TEXTURETYPE_HALF_FLOAT
             && !_this->_caps.textureHalfFloatLinearFiltering) {
      // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
      samplingMode = Constants::TEXTURE_NEAREST_SAMPLINGMODE;
    }

    auto filters = _this->_getSamplingParameters(samplingMode, generateMipMaps);
    if (type == Constants::TEXTURETYPE_FLOAT && !_this->_caps.textureFloat) {
      type = Constants::TEXTURETYPE_UNSIGNED_INT;
      BABYLON_LOG_WARN(
        "Engine",
        "Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type")
    }

    auto texture    = InternalTexture::New(this, InternalTextureSource::MultiRenderTarget);
    auto attachment = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                       "COLOR_ATTACHMENT" + iStr + "_WEBGL"];

    textures.emplace_back(texture);
    attachments.emplace_back(attachment);

    gl.activeTexture(gl["TEXTURE" + iStr]);
    gl.bindTexture(GL::TEXTURE_2D, texture->_webGLTexture.get());

    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, filters.mag);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, filters.min);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP_TO_EDGE);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP_TO_EDGE);

    gl.texImage2D(GL::TEXTURE_2D, 0,
                  static_cast<int>(_this->_getRGBABufferInternalSizedFormat(type)), width, height,
                  0, GL::RGBA, _this->_getWebGLTextureType(type), nullptr);

    gl.framebufferTexture2D(GL::DRAW_FRAMEBUFFER, attachment, GL::TEXTURE_2D,
                            texture->_webGLTexture.get(), 0);

    if (generateMipMaps) {
      gl.generateMipmap(GL::TEXTURE_2D);
    }

    // Unbind
    _this->_bindTextureDirectly(GL::TEXTURE_2D, nullptr);

    texture->_framebuffer           = std::move(framebuffer);
    texture->_depthStencilBuffer    = std::move(depthStencilBuffer);
    texture->baseWidth              = width;
    texture->baseHeight             = height;
    texture->width                  = width;
    texture->height                 = height;
    texture->isReady                = true;
    texture->samples                = 1;
    texture->generateMipMaps        = generateMipMaps;
    texture->samplingMode           = samplingMode;
    texture->type                   = type;
    texture->_generateDepthBuffer   = generateDepthBuffer;
    texture->_generateStencilBuffer = generateStencilBuffer;
    texture->_attachments           = attachments;

    _this->_internalTexturesCache.emplace_back(texture);
  }

  if (generateDepthTexture && _this->_caps.depthTextureExtension) {
    // Depth texture
    auto depthTexture = InternalTexture::New(_this, InternalTextureSource::MultiRenderTarget);

    gl.activeTexture(GL::TEXTURE0);
    gl.bindTexture(GL::TEXTURE_2D, depthTexture->_webGLTexture.get());
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::NEAREST);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::NEAREST);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP_TO_EDGE);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP_TO_EDGE);
    gl.texImage2D(GL::TEXTURE_2D,                                                            //
                  0,                                                                         //
                  _this->webGLVersion() < 2.f ? GL::DEPTH_COMPONENT : GL::DEPTH_COMPONENT16, //
                  width,                                                                     //
                  height,                                                                    //
                  0,                                                                         //
                  GL::DEPTH_COMPONENT,                                                       //
                  GL::UNSIGNED_SHORT,                                                        //
                  nullptr                                                                    //
    );

    gl.framebufferTexture2D(GL::FRAMEBUFFER,                   //
                            GL::DEPTH_ATTACHMENT,              //
                            GL::TEXTURE_2D,                    //
                            depthTexture->_webGLTexture.get(), //
                            0                                  //
    );

    depthTexture->_framebuffer           = std::move(framebuffer);
    depthTexture->baseWidth              = width;
    depthTexture->baseHeight             = height;
    depthTexture->width                  = width;
    depthTexture->height                 = height;
    depthTexture->isReady                = true;
    depthTexture->samples                = 1;
    depthTexture->generateMipMaps        = generateMipMaps;
    depthTexture->samplingMode           = GL::NEAREST;
    depthTexture->_generateDepthBuffer   = generateDepthBuffer;
    depthTexture->_generateStencilBuffer = generateStencilBuffer;

    textures.emplace_back(depthTexture);
    _this->_internalTexturesCache.emplace_back(depthTexture);
  }

  gl.drawBuffers(attachments);
  gl.bindRenderbuffer(GL::RENDERBUFFER, nullptr);
  _this->_bindUnboundFramebuffer(nullptr);

  _this->resetTextureCache();

  return textures;
}

unsigned int MultiRenderExtension::updateMultipleRenderTargetTextureSampleCount(
  const std::vector<InternalTexturePtr>& textures, unsigned int samples)
{
  if (_this->webGLVersion() < 2.f || textures.empty()) {
    return 1;
  }

  if (textures[0]->samples == samples) {
    return samples;
  }

  auto& gl = *_this->_gl;

  samples = std::min(samples, _this->getCaps().maxMSAASamples);

  // Dispose previous render buffers
  if (textures[0]->_depthStencilBuffer) {
    gl.deleteRenderbuffer(textures[0]->_depthStencilBuffer.get());
    textures[0]->_depthStencilBuffer = nullptr;
  }

  if (textures[0]->_MSAAFramebuffer) {
    gl.deleteFramebuffer(textures[0]->_MSAAFramebuffer.get());
    textures[0]->_MSAAFramebuffer = nullptr;
  }

  for (const auto& texture : textures) {
    if (texture->_MSAARenderBuffer) {
      gl.deleteRenderbuffer(texture->_MSAARenderBuffer.get());
      texture->_MSAARenderBuffer = nullptr;
    }
  }

  if (samples > 1) {
    auto framebuffer = gl.createFramebuffer();

    if (!framebuffer) {
      throw std::runtime_error("Unable to create multi sampled framebuffer");
    }

    _this->_bindUnboundFramebuffer(framebuffer);

    auto depthStencilBuffer = _this->_setupFramebufferDepthAttachments(
      textures[0]->_generateStencilBuffer, textures[0]->_generateDepthBuffer, textures[0]->width,
      textures[0]->height, static_cast<int>(samples));

    Uint32Array attachments;

    for (size_t i = 0; i < textures.size(); ++i) {
      auto iStr       = std::to_string(i);
      auto& texture   = textures[i];
      auto attachment = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                         "COLOR_ATTACHMENT" + iStr + "_WEBGL"];

      auto colorRenderbuffer = gl.createRenderbuffer();

      if (!colorRenderbuffer) {
        throw std::runtime_error("Unable to create multi sampled framebuffer");
      }

      gl.bindRenderbuffer(GL::RENDERBUFFER, colorRenderbuffer);
      gl.renderbufferStorageMultisample(GL::RENDERBUFFER, static_cast<int>(samples),
                                        _this->_getRGBAMultiSampleBufferFormat(texture->type),
                                        texture->width, texture->height);

      gl.framebufferRenderbuffer(GL::FRAMEBUFFER, attachment, GL::RENDERBUFFER,
                                 colorRenderbuffer.get());

      texture->_MSAAFramebuffer    = framebuffer;
      texture->_MSAARenderBuffer   = std::move(colorRenderbuffer);
      texture->samples             = samples;
      texture->_depthStencilBuffer = std::move(depthStencilBuffer);
      gl.bindRenderbuffer(GL::RENDERBUFFER, nullptr);
      attachments.emplace_back(attachment);
    }
    gl.drawBuffers(attachments);
  }
  else {
    _this->_bindUnboundFramebuffer(textures[0]->_framebuffer);
  }

  _this->_bindUnboundFramebuffer(nullptr);

  return samples;
}

} // end of namespace BABYLON
<commit_msg>Changed log source<commit_after>#include <babylon/engines/extensions/multi_render_extension.h>

#include <babylon/core/logging.h>
#include <babylon/engines/thin_engine.h>
#include <babylon/materials/textures/imulti_render_target_options.h>
#include <babylon/materials/textures/internal_texture.h>
#include <babylon/maths/isize.h>

namespace BABYLON {

MultiRenderExtension::MultiRenderExtension(ThinEngine* engine) : _this{engine}
{
}

MultiRenderExtension::~MultiRenderExtension() = default;

void MultiRenderExtension::unBindMultiColorAttachmentFramebuffer(
  const std::vector<InternalTexturePtr>& textures, bool disableGenerateMipMaps,
  const std::function<void()>& onBeforeUnbind)
{
  _this->_currentRenderTarget = nullptr;

  // If MSAA, we need to bitblt back to main texture
  auto& gl = *_this->_gl;

  if (textures[0]->_MSAAFramebuffer) {
    gl.bindFramebuffer(GL::READ_FRAMEBUFFER, textures[0]->_MSAAFramebuffer.get());
    gl.bindFramebuffer(GL::DRAW_FRAMEBUFFER, textures[0]->_framebuffer.get());

    auto& attachments = textures[0]->_attachments;
    if (attachments.empty()) {
      attachments               = Uint32Array(textures.size());
      textures[0]->_attachments = attachments;
    }

    for (size_t i = 0; i < textures.size(); ++i) {
      const auto iStr = std::to_string(i);
      auto& texture   = textures[i];

      for (size_t j = 0; j < attachments.size(); ++j) {
        attachments[j] = GL::NONE;
      }

      attachments[i] = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                        "COLOR_ATTACHMENT" + iStr + "_WEBGL"];
      gl.readBuffer(attachments[i]);
      gl.drawBuffers(attachments);
      gl.blitFramebuffer(0, 0, texture->width, texture->height, 0, 0, texture->width,
                         texture->height, GL::COLOR_BUFFER_BIT, GL::NEAREST);
    }
    for (size_t i = 0; i < attachments.size(); i++) {
      const auto iStr = std::to_string(i);
      attachments[i]  = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                        "COLOR_ATTACHMENT" + iStr + "_WEBGL"];
    }
    gl.drawBuffers(attachments);
  }

  for (const auto& texture : textures) {
    if (texture->generateMipMaps && !disableGenerateMipMaps && !texture->isCube) {
      _this->_bindTextureDirectly(GL::TEXTURE_2D, texture);
      gl.generateMipmap(GL::TEXTURE_2D);
      _this->_bindTextureDirectly(GL::TEXTURE_2D, nullptr);
    }
  }

  if (onBeforeUnbind) {
    if (textures[0]->_MSAAFramebuffer) {
      // Bind the correct framebuffer
      _this->_bindUnboundFramebuffer(textures[0]->_framebuffer);
    }
    onBeforeUnbind();
  }

  _this->_bindUnboundFramebuffer(nullptr);
}

std::vector<InternalTexturePtr>
MultiRenderExtension::createMultipleRenderTarget(ISize size,
                                                 const IMultiRenderTargetOptions& options)
{
  auto generateMipMaps       = options.generateMipMaps.value_or(false);
  auto generateDepthBuffer   = options.generateDepthBuffer.value_or(true);
  auto generateStencilBuffer = options.generateStencilBuffer.value_or(false);
  auto generateDepthTexture  = options.generateDepthTexture.value_or(false);
  auto textureCount          = options.textureCount.value_or(1);

  auto defaultType         = Constants::TEXTURETYPE_UNSIGNED_INT;
  auto defaultSamplingMode = Constants::TEXTURE_TRILINEAR_SAMPLINGMODE;

  const auto& types         = options.types;
  const auto& samplingModes = options.samplingModes;

  auto width  = size.width;
  auto height = size.height;

  auto& gl = *_this->_gl;
  // Create the framebuffer
  auto framebuffer = gl.createFramebuffer();
  _this->_bindUnboundFramebuffer(framebuffer);

  std::vector<InternalTexturePtr> textures;
  std::vector<GL::GLenum> attachments;

  auto depthStencilBuffer = _this->_setupFramebufferDepthAttachments(
    generateStencilBuffer, generateDepthBuffer, width, height);

  for (unsigned int i = 0; i < textureCount; ++i) {
    const auto iStr   = std::to_string(i);
    auto samplingMode = (i < samplingModes.size()) ? samplingModes[i] : defaultSamplingMode;
    auto type         = (i < types.size()) ? types[i] : defaultType;

    if (type == Constants::TEXTURETYPE_FLOAT && !_this->_caps.textureFloatLinearFiltering) {
      // if floating point linear (GL::FLOAT) then force to NEAREST_SAMPLINGMODE
      samplingMode = Constants::TEXTURE_NEAREST_SAMPLINGMODE;
    }
    else if (type == Constants::TEXTURETYPE_HALF_FLOAT
             && !_this->_caps.textureHalfFloatLinearFiltering) {
      // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
      samplingMode = Constants::TEXTURE_NEAREST_SAMPLINGMODE;
    }

    auto filters = _this->_getSamplingParameters(samplingMode, generateMipMaps);
    if (type == Constants::TEXTURETYPE_FLOAT && !_this->_caps.textureFloat) {
      type = Constants::TEXTURETYPE_UNSIGNED_INT;
      BABYLON_LOG_WARN(
        "MultiRenderExtension",
        "Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type")
    }

    auto texture    = InternalTexture::New(this, InternalTextureSource::MultiRenderTarget);
    auto attachment = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                       "COLOR_ATTACHMENT" + iStr + "_WEBGL"];

    textures.emplace_back(texture);
    attachments.emplace_back(attachment);

    gl.activeTexture(gl["TEXTURE" + iStr]);
    gl.bindTexture(GL::TEXTURE_2D, texture->_webGLTexture.get());

    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, filters.mag);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, filters.min);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP_TO_EDGE);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP_TO_EDGE);

    gl.texImage2D(GL::TEXTURE_2D, 0,
                  static_cast<int>(_this->_getRGBABufferInternalSizedFormat(type)), width, height,
                  0, GL::RGBA, _this->_getWebGLTextureType(type), nullptr);

    gl.framebufferTexture2D(GL::DRAW_FRAMEBUFFER, attachment, GL::TEXTURE_2D,
                            texture->_webGLTexture.get(), 0);

    if (generateMipMaps) {
      gl.generateMipmap(GL::TEXTURE_2D);
    }

    // Unbind
    _this->_bindTextureDirectly(GL::TEXTURE_2D, nullptr);

    texture->_framebuffer           = std::move(framebuffer);
    texture->_depthStencilBuffer    = std::move(depthStencilBuffer);
    texture->baseWidth              = width;
    texture->baseHeight             = height;
    texture->width                  = width;
    texture->height                 = height;
    texture->isReady                = true;
    texture->samples                = 1;
    texture->generateMipMaps        = generateMipMaps;
    texture->samplingMode           = samplingMode;
    texture->type                   = type;
    texture->_generateDepthBuffer   = generateDepthBuffer;
    texture->_generateStencilBuffer = generateStencilBuffer;
    texture->_attachments           = attachments;

    _this->_internalTexturesCache.emplace_back(texture);
  }

  if (generateDepthTexture && _this->_caps.depthTextureExtension) {
    // Depth texture
    auto depthTexture = InternalTexture::New(_this, InternalTextureSource::MultiRenderTarget);

    gl.activeTexture(GL::TEXTURE0);
    gl.bindTexture(GL::TEXTURE_2D, depthTexture->_webGLTexture.get());
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::NEAREST);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::NEAREST);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP_TO_EDGE);
    gl.texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP_TO_EDGE);
    gl.texImage2D(GL::TEXTURE_2D,                                                            //
                  0,                                                                         //
                  _this->webGLVersion() < 2.f ? GL::DEPTH_COMPONENT : GL::DEPTH_COMPONENT16, //
                  width,                                                                     //
                  height,                                                                    //
                  0,                                                                         //
                  GL::DEPTH_COMPONENT,                                                       //
                  GL::UNSIGNED_SHORT,                                                        //
                  nullptr                                                                    //
    );

    gl.framebufferTexture2D(GL::FRAMEBUFFER,                   //
                            GL::DEPTH_ATTACHMENT,              //
                            GL::TEXTURE_2D,                    //
                            depthTexture->_webGLTexture.get(), //
                            0                                  //
    );

    depthTexture->_framebuffer           = std::move(framebuffer);
    depthTexture->baseWidth              = width;
    depthTexture->baseHeight             = height;
    depthTexture->width                  = width;
    depthTexture->height                 = height;
    depthTexture->isReady                = true;
    depthTexture->samples                = 1;
    depthTexture->generateMipMaps        = generateMipMaps;
    depthTexture->samplingMode           = GL::NEAREST;
    depthTexture->_generateDepthBuffer   = generateDepthBuffer;
    depthTexture->_generateStencilBuffer = generateStencilBuffer;

    textures.emplace_back(depthTexture);
    _this->_internalTexturesCache.emplace_back(depthTexture);
  }

  gl.drawBuffers(attachments);
  gl.bindRenderbuffer(GL::RENDERBUFFER, nullptr);
  _this->_bindUnboundFramebuffer(nullptr);

  _this->resetTextureCache();

  return textures;
}

unsigned int MultiRenderExtension::updateMultipleRenderTargetTextureSampleCount(
  const std::vector<InternalTexturePtr>& textures, unsigned int samples)
{
  if (_this->webGLVersion() < 2.f || textures.empty()) {
    return 1;
  }

  if (textures[0]->samples == samples) {
    return samples;
  }

  auto& gl = *_this->_gl;

  samples = std::min(samples, _this->getCaps().maxMSAASamples);

  // Dispose previous render buffers
  if (textures[0]->_depthStencilBuffer) {
    gl.deleteRenderbuffer(textures[0]->_depthStencilBuffer.get());
    textures[0]->_depthStencilBuffer = nullptr;
  }

  if (textures[0]->_MSAAFramebuffer) {
    gl.deleteFramebuffer(textures[0]->_MSAAFramebuffer.get());
    textures[0]->_MSAAFramebuffer = nullptr;
  }

  for (const auto& texture : textures) {
    if (texture->_MSAARenderBuffer) {
      gl.deleteRenderbuffer(texture->_MSAARenderBuffer.get());
      texture->_MSAARenderBuffer = nullptr;
    }
  }

  if (samples > 1) {
    auto framebuffer = gl.createFramebuffer();

    if (!framebuffer) {
      throw std::runtime_error("Unable to create multi sampled framebuffer");
    }

    _this->_bindUnboundFramebuffer(framebuffer);

    auto depthStencilBuffer = _this->_setupFramebufferDepthAttachments(
      textures[0]->_generateStencilBuffer, textures[0]->_generateDepthBuffer, textures[0]->width,
      textures[0]->height, static_cast<int>(samples));

    Uint32Array attachments;

    for (size_t i = 0; i < textures.size(); ++i) {
      auto iStr       = std::to_string(i);
      auto& texture   = textures[i];
      auto attachment = gl[_this->webGLVersion() > 1.f ? "COLOR_ATTACHMENT" + iStr :
                                                         "COLOR_ATTACHMENT" + iStr + "_WEBGL"];

      auto colorRenderbuffer = gl.createRenderbuffer();

      if (!colorRenderbuffer) {
        throw std::runtime_error("Unable to create multi sampled framebuffer");
      }

      gl.bindRenderbuffer(GL::RENDERBUFFER, colorRenderbuffer);
      gl.renderbufferStorageMultisample(GL::RENDERBUFFER, static_cast<int>(samples),
                                        _this->_getRGBAMultiSampleBufferFormat(texture->type),
                                        texture->width, texture->height);

      gl.framebufferRenderbuffer(GL::FRAMEBUFFER, attachment, GL::RENDERBUFFER,
                                 colorRenderbuffer.get());

      texture->_MSAAFramebuffer    = framebuffer;
      texture->_MSAARenderBuffer   = std::move(colorRenderbuffer);
      texture->samples             = samples;
      texture->_depthStencilBuffer = std::move(depthStencilBuffer);
      gl.bindRenderbuffer(GL::RENDERBUFFER, nullptr);
      attachments.emplace_back(attachment);
    }
    gl.drawBuffers(attachments);
  }
  else {
    _this->_bindUnboundFramebuffer(textures[0]->_framebuffer);
  }

  _this->_bindUnboundFramebuffer(nullptr);

  return samples;
}

} // end of namespace BABYLON
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "LangevinSampler.h"

#include <cassert>

namespace madai {

LangevinSampler
::LangevinSampler() :
  Sampler(),
  m_TimeStep( 1.0e-2 ),
  m_MassScale( 10 ),
  m_MeanTime( 0.1 ),
  m_KickStrength( 1 ),
  m_DragCoefficient( 1.0e-2 )
{
}

LangevinSampler
::~LangevinSampler()
{
}

void
LangevinSampler
::Initialize( const Model * model )
{
  assert( model != NULL );
  m_Model = model;

  Sampler::Initialize( model );

  // Random initial starting point
  const std::vector< Parameter > & params = m_Model->GetParameters();
  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    m_CurrentVelocities.push_back(0.0);
  }

  m_TimeBeforeNextKick = m_Random.Gaussian( m_MeanTime, m_MeanTime / 10.0 );
}

Sample
LangevinSampler
::NextSample()
{
  Model * m = const_cast< Model * >(m_Model);
  double TimeLeft = m_TimeStep;

  unsigned int numberOfActiveParameters = this->GetNumberOfActiveParameters();

  assert( std::count( m_ActiveParameterIndices.begin(),
                      m_ActiveParameterIndices.end(), true )
          == numberOfActiveParameters);

  // Get the gradient of the Log Likelihood at the current point
  std::vector< double > ModelMeans;
  std::vector< double > Gradient;
  m->GetScalarAndGradientOutputs(
    m_CurrentParameters, m_ActiveParameterIndices,
    ModelMeans, Gradient );

  // Multiply by likelihood to get gradient of the likelihood
  double LogLikelihood;
  m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, ModelMeans, LogLikelihood );
  for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
    Gradient[i] *= exp( LogLikelihood );
  }

  std::vector< double > Accel( Gradient.size() );
  for ( unsigned int i = 0; i < Accel.size(); i++ ) {
    Accel[i] = Gradient[i];
    Accel[i] -= m_DragCoefficient * m_CurrentVelocities[i];
    Accel[i] /= m_MassScale;
  }
  if ( m_TimeBeforeNextKick < m_TimeStep ) { // Check if kick happens
    // Take step up to m_TimeBeforeNextKick
    for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
      m_CurrentParameters[i] += m_CurrentVelocities * m_TimeBeforeNextKick;
      m_CurrentParameters[i] += 0.5 * Accel[i] * m_TimeBeforeNextKick * m_TimeBeforeNextKick;
      m_CurrentVelocities[i] += Accel[i] * m_TimeBeforeNextKick;
    }
    // Get m_CurrentVelocities.size() number of random numbers
    double r[m_CurrentVelocities.size()];
    double temp = 0;
    for ( unsigned int i = 0; i < m_CurrentVelocities.size(); i++ ) {
      r[i] = m_Random.Uniform( -1, 1 );
      temp += r[i] * r[i];
    }
    temp = sqrt( temp );
    temp /= m_KickStrength;
    for ( unsigned int i = 0; i < m_CurrentVelocities.size(); i++ ) {
     m_CurrentVelocities[i] += r[i] / temp;
     Accel[i] -= m_DragCoefficient * r[i] / temp;
    }
    TimeLeft -= m_TimeBeforeNextKick;
    m_TimeBeforeNextKick += m_Random.Gaussian( m_MeanTime, m_MeanTime / 10.0 );
  }

  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] += m_CurrentVelocities[i] * TimeLeft;
    m_CurrentParameters[i] += 0.5 * Accel[i] * TimeLeft * TimeLeft;
    m_CurrentVelocities[i] += Accel[i] * TimeLeft;
  }

  m_TimeBeforeNextKick -= m_TimeStep;

  return Sample( m_CurrentParameters,
                 ModelMeans,
                 LogLikelihood );

}

void LangevinSampler
::SetTimeStep( double TimeStep )
{
  m_TimeStep = TimeStep;
}

void LangevinSampler
::SetKickStrength( double KickStrength )
{
  m_KickStrength = KickStrength;
}

void LangevinSampler
::SetMeanTimeBetweenKicks( double MeanTime )
{
  m_MeanTime = MeanTime;
}

void LangevinSampler
::SetDragCoefficient( double DragCoefficient )
{
  m_DragCoefficient = DragCoefficient;
}

void LangevinSampler
::SetMassScale( double MassScale )
{
  m_MassScale = MassScale;
}

}<commit_msg>Fixed a missing array bracket. Changed some default values to 1 (everything but the time step size and the damping factor).<commit_after>/*=========================================================================
 *
 *  Copyright The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "LangevinSampler.h"

#include <cassert>

namespace madai {

LangevinSampler
::LangevinSampler() :
  Sampler(),
  m_TimeStep( 1.0e-2 ),
  m_MassScale( 1 ),
  m_MeanTime( 1 ),
  m_KickStrength( 1 ),
  m_DragCoefficient( 1.0e-2 )
{
}

LangevinSampler
::~LangevinSampler()
{
}

void
LangevinSampler
::Initialize( const Model * model )
{
  assert( model != NULL );
  m_Model = model;

  Sampler::Initialize( model );

  // Random initial starting point
  const std::vector< Parameter > & params = m_Model->GetParameters();
  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ ) {
    const Distribution * priorDist = params[i].GetPriorDistribution();
    m_CurrentParameters[i] = priorDist->GetSample(m_Random);
    m_CurrentVelocities.push_back(0.0);
  }

  m_TimeBeforeNextKick = m_Random.Gaussian( m_MeanTime, m_MeanTime / 10.0 );
}

Sample
LangevinSampler
::NextSample()
{
  Model * m = const_cast< Model * >(m_Model);
  double TimeLeft = m_TimeStep;

  unsigned int numberOfActiveParameters = this->GetNumberOfActiveParameters();

  assert( std::count( m_ActiveParameterIndices.begin(),
                      m_ActiveParameterIndices.end(), true )
          == numberOfActiveParameters);

  // Get the gradient of the Log Likelihood at the current point
  std::vector< double > ModelMeans;
  std::vector< double > Gradient;
  m->GetScalarAndGradientOutputs(
    m_CurrentParameters, m_ActiveParameterIndices,
    ModelMeans, Gradient );

  // Multiply by likelihood to get gradient of the likelihood
  double LogLikelihood;
  m->GetScalarOutputsAndLogLikelihood(
    m_CurrentParameters, ModelMeans, LogLikelihood );
  for ( unsigned int i = 0; i < Gradient.size(); i++ ) {
    Gradient[i] *= exp( LogLikelihood );
  }

  std::vector< double > Accel( Gradient.size() );
  for ( unsigned int i = 0; i < Accel.size(); i++ ) {
    Accel[i] = Gradient[i];
    Accel[i] -= m_DragCoefficient * m_CurrentVelocities[i];
    Accel[i] /= m_MassScale;
  }
  if ( m_TimeBeforeNextKick < m_TimeStep ) { // Check if kick happens
    // Take step up to m_TimeBeforeNextKick
    for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
      m_CurrentParameters[i] += m_CurrentVelocities[i] * m_TimeBeforeNextKick;
      m_CurrentParameters[i] += 0.5 * Accel[i] * m_TimeBeforeNextKick * m_TimeBeforeNextKick;
      m_CurrentVelocities[i] += Accel[i] * m_TimeBeforeNextKick;
    }
    // Get m_CurrentVelocities.size() number of random numbers
    double r[m_CurrentVelocities.size()];
    double temp = 0;
    for ( unsigned int i = 0; i < m_CurrentVelocities.size(); i++ ) {
      r[i] = m_Random.Uniform( -1, 1 );
      temp += r[i] * r[i];
    }
    temp = sqrt( temp );
    temp /= m_KickStrength;
    for ( unsigned int i = 0; i < m_CurrentVelocities.size(); i++ ) {
     m_CurrentVelocities[i] += r[i] / temp;
     Accel[i] -= m_DragCoefficient * r[i] / temp;
    }
    TimeLeft -= m_TimeBeforeNextKick;
    m_TimeBeforeNextKick += m_Random.Gaussian( m_MeanTime, m_MeanTime / 10.0 );
  }

  for ( unsigned int i = 0; i < m_CurrentParameters.size(); i++ ) {
    m_CurrentParameters[i] += m_CurrentVelocities[i] * TimeLeft;
    m_CurrentParameters[i] += 0.5 * Accel[i] * TimeLeft * TimeLeft;
    m_CurrentVelocities[i] += Accel[i] * TimeLeft;
  }

  m_TimeBeforeNextKick -= m_TimeStep;

  return Sample( m_CurrentParameters,
                 ModelMeans,
                 LogLikelihood );

}

void LangevinSampler
::SetTimeStep( double TimeStep )
{
  m_TimeStep = TimeStep;
}

void LangevinSampler
::SetKickStrength( double KickStrength )
{
  m_KickStrength = KickStrength;
}

void LangevinSampler
::SetMeanTimeBetweenKicks( double MeanTime )
{
  m_MeanTime = MeanTime;
}

void LangevinSampler
::SetDragCoefficient( double DragCoefficient )
{
  m_DragCoefficient = DragCoefficient;
}

void LangevinSampler
::SetMassScale( double MassScale )
{
  m_MassScale = MassScale;
}

}<|endoftext|>


<commit_before>#include "QtVmbViewer.h"
#include <QPixmap>
#include <QVBoxLayout>

// Constructor
QtVmbViewer::QtVmbViewer( QWidget *parent ) : QWidget( parent ), label( new QLabel ) {
    // Scale the image label
    label->setScaledContents( true );
    // Widget layout
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->addWidget( label );
    layout->setSizeConstraint( QLayout::SetFixedSize );
    // Create the camera
    camera = new VmbCamera( "50-0503323406" );
    // Connect the camera signal to get the received frame
    connect( camera, &VmbCamera::ImageReady, this, &QtVmbViewer::UpdateImage );
    // Open the camera
    camera->Open();
    // Start acquisition
    camera->StartCapture();
}

// Destructor
QtVmbViewer::~QtVmbViewer() {
    // Stop acquisition
    camera->StopCapture();
    // Close the camera
    camera->Close();
    // Delete the camera
    delete camera;
}

// Image callback
void QtVmbViewer::UpdateImage() {
    // Set the image to the label
    label->setPixmap( QPixmap::fromImage( *camera->image ) );
    // Update the widget
    label->update();
}

<commit_msg>Resize the displayed image.<commit_after>#include "QtVmbViewer.h"
#include <QPixmap>
#include <QVBoxLayout>

// Constructor
QtVmbViewer::QtVmbViewer( QWidget *parent ) : QWidget( parent ), label( new QLabel ) {
    // Scale the image label
    label->setScaledContents( true );
    // Widget layout
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->addWidget( label );
    layout->setSizeConstraint( QLayout::SetFixedSize );
    // Create the camera
    camera = new VmbCamera( "50-0503323406" );
    // Connect the camera signal to get the received frame
    connect( camera, &VmbCamera::ImageReady, this, &QtVmbViewer::UpdateImage );
    // Open the camera
    camera->Open();
    // Start acquisition
    camera->StartCapture();
}

// Destructor
QtVmbViewer::~QtVmbViewer() {
    // Stop acquisition
    camera->StopCapture();
    // Close the camera
    camera->Close();
    // Delete the camera
    delete camera;
}

// Image callback
void QtVmbViewer::UpdateImage() {
    // Set the image to the label
    label->setPixmap( QPixmap::fromImage( *camera->image ).scaled( camera->width*0.3, camera->height*0.3, Qt::KeepAspectRatio ) );
    // Update the widget
    label->update();
}

<|endoftext|>