<commit_before>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <machine/Device.h>
#include <processor/IoPort.h>
#include <processor/MemoryMappedIo.h>
#include <processor/PhysicalMemoryManager.h>
#include <Log.h>

/** Singleton Device instantiation. */
Device Device::m_Root;

Device::Device() : m_Addresses(), m_Children(), m_pParent(0),
#ifdef OPENFIRMWARE
                   m_OfHandle(0),
#endif
                   m_InterruptNumber(0),
                   m_SpecificType(),
                   m_ClassCode(0), m_SubclassCode(0), m_VendorId(0), m_DeviceId(0), m_ProgInterface(0),
                   m_PciBusPos(0), m_PciDevicePos(0), m_PciFunctionNum(0)
{
}

Device::Device (Device *p) : m_Addresses(), m_Children(), m_pParent(0), m_InterruptNumber(p->m_InterruptNumber),
#ifdef OPENFIRMWARE
                             m_OfHandle(0),
#endif
                             m_SpecificType(p->m_SpecificType),
                             m_ClassCode(p->m_ClassCode), m_SubclassCode(p->m_SubclassCode),
                             m_VendorId(p->m_VendorId), m_DeviceId(p->m_DeviceId), m_ProgInterface(p->m_ProgInterface),
                             m_PciBusPos(p->m_PciBusPos), m_PciDevicePos(p->m_PciDevicePos), m_PciFunctionNum(p->m_PciFunctionNum)
{
  m_pParent = p->m_pParent;
  for (unsigned int i = 0; i < p->m_Children.count(); i++)
  {
    m_Children.pushBack(p->m_Children[i]);
  }

  p->removeIoMappings();

  for (unsigned int i = 0; i < p->m_Addresses.count(); i++)
  {
    Address *pa = p->m_Addresses[i];
    Address *a = new Address(pa->m_Name, pa->m_Address, pa->m_Size, pa->m_IsIoSpace, pa->m_Padding);
    NOTICE("address=" << reinterpret_cast<uintptr_t>(a) << ", m_Io=" << reinterpret_cast<uintptr_t>(a->m_Io));
    m_Addresses.pushBack(a);
  }
}

Device::~Device()
{
  for (unsigned int i = 0; i < m_Addresses.count(); i++)
  {
    delete m_Addresses[i];
  }
  for (unsigned int i = 0; i < m_Children.count(); i++)
  {
    delete m_Children[i];
  }
}

void Device::removeIoMappings()
{
  for (unsigned int i = 0; i < m_Addresses.count(); i++)
  {
    Address *pa = m_Addresses[i];
    if (pa->m_Io)
      delete pa->m_Io;
    pa->m_Io = 0;
  }
}

void Device::getName(String &str)
{
  str = "Root";
}

/** Adds a device as a child of this device. */
void Device::addChild(Device *pDevice)
{
  m_Children.pushBack(pDevice);
}
/** Retrieves the n'th child of this device. */
Device *Device::getChild(size_t n)
{
  return m_Children[n];
}
/** Retrieves the number of children of this device. */
size_t Device::getNumChildren()
{
  return m_Children.count();
}
/** Removes the n'th child of this device. */
void Device::removeChild(size_t n)
{
  unsigned int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
  {
    if (i == n)
    {
      it = m_Children.erase(it);
      break;
    }
  }
}
/** Removes the given Device from this device's child list. */
void Device::removeChild(Device *d)
{
  int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
  if (*it == d)
  {
    m_Children.erase(it);
    break;
  }
}

void Device::replaceChild(Device *src, Device *dest)
{
  int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
    if (*it == src)
    {
      *it = dest;
      break;
    }
}

/** Search functions */

void Device::searchByVendorId(uint16_t vendorId, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if(pChild->getPciVendorId() == vendorId)
            callback(pChild);
        pChild->searchByVendorId(vendorId, callback);
    }
}

void Device::searchByVendorIdAndDeviceId(uint16_t vendorId, uint16_t deviceId, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciVendorId() == vendorId) && (pChild->getPciDeviceId() == deviceId))
            callback(pChild);
        pChild->searchByVendorIdAndDeviceId(vendorId, deviceId, callback);
    }
}

void Device::searchByClass(uint16_t classCode, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if(pChild->getPciClassCode() == classCode)
            callback(pChild);
        pChild->searchByClass(classCode, callback);
    }
}

void Device::searchByClassAndSubclass(uint16_t classCode, uint16_t subclassCode, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciClassCode() == classCode) && (pChild->getPciSubclassCode() == subclassCode))
            callback(pChild);
        pChild->searchByClassAndSubclass(classCode, subclassCode, callback);
    }
}

void Device::searchByClassSubclassAndProgInterface(uint16_t classCode, uint16_t subclassCode, uint8_t progInterface, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciClassCode() == classCode) && (pChild->getPciSubclassCode() == subclassCode) && (pChild->getPciProgInterface() == progInterface))
            callback(pChild);
        pChild->searchByClassSubclassAndProgInterface(classCode, subclassCode, progInterface, callback);
    }
}

Device::Address::Address(String n, uintptr_t a, size_t s, bool io, size_t pad) :
  m_Name(n), m_Address(a), m_Size(s), m_IsIoSpace(io), m_Io(0), m_Padding(pad)
{
#ifndef KERNEL_PROCESSOR_NO_PORT_IO
    if (m_IsIoSpace)
    {
        IoPort *pIo = new IoPort(m_Name);
        pIo->allocate(a, s);
        m_Io = pIo;
    }
    else
    {
#else
        // In this case, IO accesses go through MemoryMappedIo too.
        size_t pageSize = PhysicalMemoryManager::getPageSize();
        uint32_t numPages = s / pageSize;
        if (s%pageSize) numPages++;

        MemoryMappedIo *pIo = new MemoryMappedIo(m_Name, a%pageSize, pad);
        PhysicalMemoryManager &physicalMemoryManager = PhysicalMemoryManager::instance();
        if (!physicalMemoryManager.allocateRegion(*pIo,
                                                    numPages,
                                                    PhysicalMemoryManager::continuous | PhysicalMemoryManager::nonRamMemory |
                                                    PhysicalMemoryManager::force,
                                                    VirtualAddressSpace::KernelMode | VirtualAddressSpace::Write |
                                                    VirtualAddressSpace::WriteThrough | VirtualAddressSpace::CacheDisable,
                                                    a))
        {
            ERROR("Device::Address - allocateRegion failed!");
        }
        m_Io = pIo;
#ifndef KERNEL_PROCESSOR_NO_PORT_IO
    }
#endif
}

Device::Address::~Address()
{
  if (m_Io)
    delete m_Io;
}
<commit_msg>Fix a typo: #endif instead of #else, in Device.cc<commit_after>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <machine/Device.h>
#include <processor/IoPort.h>
#include <processor/MemoryMappedIo.h>
#include <processor/PhysicalMemoryManager.h>
#include <Log.h>

/** Singleton Device instantiation. */
Device Device::m_Root;

Device::Device() : m_Addresses(), m_Children(), m_pParent(0),
#ifdef OPENFIRMWARE
                   m_OfHandle(0),
#endif
                   m_InterruptNumber(0),
                   m_SpecificType(),
                   m_ClassCode(0), m_SubclassCode(0), m_VendorId(0), m_DeviceId(0), m_ProgInterface(0),
                   m_PciBusPos(0), m_PciDevicePos(0), m_PciFunctionNum(0)
{
}

Device::Device (Device *p) : m_Addresses(), m_Children(), m_pParent(0), m_InterruptNumber(p->m_InterruptNumber),
#ifdef OPENFIRMWARE
                             m_OfHandle(0),
#endif
                             m_SpecificType(p->m_SpecificType),
                             m_ClassCode(p->m_ClassCode), m_SubclassCode(p->m_SubclassCode),
                             m_VendorId(p->m_VendorId), m_DeviceId(p->m_DeviceId), m_ProgInterface(p->m_ProgInterface),
                             m_PciBusPos(p->m_PciBusPos), m_PciDevicePos(p->m_PciDevicePos), m_PciFunctionNum(p->m_PciFunctionNum)
{
  m_pParent = p->m_pParent;
  for (unsigned int i = 0; i < p->m_Children.count(); i++)
  {
    m_Children.pushBack(p->m_Children[i]);
  }

  p->removeIoMappings();

  for (unsigned int i = 0; i < p->m_Addresses.count(); i++)
  {
    Address *pa = p->m_Addresses[i];
    Address *a = new Address(pa->m_Name, pa->m_Address, pa->m_Size, pa->m_IsIoSpace, pa->m_Padding);
    NOTICE("address=" << reinterpret_cast<uintptr_t>(a) << ", m_Io=" << reinterpret_cast<uintptr_t>(a->m_Io));
    m_Addresses.pushBack(a);
  }
}

Device::~Device()
{
  for (unsigned int i = 0; i < m_Addresses.count(); i++)
  {
    delete m_Addresses[i];
  }
  for (unsigned int i = 0; i < m_Children.count(); i++)
  {
    delete m_Children[i];
  }
}

void Device::removeIoMappings()
{
  for (unsigned int i = 0; i < m_Addresses.count(); i++)
  {
    Address *pa = m_Addresses[i];
    if (pa->m_Io)
      delete pa->m_Io;
    pa->m_Io = 0;
  }
}

void Device::getName(String &str)
{
  str = "Root";
}

/** Adds a device as a child of this device. */
void Device::addChild(Device *pDevice)
{
  m_Children.pushBack(pDevice);
}
/** Retrieves the n'th child of this device. */
Device *Device::getChild(size_t n)
{
  return m_Children[n];
}
/** Retrieves the number of children of this device. */
size_t Device::getNumChildren()
{
  return m_Children.count();
}
/** Removes the n'th child of this device. */
void Device::removeChild(size_t n)
{
  unsigned int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
  {
    if (i == n)
    {
      it = m_Children.erase(it);
      break;
    }
  }
}
/** Removes the given Device from this device's child list. */
void Device::removeChild(Device *d)
{
  int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
  if (*it == d)
  {
    m_Children.erase(it);
    break;
  }
}

void Device::replaceChild(Device *src, Device *dest)
{
  int i = 0;
  for(Vector<Device*>::Iterator it = m_Children.begin();
      it != m_Children.end();
      it++, i++)
    if (*it == src)
    {
      *it = dest;
      break;
    }
}

/** Search functions */

void Device::searchByVendorId(uint16_t vendorId, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if(pChild->getPciVendorId() == vendorId)
            callback(pChild);
        pChild->searchByVendorId(vendorId, callback);
    }
}

void Device::searchByVendorIdAndDeviceId(uint16_t vendorId, uint16_t deviceId, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciVendorId() == vendorId) && (pChild->getPciDeviceId() == deviceId))
            callback(pChild);
        pChild->searchByVendorIdAndDeviceId(vendorId, deviceId, callback);
    }
}

void Device::searchByClass(uint16_t classCode, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if(pChild->getPciClassCode() == classCode)
            callback(pChild);
        pChild->searchByClass(classCode, callback);
    }
}

void Device::searchByClassAndSubclass(uint16_t classCode, uint16_t subclassCode, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciClassCode() == classCode) && (pChild->getPciSubclassCode() == subclassCode))
            callback(pChild);
        pChild->searchByClassAndSubclass(classCode, subclassCode, callback);
    }
}

void Device::searchByClassSubclassAndProgInterface(uint16_t classCode, uint16_t subclassCode, uint8_t progInterface, void (*callback)(Device*))
{
    for (unsigned int i = 0; i < m_Children.count(); i++)
    {
        Device *pChild = m_Children[i];
        if((pChild->getPciClassCode() == classCode) && (pChild->getPciSubclassCode() == subclassCode) && (pChild->getPciProgInterface() == progInterface))
            callback(pChild);
        pChild->searchByClassSubclassAndProgInterface(classCode, subclassCode, progInterface, callback);
    }
}

Device::Address::Address(String n, uintptr_t a, size_t s, bool io, size_t pad) :
  m_Name(n), m_Address(a), m_Size(s), m_IsIoSpace(io), m_Io(0), m_Padding(pad)
{
#ifndef KERNEL_PROCESSOR_NO_PORT_IO
    if (m_IsIoSpace)
    {
        IoPort *pIo = new IoPort(m_Name);
        pIo->allocate(a, s);
        m_Io = pIo;
    }
    else
    {
#endif
        // In this case, IO accesses go through MemoryMappedIo too.
        size_t pageSize = PhysicalMemoryManager::getPageSize();
        uint32_t numPages = s / pageSize;
        if (s%pageSize) numPages++;

        MemoryMappedIo *pIo = new MemoryMappedIo(m_Name, a%pageSize, pad);
        PhysicalMemoryManager &physicalMemoryManager = PhysicalMemoryManager::instance();
        if (!physicalMemoryManager.allocateRegion(*pIo,
                                                    numPages,
                                                    PhysicalMemoryManager::continuous | PhysicalMemoryManager::nonRamMemory |
                                                    PhysicalMemoryManager::force,
                                                    VirtualAddressSpace::KernelMode | VirtualAddressSpace::Write |
                                                    VirtualAddressSpace::WriteThrough | VirtualAddressSpace::CacheDisable,
                                                    a))
        {
            ERROR("Device::Address - allocateRegion failed!");
        }
        m_Io = pIo;
#ifndef KERNEL_PROCESSOR_NO_PORT_IO
    }
#endif
}

Device::Address::~Address()
{
  if (m_Io)
    delete m_Io;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <iomanip>
#include <ios>
#include <stan/mcmc/chains.hpp>

int calculate_size(const Eigen::VectorXd& x, const std::string& name,
		   int digits) {
  using std::max;
  using std::ceil;
  using std::log10;

  double padding = 0;
  if (digits > 0)
    padding = digits + 1;

  double size = ceil(log10(x.maxCoeff()+0.001)) + padding;
  if (x.minCoeff() < 0)
    size = max(size, ceil(log10(-x.minCoeff()+0.01))+(padding+1));

  return max(size,
	     max(name.length(), std::string("-0.0").length())+0.0);
}

/**
 * The Stan print function.
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success,
 *         non-zero otherwise
 */
int main(int argc, const char* argv[]) {
  if (argc == 1) {
    std::cout << "usage: print <filename 1> <filename 2>";
    return 0;
  }

  std::vector<std::string> filenames;
  for (int i = 1; i < argc; i++) {
    filenames.push_back(argv[i]);
  }

  Eigen::VectorXi thin(filenames.size());

  std::ifstream ifstream;
  ifstream.open(filenames[0].c_str());
  stan::io::stan_csv stan_csv = stan::io::stan_csv_reader::parse(ifstream);
  stan::mcmc::chains<> chains(stan_csv);
  ifstream.close();
  thin(0) = stan_csv.metadata.thin;

  for (int chain = 1; chain < filenames.size(); chain++) {
    ifstream.open(filenames[chain].c_str());
    stan_csv = stan::io::stan_csv_reader::parse(ifstream);
    chains.add(stan_csv);
    ifstream.close();
    thin(chain) = stan_csv.metadata.thin;
  }

  // print
  const int skip = 3;
  std::string model_name = "NEED MODEL NAME";
  int max_name_length = 0;
  for (int i = skip; i < chains.num_params(); i++)
    if (chains.param_name(i).length() > max_name_length)
      max_name_length = chains.param_name(i).length();

  Eigen::MatrixXd values(chains.num_params(),10);
  values.setZero();
  Eigen::VectorXd probs(5);
  probs << 0.025, 0.25, 0.5, 0.75, 0.975;

  for (int i = skip; i < chains.num_params(); i++) {
    double sd = chains.sd(i);
    double n_eff = chains.effective_sample_size(i);
    values(i,0) = chains.mean(i);
    values(i,1) = sd / sqrt(n_eff);
    values(i,2) = sd;
    Eigen::VectorXd quantiles = chains.quantiles(i,probs);
    for (int j = 0; j < 5; j++)
      values(i,3+j) = quantiles(j);
    values(i,8) = n_eff;
    values(i,9) = chains.split_potential_scale_reduction(i);
  }

  Eigen::VectorXi column_lengths(11);
  column_lengths(0) = max_name_length + 1;
  column_lengths(1) = calculate_size(values.col(0), "mean", 1)+1;
  column_lengths(2) = calculate_size(values.col(1), "se_mean", 1)+1;
  column_lengths(3) = calculate_size(values.col(2), "sd", 1)+1;
  column_lengths(4) = calculate_size(values.col(3), "2.5%", 1)+1;
  column_lengths(5) = calculate_size(values.col(4), "25%", 1)+1;
  column_lengths(6) = calculate_size(values.col(5), "50%", 1)+1;
  column_lengths(7) = calculate_size(values.col(6), "75%", 1)+1;
  column_lengths(8) = calculate_size(values.col(7), "97.5%", 1)+1;
  column_lengths(9) = calculate_size(values.col(8), "n_eff", 0)+1;
  column_lengths(10) = calculate_size(values.col(9), "Rhat", 1)+1;

  std::cout << "Inference for Stan model: " << model_name << std::endl
	    << chains.num_chains() << " chains: each with iter=(" << chains.num_kept_samples(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << chains.num_kept_samples(chain);
  std::cout << ")";
  std::cout << "; warmup=(" << chains.warmup(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << chains.warmup(chain);
  std::cout << ")";
  std::cout << "; thin=(" << thin(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << thin(chain);
  std::cout << ")";
  std::cout << "; " << chains.num_samples() << " iterations saved."
	    << std::endl << std::endl;

  // header
  std::cout << std::setw(column_lengths(0)) << ""
	    << std::setw(column_lengths(1)) << "mean"
	    << std::setw(column_lengths(2)) << "se_mean"
	    << std::setw(column_lengths(3)) << "sd"
	    << std::setw(column_lengths(4)) << "2.5%"
	    << std::setw(column_lengths(5)) << "25%"
	    << std::setw(column_lengths(6)) << "50%"
	    << std::setw(column_lengths(7)) << "75%"
	    << std::setw(column_lengths(8)) << "97.5%"
	    << std::setw(column_lengths(9)) << "n_eff"
	    << std::setw(column_lengths(10)) << "Rhat"
	    << std::endl;
  // each row
  using std::setprecision;
  using std::setw;
  for (int i = skip; i < chains.num_params(); i++) {
    std::cout << setw(column_lengths(0)) << std::left << chains.param_name(i)
	      << std::right << std::fixed
	      << setprecision(1) << setw(column_lengths(1)) << values(i,0)
	      << setprecision(1) << setw(column_lengths(2)) << values(i,1)
	      << setprecision(1) << setw(column_lengths(3)) << values(i,2)
	      << setprecision(1) << setw(column_lengths(4)) << values(i,3)
	      << setprecision(1) << setw(column_lengths(5)) << values(i,4)
	      << setprecision(1) << setw(column_lengths(6)) << values(i,5)
	      << setprecision(1) << setw(column_lengths(7)) << values(i,6)
	      << setprecision(1) << setw(column_lengths(8)) << values(i,7)
	      << setprecision(0) << setw(column_lengths(9)) << values(i,8)
	      << setprecision(1) << setw(column_lengths(10)) << values(i,9)
	      << std::endl;
  }
  std::cout << std::endl;
  std::cout << "Samples were drawn using " << stan_csv.adaptation.sampler << "." << std::endl
	    << "For each parameter, n_eff is a crude measure of effective sample size," << std::endl
	    << "and Rhat is the potential scale reduction factor on split chains (at " << std::endl
	    << "convergence, Rhat=1)." << std::endl
	    << std::endl;

  /*
Inference for Stan model: schools_code.
1 chains: each with iter=100; warmup=50; thin=1; 100 iterations saved.

         mean se_mean   sd  2.5%  25%  50%  75% 97.5% n_eff Rhat
mu        8.3     0.6  4.0   1.6  5.2  8.1 11.0  15.8    42  1.0
tau       6.2     1.0  5.1   0.1  2.5  5.3  8.6  17.9    28  1.0
eta[1]    0.5     0.2  1.1  -1.8 -0.1  0.5  1.3   2.4    50  1.0
eta[2]    0.0     0.1  0.8  -1.5 -0.5  0.0  0.6   1.4    50  1.0
eta[3]   -0.3     0.1  0.7  -1.6 -0.8 -0.3  0.2   1.1    26  1.1
eta[4]   -0.1     0.1  0.7  -1.6 -0.5 -0.1  0.2   1.5    50  1.0
eta[5]   -0.4     0.1  0.8  -1.6 -1.1 -0.4  0.1   1.2    49  1.0
eta[6]   -0.2     0.1  0.9  -1.9 -1.0 -0.5  0.5   1.6    50  1.0
eta[7]    0.3     0.2  0.9  -1.8 -0.2  0.6  0.9   1.7    27  1.0
eta[8]    0.0     0.1  0.7  -1.4 -0.4  0.1  0.6   1.1    50  1.0
theta[1] 12.9     1.5 10.4  -6.5  7.4 11.4 15.1  39.1    50  1.0
theta[2]  9.2     1.0  6.1   0.0  4.3  8.4 13.3  22.2    35  1.0
theta[3]  6.3     0.9  6.4 -12.2  3.9  6.7 10.2  13.3    50  1.0
theta[4]  8.0     1.0  6.8  -6.9  4.6  7.8 12.6  19.4    50  1.0
theta[5]  4.6     0.8  5.6  -6.4  1.2  6.0  8.9  13.0    50  1.0
theta[6]  6.2     1.0  5.2  -1.9  2.1  6.8 10.5  13.6    27  1.0
theta[7] 11.0     0.8  5.1   2.0  7.9 10.8 14.3  21.0    40  1.0
theta[8]  8.4     1.0  6.2  -3.3  5.3  8.4 13.0  17.8    41  1.0
lp__     -4.5     0.8  2.7 -11.0 -5.7 -4.3 -2.4  -0.7    13  1.1

Samples were drawn using NUTS2 at Sat Feb 16 00:42:14 2013.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
   */

  return 0;
}

<commit_msg>updated print<commit_after>#include <algorithm>
#include <iostream>
#include <iomanip>
#include <ios>
#include <stan/mcmc/chains.hpp>

int calculate_size(const Eigen::VectorXd& x, const std::string& name,
		   int digits) {
  using std::max;
  using std::ceil;
  using std::log10;

  double padding = 0;
  if (digits > 0)
    padding = digits + 1;

  double size = ceil(log10(x.maxCoeff()+0.001)) + padding;
  if (x.minCoeff() < 0)
    size = max(size, ceil(log10(-x.minCoeff()+0.01))+(padding+1));

  return max(size,
	     max(name.length(), std::string("-0.0").length())+0.0);
}

/**
 * The Stan print function.
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success,
 *         non-zero otherwise
 */
int main(int argc, const char* argv[]) {
  if (argc == 1) {
    std::cout << "usage: print <filename 1> <filename 2>";
    return 0;
  }

  std::vector<std::string> filenames;
  for (int i = 1; i < argc; i++) {
    filenames.push_back(argv[i]);
  }

  Eigen::VectorXi thin(filenames.size());

  std::ifstream ifstream;
  ifstream.open(filenames[0].c_str());
  stan::io::stan_csv stan_csv = stan::io::stan_csv_reader::parse(ifstream);
  stan::mcmc::chains<> chains(stan_csv);
  ifstream.close();
  thin(0) = stan_csv.metadata.thin;

  for (int chain = 1; chain < filenames.size(); chain++) {
    ifstream.open(filenames[chain].c_str());
    stan_csv = stan::io::stan_csv_reader::parse(ifstream);
    chains.add(stan_csv);
    ifstream.close();
    thin(chain) = stan_csv.metadata.thin;
  }

  // print
  const int skip = 3;
  std::string model_name = "NEED MODEL NAME";
  int max_name_length = 0;
  for (int i = skip; i < chains.num_params(); i++)
    if (chains.param_name(i).length() > max_name_length)
      max_name_length = chains.param_name(i).length();

  Eigen::MatrixXd values(chains.num_params(),10);
  values.setZero();
  Eigen::VectorXd probs(5);
  probs << 0.025, 0.25, 0.5, 0.75, 0.975;

  for (int i = skip; i < chains.num_params(); i++) {
    double sd = chains.sd(i);
    double n_eff = chains.effective_sample_size(i);
    values(i,0) = chains.mean(i);
    values(i,1) = sd / sqrt(n_eff);
    values(i,2) = sd;
    Eigen::VectorXd quantiles = chains.quantiles(i,probs);
    for (int j = 0; j < 5; j++)
      values(i,3+j) = quantiles(j);
    values(i,8) = n_eff;
    values(i,9) = chains.split_potential_scale_reduction(i);
  }

  int n = 10;
  Eigen::Matrix<std::string, Eigen::Dynamic, 1> headers(n);
  headers <<
    "mean", "se_mean", "sd",
    "2.5%", "25%", "50%", "75%", "97.5%",
    "n_eff", "Rhat";
  Eigen::VectorXi digits(n);
  digits.setConstant(1);
  digits(8) = 0;

  Eigen::VectorXi column_lengths(n);
  for (int i = 0; i < n; i++) {
    column_lengths(i) = calculate_size(values.col(i), headers(i), digits(i)) + 1;
  }

  std::cout << "Inference for Stan model: " << model_name << std::endl
	    << chains.num_chains() << " chains: each with iter=(" << chains.num_kept_samples(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << chains.num_kept_samples(chain);
  std::cout << ")";
  std::cout << "; warmup=(" << chains.warmup(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << chains.warmup(chain);
  std::cout << ")";
  std::cout << "; thin=(" << thin(0);
  for (int chain = 1; chain < chains.num_chains(); chain++)
    std::cout << "," << thin(chain);
  std::cout << ")";
  std::cout << "; " << chains.num_samples() << " iterations saved."
	    << std::endl << std::endl;

  using std::setprecision;
  using std::setw;

  // header
  std::cout << std::setw(max_name_length+1) << "";
  for (int i = 0; i < n; i++) {
    std::cout << setw(column_lengths(i)) << headers(i);
  }
  std::cout << std::endl;
  // each row
  for (int i = skip; i < chains.num_params(); i++) {
    std::cout << setw(max_name_length+1) << std::left << chains.param_name(i);
    std::cout << std::right << std::fixed;
    for (int j = 0; j < n; j++)
      std::cout << setprecision(digits(j)) << setw(column_lengths(j)) << values(i,j);
    std::cout << std::endl;
  }
  std::cout << std::endl;
  std::cout << "Samples were drawn using " << stan_csv.adaptation.sampler << "." << std::endl
	    << "For each parameter, n_eff is a crude measure of effective sample size," << std::endl
	    << "and Rhat is the potential scale reduction factor on split chains (at " << std::endl
	    << "convergence, Rhat=1)." << std::endl
	    << std::endl;

  /*
Inference for Stan model: schools_code.
1 chains: each with iter=100; warmup=50; thin=1; 100 iterations saved.

         mean se_mean   sd  2.5%  25%  50%  75% 97.5% n_eff Rhat
mu        8.3     0.6  4.0   1.6  5.2  8.1 11.0  15.8    42  1.0
tau       6.2     1.0  5.1   0.1  2.5  5.3  8.6  17.9    28  1.0
eta[1]    0.5     0.2  1.1  -1.8 -0.1  0.5  1.3   2.4    50  1.0
eta[2]    0.0     0.1  0.8  -1.5 -0.5  0.0  0.6   1.4    50  1.0
eta[3]   -0.3     0.1  0.7  -1.6 -0.8 -0.3  0.2   1.1    26  1.1
eta[4]   -0.1     0.1  0.7  -1.6 -0.5 -0.1  0.2   1.5    50  1.0
eta[5]   -0.4     0.1  0.8  -1.6 -1.1 -0.4  0.1   1.2    49  1.0
eta[6]   -0.2     0.1  0.9  -1.9 -1.0 -0.5  0.5   1.6    50  1.0
eta[7]    0.3     0.2  0.9  -1.8 -0.2  0.6  0.9   1.7    27  1.0
eta[8]    0.0     0.1  0.7  -1.4 -0.4  0.1  0.6   1.1    50  1.0
theta[1] 12.9     1.5 10.4  -6.5  7.4 11.4 15.1  39.1    50  1.0
theta[2]  9.2     1.0  6.1   0.0  4.3  8.4 13.3  22.2    35  1.0
theta[3]  6.3     0.9  6.4 -12.2  3.9  6.7 10.2  13.3    50  1.0
theta[4]  8.0     1.0  6.8  -6.9  4.6  7.8 12.6  19.4    50  1.0
theta[5]  4.6     0.8  5.6  -6.4  1.2  6.0  8.9  13.0    50  1.0
theta[6]  6.2     1.0  5.2  -1.9  2.1  6.8 10.5  13.6    27  1.0
theta[7] 11.0     0.8  5.1   2.0  7.9 10.8 14.3  21.0    40  1.0
theta[8]  8.4     1.0  6.2  -3.3  5.3  8.4 13.0  17.8    41  1.0
lp__     -4.5     0.8  2.7 -11.0 -5.7 -4.3 -2.4  -0.7    13  1.1

Samples were drawn using NUTS2 at Sat Feb 16 00:42:14 2013.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
   */

  return 0;
}

<|endoftext|>


<commit_before>/* ----------------------------------------------------------------------------
   libconfig - A library for processing structured configuration files
   Copyright (C) 2005-2014  Mark A Lindner

   This file is part of libconfig.

   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 Library General Public
   License along with this library; if not, see
   <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------------
*/

#ifndef __libconfig_hpp
#define __libconfig_hpp

#include <stdio.h>
#include <exception>
#include <string>

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#if defined(LIBCONFIGXX_STATIC)
#define LIBCONFIGXX_API
#elif defined(LIBCONFIGXX_EXPORTS)
#define LIBCONFIGXX_API __declspec(dllexport)
#else /* ! LIBCONFIGXX_EXPORTS */
#define LIBCONFIGXX_API __declspec(dllimport)
#endif /* LIBCONFIGXX_STATIC */
#else /* ! WIN32 */
#define LIBCONFIGXX_API
#endif /* WIN32 */

#define LIBCONFIGXX_VER_MAJOR    1
#define LIBCONFIGXX_VER_MINOR    5
#define LIBCONFIGXX_VER_REVISION 0

struct config_t; // fwd decl
struct config_setting_t; // fwd decl

namespace libconfig {

class LIBCONFIGXX_API ConfigException : public std::exception { };

class Setting; // fwd decl
class SettingIterator;
class SettingConstIterator;

class LIBCONFIGXX_API SettingException : public ConfigException
{
  public:

  SettingException(const Setting &setting);
  SettingException(const Setting &setting, int idx);
  SettingException(const Setting &setting, const char *name);
  SettingException(const char *path);

  SettingException(const SettingException &other);
  SettingException& operator=(const SettingException &other);

  virtual ~SettingException() throw();

  const char *getPath() const;

  virtual const char *what() const throw();

  private:

  char *_path;
};

class LIBCONFIGXX_API SettingTypeException : public SettingException
{
  public:

  SettingTypeException(const Setting &setting);
  SettingTypeException(const Setting &setting, int idx);
  SettingTypeException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API SettingNotFoundException : public SettingException
{
  public:

  SettingNotFoundException(const char *path);
  SettingNotFoundException(const Setting &setting, int idx);
  SettingNotFoundException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API SettingNameException : public SettingException
{
  public:

  SettingNameException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API FileIOException : public ConfigException
{
  public:

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API ParseException : public ConfigException
{
  public:

  ParseException(const char *file, int line, const char *error);

  ParseException(const ParseException &other);

  virtual ~ParseException() throw();

  inline const char *getFile() const
  { return(_file); }

  inline int getLine() const
  { return(_line); }

  inline const char *getError() const
  { return(_error); }

  virtual const char *what() const throw();

  private:

  const char *_file;
  int _line;
  const char *_error;
};

class LIBCONFIGXX_API Setting
{
  friend class Config;

  public:

  enum Type
  {
    TypeNone = 0,
    // scalar types
    TypeInt,
    TypeInt64,
    TypeFloat,
    TypeString,
    TypeBoolean,
    // aggregate types
    TypeGroup,
    TypeArray,
    TypeList
  };

  enum Format
  {
    FormatDefault = 0,
    FormatHex = 1
  };

  typedef SettingIterator iterator;
  typedef SettingConstIterator const_iterator;

  public:

  virtual ~Setting();

  inline Type getType() const { return(_type); }

  inline Format getFormat() const { return(_format); }
  void setFormat(Format format);

  operator bool() const;
  operator int() const;
  operator unsigned int() const;
  operator long() const;
  operator unsigned long() const;
  operator long long() const;
  operator unsigned long long() const;
  operator double() const;
  operator float() const;
  operator const char *() const;
  operator std::string() const;

  inline const char *c_str() const
  { return operator const char *(); }

  Setting & operator=(bool value);
  Setting & operator=(int value);
  Setting & operator=(long value);
  Setting & operator=(const long long &value);
  Setting & operator=(const double &value);
  Setting & operator=(float value);
  Setting & operator=(const char *value);
  Setting & operator=(const std::string &value);

  Setting & lookup(const char *path) const;
  inline Setting & lookup(const std::string &path) const
  { return(lookup(path.c_str())); }

  Setting & operator[](const char *name) const;
  Setting & operator[](int index) const;

  bool lookupValue(const char *name, bool &value) const;
  bool lookupValue(const char *name, int &value) const;
  bool lookupValue(const char *name, unsigned int &value) const;
  bool lookupValue(const char *name, long long &value) const;
  bool lookupValue(const char *name, unsigned long long &value) const;
  bool lookupValue(const char *name, double &value) const;
  bool lookupValue(const char *name, float &value) const;
  bool lookupValue(const char *name, const char *&value) const;
  bool lookupValue(const char *name, std::string &value) const;

  inline bool lookupValue(const std::string &name, bool &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, int &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, unsigned int &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, long long &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name,
                          unsigned long long &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, double &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, float &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, const char *&value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, std::string &value) const
  { return(lookupValue(name.c_str(), value)); }

  void remove(const char *name);

  inline void remove(const std::string &name)
  { remove(name.c_str()); }

  void remove(unsigned int idx);

  Setting & add(const char *name, Type type);

  inline Setting & add(const std::string &name, Type type)
  { return(add(name.c_str(), type)); }

  Setting & add(Type type);

  bool exists(const char *name) const;

  inline bool exists(const std::string &name) const
  { return(exists(name.c_str())); }

  int getLength() const;
  const char *getName() const;
  std::string getPath() const;
  int getIndex() const;

  const Setting & getParent() const;
  Setting & getParent();

  bool isRoot() const;

  inline bool isGroup() const
  { return(_type == TypeGroup); }

  inline bool isArray() const
  { return(_type == TypeArray); }

  inline bool isList() const
  { return(_type == TypeList); }

  inline bool isAggregate() const
  { return(_type >= TypeGroup); }

  inline bool isScalar() const
  { return((_type > TypeNone) && (_type < TypeGroup)); }

  inline bool isNumber() const
  {
    return((_type == TypeInt) || (_type == TypeInt64) || (_type == TypeFloat));
  }

  unsigned int getSourceLine() const;
  const char *getSourceFile() const;

  iterator begin();
  iterator end();

  const_iterator begin() const;
  const_iterator end() const;

  private:

  config_setting_t *_setting;
  Type _type;
  Format _format;

  Setting(config_setting_t *setting);

  void assertType(Type type) const;
  static Setting & wrapSetting(config_setting_t *setting);

  Setting(const Setting& other); // not supported
  Setting& operator=(const Setting& other); // not supported
};

class LIBCONFIGXX_API SettingIterator
{
  public:

  SettingIterator(Setting &setting, bool endIterator = false);
  SettingIterator(const SettingIterator &other);
  SettingIterator& operator=(const SettingIterator &other);

  // Equality comparison.
  inline bool operator==(SettingIterator const &other) const
  { return(_idx == other._idx); }

  inline bool operator!=(SettingIterator const &other) const
  { return(*this != other); }

  bool operator<(SettingIterator const &other) const;

  // Dereference operators.
  inline Setting & operator*()
  { return((*_setting)[_idx]); }

  inline Setting * operator->()
  { return(&(*_setting)[_idx]); }

  inline const Setting & operator*() const
  { return(*_setting)[_idx]; }
  inline const Setting * operator->() const
  { return(&(*_setting)[_idx]); }

  // Increment and decrement operators.
  SettingIterator & operator++();
  SettingIterator operator++(int);

  SettingIterator & operator--();
  SettingIterator operator--(int);

  // Arithmetic operators.
  SettingIterator operator+(int offset) const;
  SettingIterator & operator+=(int offset);

  SettingIterator operator-(int offset) const;
  SettingIterator & operator-=(int offset);

  int operator-(const SettingIterator &other) const;

  private:

  Setting *_setting;

  int _count;
  int _idx;
};

SettingIterator operator+(int offset, const SettingIterator &si);

class LIBCONFIGXX_API SettingConstIterator
{
  public:

  SettingConstIterator(const Setting &setting, bool endIterator = false);
  SettingConstIterator(const SettingConstIterator &rhs);
  SettingConstIterator& operator=(const SettingConstIterator &rhs);

  // Equality comparison.
  bool operator==(SettingConstIterator const &other) const
  { return(_idx == other._idx); }

  inline bool operator!=(SettingConstIterator const &other) const
  { return(*this != other); }

  // Dereference operators.
  inline Setting const & operator*()
  { return((*_setting)[_idx]); }
  inline Setting const * operator->()
  { return(&(*_setting)[_idx]); }

  inline const Setting& operator*() const
  { return((*_setting)[_idx]); }
  inline const Setting * operator->() const
  { return(&(*_setting)[_idx]); }

  // Increment and decrement operators.
  SettingConstIterator & operator++();
  SettingConstIterator operator++(int);

  SettingConstIterator & operator--();
  SettingConstIterator operator--(int);

  // Arithmetic operators.
  SettingConstIterator operator+(int offset) const;
  SettingConstIterator & operator+=(int offset);

  SettingConstIterator operator-(int offset) const;
  SettingConstIterator & operator-=(int offset);

  int operator-(const SettingConstIterator &other) const;

  private:

  const Setting *_setting;

  int _count;
  int _idx;
};

SettingConstIterator operator+(int offset, const SettingConstIterator &si);

class LIBCONFIGXX_API Config
{
  public:

  Config();
  virtual ~Config();

  void setAutoConvert(bool flag);
  bool getAutoConvert() const;

  void setDefaultFormat(Setting::Format format);
  inline Setting::Format getDefaultFormat() const
  { return(_defaultFormat); }

  void setTabWidth(unsigned short width);
  unsigned short getTabWidth() const;

  void setIncludeDir(const char *includeDir);
  const char *getIncludeDir() const;

  void read(FILE *stream);
  void write(FILE *stream) const;

  void readString(const char *str);
  inline void readString(const std::string &str)
  { return(readString(str.c_str())); }

  void readFile(const char *filename);
  void writeFile(const char *filename);

  Setting & lookup(const char *path) const;
  inline Setting & lookup(const std::string &path) const
  { return(lookup(path.c_str())); }

  bool exists(const char *path) const;
  inline bool exists(const std::string &path) const
  { return(exists(path.c_str())); }

  bool lookupValue(const char *path, bool &value) const;
  bool lookupValue(const char *path, int &value) const;
  bool lookupValue(const char *path, unsigned int &value) const;
  bool lookupValue(const char *path, long long &value) const;
  bool lookupValue(const char *path, unsigned long long &value) const;
  bool lookupValue(const char *path, double &value) const;
  bool lookupValue(const char *path, float &value) const;
  bool lookupValue(const char *path, const char *&value) const;
  bool lookupValue(const char *path, std::string &value) const;

  inline bool lookupValue(const std::string &path, bool &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, int &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, unsigned int &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, long long &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path,
                          unsigned long long &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, double &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, float &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, const char *&value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, std::string &value) const
  { return(lookupValue(path.c_str(), value)); }

  Setting & getRoot() const;

  private:

  static void ConfigDestructor(void *arg);
  void handleError() const;

  config_t *_config;
  Setting::Format _defaultFormat;

  Config(const Config& other); // not supported
  Config& operator=(const Config& other); // not supported
};

} // namespace libconfig

#endif // __libconfig_hpp
<commit_msg>Fixed implementations of iterator operator== and operator!= (which were infinitely recursive).<commit_after>/* ----------------------------------------------------------------------------
   libconfig - A library for processing structured configuration files
   Copyright (C) 2005-2014  Mark A Lindner

   This file is part of libconfig.

   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 Library General Public
   License along with this library; if not, see
   <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------------
*/

#ifndef __libconfig_hpp
#define __libconfig_hpp

#include <stdio.h>
#include <exception>
#include <string>

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#if defined(LIBCONFIGXX_STATIC)
#define LIBCONFIGXX_API
#elif defined(LIBCONFIGXX_EXPORTS)
#define LIBCONFIGXX_API __declspec(dllexport)
#else /* ! LIBCONFIGXX_EXPORTS */
#define LIBCONFIGXX_API __declspec(dllimport)
#endif /* LIBCONFIGXX_STATIC */
#else /* ! WIN32 */
#define LIBCONFIGXX_API
#endif /* WIN32 */

#define LIBCONFIGXX_VER_MAJOR    1
#define LIBCONFIGXX_VER_MINOR    5
#define LIBCONFIGXX_VER_REVISION 0

struct config_t; // fwd decl
struct config_setting_t; // fwd decl

namespace libconfig {

class LIBCONFIGXX_API ConfigException : public std::exception { };

class Setting; // fwd decl
class SettingIterator;
class SettingConstIterator;

class LIBCONFIGXX_API SettingException : public ConfigException
{
  public:

  SettingException(const Setting &setting);
  SettingException(const Setting &setting, int idx);
  SettingException(const Setting &setting, const char *name);
  SettingException(const char *path);

  SettingException(const SettingException &other);
  SettingException& operator=(const SettingException &other);

  virtual ~SettingException() throw();

  const char *getPath() const;

  virtual const char *what() const throw();

  private:

  char *_path;
};

class LIBCONFIGXX_API SettingTypeException : public SettingException
{
  public:

  SettingTypeException(const Setting &setting);
  SettingTypeException(const Setting &setting, int idx);
  SettingTypeException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API SettingNotFoundException : public SettingException
{
  public:

  SettingNotFoundException(const char *path);
  SettingNotFoundException(const Setting &setting, int idx);
  SettingNotFoundException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API SettingNameException : public SettingException
{
  public:

  SettingNameException(const Setting &setting, const char *name);

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API FileIOException : public ConfigException
{
  public:

  virtual const char *what() const throw();
};

class LIBCONFIGXX_API ParseException : public ConfigException
{
  public:

  ParseException(const char *file, int line, const char *error);

  ParseException(const ParseException &other);

  virtual ~ParseException() throw();

  inline const char *getFile() const
  { return(_file); }

  inline int getLine() const
  { return(_line); }

  inline const char *getError() const
  { return(_error); }

  virtual const char *what() const throw();

  private:

  const char *_file;
  int _line;
  const char *_error;
};

class LIBCONFIGXX_API Setting
{
  friend class Config;

  public:

  enum Type
  {
    TypeNone = 0,
    // scalar types
    TypeInt,
    TypeInt64,
    TypeFloat,
    TypeString,
    TypeBoolean,
    // aggregate types
    TypeGroup,
    TypeArray,
    TypeList
  };

  enum Format
  {
    FormatDefault = 0,
    FormatHex = 1
  };

  typedef SettingIterator iterator;
  typedef SettingConstIterator const_iterator;

  public:

  virtual ~Setting();

  inline Type getType() const { return(_type); }

  inline Format getFormat() const { return(_format); }
  void setFormat(Format format);

  operator bool() const;
  operator int() const;
  operator unsigned int() const;
  operator long() const;
  operator unsigned long() const;
  operator long long() const;
  operator unsigned long long() const;
  operator double() const;
  operator float() const;
  operator const char *() const;
  operator std::string() const;

  inline const char *c_str() const
  { return operator const char *(); }

  Setting & operator=(bool value);
  Setting & operator=(int value);
  Setting & operator=(long value);
  Setting & operator=(const long long &value);
  Setting & operator=(const double &value);
  Setting & operator=(float value);
  Setting & operator=(const char *value);
  Setting & operator=(const std::string &value);

  Setting & lookup(const char *path) const;
  inline Setting & lookup(const std::string &path) const
  { return(lookup(path.c_str())); }

  Setting & operator[](const char *name) const;
  Setting & operator[](int index) const;

  bool lookupValue(const char *name, bool &value) const;
  bool lookupValue(const char *name, int &value) const;
  bool lookupValue(const char *name, unsigned int &value) const;
  bool lookupValue(const char *name, long long &value) const;
  bool lookupValue(const char *name, unsigned long long &value) const;
  bool lookupValue(const char *name, double &value) const;
  bool lookupValue(const char *name, float &value) const;
  bool lookupValue(const char *name, const char *&value) const;
  bool lookupValue(const char *name, std::string &value) const;

  inline bool lookupValue(const std::string &name, bool &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, int &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, unsigned int &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, long long &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name,
                          unsigned long long &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, double &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, float &value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, const char *&value) const
  { return(lookupValue(name.c_str(), value)); }

  inline bool lookupValue(const std::string &name, std::string &value) const
  { return(lookupValue(name.c_str(), value)); }

  void remove(const char *name);

  inline void remove(const std::string &name)
  { remove(name.c_str()); }

  void remove(unsigned int idx);

  Setting & add(const char *name, Type type);

  inline Setting & add(const std::string &name, Type type)
  { return(add(name.c_str(), type)); }

  Setting & add(Type type);

  bool exists(const char *name) const;

  inline bool exists(const std::string &name) const
  { return(exists(name.c_str())); }

  int getLength() const;
  const char *getName() const;
  std::string getPath() const;
  int getIndex() const;

  const Setting & getParent() const;
  Setting & getParent();

  bool isRoot() const;

  inline bool isGroup() const
  { return(_type == TypeGroup); }

  inline bool isArray() const
  { return(_type == TypeArray); }

  inline bool isList() const
  { return(_type == TypeList); }

  inline bool isAggregate() const
  { return(_type >= TypeGroup); }

  inline bool isScalar() const
  { return((_type > TypeNone) && (_type < TypeGroup)); }

  inline bool isNumber() const
  {
    return((_type == TypeInt) || (_type == TypeInt64) || (_type == TypeFloat));
  }

  unsigned int getSourceLine() const;
  const char *getSourceFile() const;

  iterator begin();
  iterator end();

  const_iterator begin() const;
  const_iterator end() const;

  private:

  config_setting_t *_setting;
  Type _type;
  Format _format;

  Setting(config_setting_t *setting);

  void assertType(Type type) const;
  static Setting & wrapSetting(config_setting_t *setting);

  Setting(const Setting& other); // not supported
  Setting& operator=(const Setting& other); // not supported
};

class LIBCONFIGXX_API SettingIterator
{
  public:

  SettingIterator(Setting &setting, bool endIterator = false);
  SettingIterator(const SettingIterator &other);
  SettingIterator& operator=(const SettingIterator &other);

  // Equality comparison.
  inline bool operator==(SettingIterator const &other) const
  { return((_setting == other._setting) && (_idx == other._idx)); }

  inline bool operator!=(SettingIterator const &other) const
  { return(!operator==(other)); }

  bool operator<(SettingIterator const &other) const;

  // Dereference operators.
  inline Setting & operator*()
  { return((*_setting)[_idx]); }

  inline Setting * operator->()
  { return(&(*_setting)[_idx]); }

  inline const Setting & operator*() const
  { return(*_setting)[_idx]; }
  inline const Setting * operator->() const
  { return(&(*_setting)[_idx]); }

  // Increment and decrement operators.
  SettingIterator & operator++();
  SettingIterator operator++(int);

  SettingIterator & operator--();
  SettingIterator operator--(int);

  // Arithmetic operators.
  SettingIterator operator+(int offset) const;
  SettingIterator & operator+=(int offset);

  SettingIterator operator-(int offset) const;
  SettingIterator & operator-=(int offset);

  int operator-(const SettingIterator &other) const;

  private:

  Setting *_setting;

  int _count;
  int _idx;
};

SettingIterator operator+(int offset, const SettingIterator &si);

class LIBCONFIGXX_API SettingConstIterator
{
  public:

  SettingConstIterator(const Setting &setting, bool endIterator = false);
  SettingConstIterator(const SettingConstIterator &rhs);
  SettingConstIterator& operator=(const SettingConstIterator &rhs);

  // Equality comparison.
  bool operator==(SettingConstIterator const &other) const
  { return((_setting == other._setting) && (_idx == other._idx)); }

  inline bool operator!=(SettingConstIterator const &other) const
  { return(!operator==(other)); }

  // Dereference operators.
  inline Setting const & operator*()
  { return((*_setting)[_idx]); }
  inline Setting const * operator->()
  { return(&(*_setting)[_idx]); }

  inline const Setting& operator*() const
  { return((*_setting)[_idx]); }
  inline const Setting * operator->() const
  { return(&(*_setting)[_idx]); }

  // Increment and decrement operators.
  SettingConstIterator & operator++();
  SettingConstIterator operator++(int);

  SettingConstIterator & operator--();
  SettingConstIterator operator--(int);

  // Arithmetic operators.
  SettingConstIterator operator+(int offset) const;
  SettingConstIterator & operator+=(int offset);

  SettingConstIterator operator-(int offset) const;
  SettingConstIterator & operator-=(int offset);

  int operator-(const SettingConstIterator &other) const;

  private:

  const Setting *_setting;

  int _count;
  int _idx;
};

SettingConstIterator operator+(int offset, const SettingConstIterator &si);

class LIBCONFIGXX_API Config
{
  public:

  Config();
  virtual ~Config();

  void setAutoConvert(bool flag);
  bool getAutoConvert() const;

  void setDefaultFormat(Setting::Format format);
  inline Setting::Format getDefaultFormat() const
  { return(_defaultFormat); }

  void setTabWidth(unsigned short width);
  unsigned short getTabWidth() const;

  void setIncludeDir(const char *includeDir);
  const char *getIncludeDir() const;

  void read(FILE *stream);
  void write(FILE *stream) const;

  void readString(const char *str);
  inline void readString(const std::string &str)
  { return(readString(str.c_str())); }

  void readFile(const char *filename);
  void writeFile(const char *filename);

  Setting & lookup(const char *path) const;
  inline Setting & lookup(const std::string &path) const
  { return(lookup(path.c_str())); }

  bool exists(const char *path) const;
  inline bool exists(const std::string &path) const
  { return(exists(path.c_str())); }

  bool lookupValue(const char *path, bool &value) const;
  bool lookupValue(const char *path, int &value) const;
  bool lookupValue(const char *path, unsigned int &value) const;
  bool lookupValue(const char *path, long long &value) const;
  bool lookupValue(const char *path, unsigned long long &value) const;
  bool lookupValue(const char *path, double &value) const;
  bool lookupValue(const char *path, float &value) const;
  bool lookupValue(const char *path, const char *&value) const;
  bool lookupValue(const char *path, std::string &value) const;

  inline bool lookupValue(const std::string &path, bool &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, int &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, unsigned int &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, long long &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path,
                          unsigned long long &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, double &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, float &value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, const char *&value) const
  { return(lookupValue(path.c_str(), value)); }

  inline bool lookupValue(const std::string &path, std::string &value) const
  { return(lookupValue(path.c_str(), value)); }

  Setting & getRoot() const;

  private:

  static void ConfigDestructor(void *arg);
  void handleError() const;

  config_t *_config;
  Setting::Format _defaultFormat;

  Config(const Config& other); // not supported
  Config& operator=(const Config& other); // not supported
};

} // namespace libconfig

#endif // __libconfig_hpp
<|endoftext|>


<commit_before>#include "defaultsettings.h"

#include "settingshelper.h"
#include "microphoneinfo.h"

#include "logger.h"
#include "settingskeys.h"

#include <thread>

DefaultSettings::DefaultSettings():
  settings_(settingsFile, settingsFileFormat)
{}

void DefaultSettings::validateSettings(std::shared_ptr<MicrophoneInfo> mic,
                                       std::shared_ptr<CameraInfo> cam)
{
  if (!validateAudioSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid audio settings, using defaults");
    setDefaultAudioSettings(mic);
  }

  if (!validateVideoSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid video settings, using defaults");
    setDefaultVideoSettings(cam);
  }

  if (!validateCallSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid call settings, using defaults");
    setDefaultCallSettings();
  }
}

bool DefaultSettings::validateAudioSettings()
{
  QStringList neededSettings = {SettingsKey::audioBitrate,
                                SettingsKey::audioComplexity,
                                SettingsKey::audioSignalType,
                                SettingsKey::audioAEC,
                                SettingsKey::audioAECDelay,
                                SettingsKey::audioAECFilterLength,
                                SettingsKey::audioDenoise,
                                SettingsKey::audioDereverb,
                                SettingsKey::audioAGC};

  return checkSettingsList(settings_, neededSettings);
}

bool DefaultSettings::validateVideoSettings()
{
  // video/DeviceID and video/Device are no checked in case we don't have a camera

  const QStringList neededSettings = {SettingsKey::videoResultionWidth,
                                      SettingsKey::videoResultionHeight,
                                      SettingsKey::videoResolutionID,
                                      SettingsKey::videoInputFormat,
                                      SettingsKey::videoYUVThreads,
                                      SettingsKey::videoRGBThreads,
                                      SettingsKey::videoOpenHEVCThreads,
                                      SettingsKey::videoFramerateID,
                                      SettingsKey::videoFramerate,
                                      SettingsKey::videoOpenGL,
                                      SettingsKey::videoQP,

                                      SettingsKey::videoIntra,
                                      SettingsKey::videoSlices,
                                      SettingsKey::videoKvzThreads,
                                      SettingsKey::videoWPP,
                                      SettingsKey::videoOWF,
                                      SettingsKey::videoTiles,
                                      SettingsKey::videoTileDimensions,
                                      SettingsKey::videoVPS,
                                      SettingsKey::videoBitrate,
                                      SettingsKey::videoRCAlgorithm,
                                      SettingsKey::videoOBAClipNeighbours,
                                      SettingsKey::videoScalingList,
                                      SettingsKey::videoLossless,
                                      SettingsKey::videoMVConstraint,
                                      SettingsKey::videoQPInCU,
                                      SettingsKey::videoVAQ,
                                      SettingsKey::videoPreset};

  return checkSettingsList(settings_, neededSettings);
}

bool DefaultSettings::validateCallSettings()
{
  return true;
}

void DefaultSettings::setDefaultAudioSettings(std::shared_ptr<MicrophoneInfo> mic)
{
  if (settings_.value(SettingsKey::audioDevice).isNull() ||
      settings_.value(SettingsKey::audioDevice).toString() == "")
  {
    // TODO: Choose device based on which supports sample rate of 48000
    QStringList devices = mic->getDeviceList();

    if (!devices.empty())
    {
      settings_.setValue(SettingsKey::audioDevice,        devices.first());
      settings_.setValue(SettingsKey::audioDeviceID,      0);
    }
    else
    {
      settings_.setValue(SettingsKey::audioDevice,        "");
      settings_.setValue(SettingsKey::audioDeviceID,      -1);
      Logger::getLogger()->printError(this, "Did not find microphone!");
    }
  }

  // TODO: Choose rest of the audio paramers such as samplerate (and maybe codec)

  settings_.setValue(SettingsKey::audioBitrate,         24000);
  settings_.setValue(SettingsKey::audioComplexity,      10);
  settings_.setValue(SettingsKey::audioSignalType,      "Auto");
  settings_.setValue(SettingsKey::audioAEC,             1);
  settings_.setValue(SettingsKey::audioAECDelay,        120);
  settings_.setValue(SettingsKey::audioAECFilterLength, 250);
  settings_.setValue(SettingsKey::audioDenoise,         1);
  settings_.setValue(SettingsKey::audioDereverb,        1);
  settings_.setValue(SettingsKey::audioAGC,             1);
}

void DefaultSettings::setDefaultVideoSettings(std::shared_ptr<CameraInfo> cam)
{

  // this is a sensible guess on the amounts of threads required
  // TODO: Maybe it would be possible to come up with something even more accurate?
  unsigned int threads = std::thread::hardware_concurrency();
  if (threads < 16)
  {
    settings_.setValue(SettingsKey::videoYUVThreads, 1);
    settings_.setValue(SettingsKey::videoRGBThreads, 1);
    settings_.setValue(SettingsKey::videoOpenHEVCThreads, 1);

    if (threads <= 4)
    {
      settings_.setValue(SettingsKey::videoKvzThreads, threads);
    }
    else
    {
      settings_.setValue(SettingsKey::videoKvzThreads, threads - 1);
    }
  }
  else
  {
    settings_.setValue(SettingsKey::videoYUVThreads, 2);
    settings_.setValue(SettingsKey::videoRGBThreads, 2);
    settings_.setValue(SettingsKey::videoOpenHEVCThreads, 2);
    settings_.setValue(SettingsKey::videoKvzThreads, threads - 2);
  }

  SettingsCameraFormat format = selectBestCameraFormat(cam);

  settings_.setValue(SettingsKey::videoDevice,          format.deviceName);
  settings_.setValue(SettingsKey::videoDeviceID,        format.deviceID);

  // select best camera/format here
  settings_.setValue(SettingsKey::videoInputFormat,     format.format);
  settings_.setValue(SettingsKey::videoResultionWidth,  format.resolution.width());
  settings_.setValue(SettingsKey::videoResultionHeight, format.resolution.height());
  settings_.setValue(SettingsKey::videoResolutionID,    format.resolutionID);
  settings_.setValue(SettingsKey::videoFramerateID,     format.framerateID);
  settings_.setValue(SettingsKey::videoFramerate,       format.framerate);

  settings_.setValue(SettingsKey::videoOpenGL, 0); // TODO: When can we enable this?
  settings_.setValue(SettingsKey::videoQP, 32);

  settings_.setValue(SettingsKey::videoIntra, 64);

  // TODO: This should be enabled when the performance is good enough
  settings_.setValue(SettingsKey::videoSlices, 0);

  settings_.setValue(SettingsKey::videoWPP, 1);
  settings_.setValue(SettingsKey::videoOWF, 0); // causes too much latency
  settings_.setValue(SettingsKey::videoTiles, 0);
  settings_.setValue(SettingsKey::videoTileDimensions, "2x2");
  settings_.setValue(SettingsKey::videoVPS, 1);
  settings_.setValue(SettingsKey::videoBitrate, 0);
  settings_.setValue(SettingsKey::videoRCAlgorithm, "lambda");
  settings_.setValue(SettingsKey::videoOBAClipNeighbours, 0);
  settings_.setValue(SettingsKey::videoScalingList, 0);
  settings_.setValue(SettingsKey::videoLossless, 0); // very CPU intensive
  settings_.setValue(SettingsKey::videoMVConstraint, "none");
  settings_.setValue(SettingsKey::videoQPInCU, 0);
  settings_.setValue(SettingsKey::videoVAQ, "disabled");
  settings_.setValue(SettingsKey::videoPreset, "ultrafast");
}

void DefaultSettings::setDefaultCallSettings()
{
}

SettingsCameraFormat DefaultSettings::selectBestCameraFormat(std::shared_ptr<CameraInfo> cam)
{
  // Note: the current implementation does not go through all the devices to
  // find the best format, just the first one
  if (!settings_.value(SettingsKey::videoDeviceID).isNull() &&
      settings_.value(SettingsKey::videoDeviceID) != "")
  {
    int deviceID = settings_.value(SettingsKey::videoDeviceID).toInt();
    deviceID = cam->getMostMatchingDeviceID(settings_.value(SettingsKey::videoDevice).toString(),
                                            deviceID);
    return selectBestDeviceFormat(cam, deviceID);
  }

  return selectBestDeviceFormat(cam, 0);
}

SettingsCameraFormat DefaultSettings::selectBestDeviceFormat(std::shared_ptr<CameraInfo> cam,
                                                             int deviceID)
{
  // point system for best format

  SettingsCameraFormat bestOption = {"No camera found", deviceID, "No camera", -1, {}, -1, 0, -1};
  uint64_t highestValue = 0;

  std::vector<SettingsCameraFormat> options;
  cam->getCameraOptions(options, deviceID);

  for (auto& option: options)
  {
    uint64_t points = calculatePoints(option.resolution,
                                      option.framerate.toDouble());

    if (points > highestValue)
    {
      highestValue = points;
      bestOption = option;
    }
  }

  QString resolution = QString::number(bestOption.resolution.width()) + "x" +
                       QString::number(bestOption.resolution.height());

  Logger::getLogger()->printDebug(DEBUG_NORMAL, this, "Selected the best format",
                                  {"Points", "Device", "Format", "Resolution", "Framerate"},
                                   {QString::number(highestValue), bestOption.deviceName,
                                    bestOption.format, resolution, bestOption.framerate});

  return bestOption;
}

uint64_t DefaultSettings::calculatePoints(QSize resolution, double fps)
{
  // we give much lower score to low fps values
  if (fps < 30.0)
  {
    return (resolution.width()*resolution.height()/10 + (int)fps);
  }

  return resolution.width()*resolution.height() + (int)fps;
}
<commit_msg>feature(Settings): Change default openHEVC thread amount to reduce latency<commit_after>#include "defaultsettings.h"

#include "settingshelper.h"
#include "microphoneinfo.h"

#include "logger.h"
#include "settingskeys.h"

#include <thread>

DefaultSettings::DefaultSettings():
  settings_(settingsFile, settingsFileFormat)
{}

void DefaultSettings::validateSettings(std::shared_ptr<MicrophoneInfo> mic,
                                       std::shared_ptr<CameraInfo> cam)
{
  if (!validateAudioSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid audio settings, using defaults");
    setDefaultAudioSettings(mic);
  }

  if (!validateVideoSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid video settings, using defaults");
    setDefaultVideoSettings(cam);
  }

  if (!validateCallSettings())
  {
    Logger::getLogger()->printWarning(this, "Did not find valid call settings, using defaults");
    setDefaultCallSettings();
  }
}

bool DefaultSettings::validateAudioSettings()
{
  QStringList neededSettings = {SettingsKey::audioBitrate,
                                SettingsKey::audioComplexity,
                                SettingsKey::audioSignalType,
                                SettingsKey::audioAEC,
                                SettingsKey::audioAECDelay,
                                SettingsKey::audioAECFilterLength,
                                SettingsKey::audioDenoise,
                                SettingsKey::audioDereverb,
                                SettingsKey::audioAGC};

  return checkSettingsList(settings_, neededSettings);
}

bool DefaultSettings::validateVideoSettings()
{
  // video/DeviceID and video/Device are no checked in case we don't have a camera

  const QStringList neededSettings = {SettingsKey::videoResultionWidth,
                                      SettingsKey::videoResultionHeight,
                                      SettingsKey::videoResolutionID,
                                      SettingsKey::videoInputFormat,
                                      SettingsKey::videoYUVThreads,
                                      SettingsKey::videoRGBThreads,
                                      SettingsKey::videoOpenHEVCThreads,
                                      SettingsKey::videoFramerateID,
                                      SettingsKey::videoFramerate,
                                      SettingsKey::videoOpenGL,
                                      SettingsKey::videoQP,

                                      SettingsKey::videoIntra,
                                      SettingsKey::videoSlices,
                                      SettingsKey::videoKvzThreads,
                                      SettingsKey::videoWPP,
                                      SettingsKey::videoOWF,
                                      SettingsKey::videoTiles,
                                      SettingsKey::videoTileDimensions,
                                      SettingsKey::videoVPS,
                                      SettingsKey::videoBitrate,
                                      SettingsKey::videoRCAlgorithm,
                                      SettingsKey::videoOBAClipNeighbours,
                                      SettingsKey::videoScalingList,
                                      SettingsKey::videoLossless,
                                      SettingsKey::videoMVConstraint,
                                      SettingsKey::videoQPInCU,
                                      SettingsKey::videoVAQ,
                                      SettingsKey::videoPreset};

  return checkSettingsList(settings_, neededSettings);
}

bool DefaultSettings::validateCallSettings()
{
  return true;
}

void DefaultSettings::setDefaultAudioSettings(std::shared_ptr<MicrophoneInfo> mic)
{
  if (settings_.value(SettingsKey::audioDevice).isNull() ||
      settings_.value(SettingsKey::audioDevice).toString() == "")
  {
    // TODO: Choose device based on which supports sample rate of 48000
    QStringList devices = mic->getDeviceList();

    if (!devices.empty())
    {
      settings_.setValue(SettingsKey::audioDevice,        devices.first());
      settings_.setValue(SettingsKey::audioDeviceID,      0);
    }
    else
    {
      settings_.setValue(SettingsKey::audioDevice,        "");
      settings_.setValue(SettingsKey::audioDeviceID,      -1);
      Logger::getLogger()->printError(this, "Did not find microphone!");
    }
  }

  // TODO: Choose rest of the audio paramers such as samplerate (and maybe codec)

  settings_.setValue(SettingsKey::audioBitrate,         24000);
  settings_.setValue(SettingsKey::audioComplexity,      10);
  settings_.setValue(SettingsKey::audioSignalType,      "Auto");
  settings_.setValue(SettingsKey::audioAEC,             1);
  settings_.setValue(SettingsKey::audioAECDelay,        120);
  settings_.setValue(SettingsKey::audioAECFilterLength, 250);
  settings_.setValue(SettingsKey::audioDenoise,         1);
  settings_.setValue(SettingsKey::audioDereverb,        1);
  settings_.setValue(SettingsKey::audioAGC,             1);
}

void DefaultSettings::setDefaultVideoSettings(std::shared_ptr<CameraInfo> cam)
{

  // this is a sensible guess on the amounts of threads required
  // TODO: Maybe it would be possible to come up with something even more accurate?
  unsigned int threads = std::thread::hardware_concurrency();
  if (threads < 16)
  {
    settings_.setValue(SettingsKey::videoYUVThreads, 1);
    settings_.setValue(SettingsKey::videoRGBThreads, 1);
    settings_.setValue(SettingsKey::videoOpenHEVCThreads, 1);

    if (threads <= 4)
    {
      settings_.setValue(SettingsKey::videoKvzThreads, threads);
    }
    else
    {
      settings_.setValue(SettingsKey::videoKvzThreads, threads - 1);

      // slightly reduces decoding latency (~4 ms)
      settings_.setValue(SettingsKey::videoOpenHEVCThreads, 2);
    }
  }
  else
  {
    settings_.setValue(SettingsKey::videoYUVThreads, 2);
    settings_.setValue(SettingsKey::videoRGBThreads, 2);
    settings_.setValue(SettingsKey::videoOpenHEVCThreads, 3);
    settings_.setValue(SettingsKey::videoKvzThreads, threads - 2);
  }

  SettingsCameraFormat format = selectBestCameraFormat(cam);

  settings_.setValue(SettingsKey::videoDevice,          format.deviceName);
  settings_.setValue(SettingsKey::videoDeviceID,        format.deviceID);

  // select best camera/format here
  settings_.setValue(SettingsKey::videoInputFormat,     format.format);
  settings_.setValue(SettingsKey::videoResultionWidth,  format.resolution.width());
  settings_.setValue(SettingsKey::videoResultionHeight, format.resolution.height());
  settings_.setValue(SettingsKey::videoResolutionID,    format.resolutionID);
  settings_.setValue(SettingsKey::videoFramerateID,     format.framerateID);
  settings_.setValue(SettingsKey::videoFramerate,       format.framerate);

  settings_.setValue(SettingsKey::videoOpenGL, 0); // TODO: When can we enable this?
  settings_.setValue(SettingsKey::videoQP, 32);

  settings_.setValue(SettingsKey::videoIntra, 64);

  // TODO: This should be enabled when the performance is good enough
  settings_.setValue(SettingsKey::videoSlices, 0);

  settings_.setValue(SettingsKey::videoWPP, 1);
  settings_.setValue(SettingsKey::videoOWF, 0); // causes too much latency
  settings_.setValue(SettingsKey::videoTiles, 0);
  settings_.setValue(SettingsKey::videoTileDimensions, "2x2");
  settings_.setValue(SettingsKey::videoVPS, 1);
  settings_.setValue(SettingsKey::videoBitrate, 0);
  settings_.setValue(SettingsKey::videoRCAlgorithm, "lambda");
  settings_.setValue(SettingsKey::videoOBAClipNeighbours, 0);
  settings_.setValue(SettingsKey::videoScalingList, 0);
  settings_.setValue(SettingsKey::videoLossless, 0); // very CPU intensive
  settings_.setValue(SettingsKey::videoMVConstraint, "none");
  settings_.setValue(SettingsKey::videoQPInCU, 0);
  settings_.setValue(SettingsKey::videoVAQ, "disabled");
  settings_.setValue(SettingsKey::videoPreset, "ultrafast");
}

void DefaultSettings::setDefaultCallSettings()
{
}

SettingsCameraFormat DefaultSettings::selectBestCameraFormat(std::shared_ptr<CameraInfo> cam)
{
  // Note: the current implementation does not go through all the devices to
  // find the best format, just the first one
  if (!settings_.value(SettingsKey::videoDeviceID).isNull() &&
      settings_.value(SettingsKey::videoDeviceID) != "")
  {
    int deviceID = settings_.value(SettingsKey::videoDeviceID).toInt();
    deviceID = cam->getMostMatchingDeviceID(settings_.value(SettingsKey::videoDevice).toString(),
                                            deviceID);
    return selectBestDeviceFormat(cam, deviceID);
  }

  return selectBestDeviceFormat(cam, 0);
}

SettingsCameraFormat DefaultSettings::selectBestDeviceFormat(std::shared_ptr<CameraInfo> cam,
                                                             int deviceID)
{
  // point system for best format

  SettingsCameraFormat bestOption = {"No camera found", deviceID, "No camera", -1, {}, -1, 0, -1};
  uint64_t highestValue = 0;

  std::vector<SettingsCameraFormat> options;
  cam->getCameraOptions(options, deviceID);

  for (auto& option: options)
  {
    uint64_t points = calculatePoints(option.resolution,
                                      option.framerate.toDouble());

    if (points > highestValue)
    {
      highestValue = points;
      bestOption = option;
    }
  }

  QString resolution = QString::number(bestOption.resolution.width()) + "x" +
                       QString::number(bestOption.resolution.height());

  Logger::getLogger()->printDebug(DEBUG_NORMAL, this, "Selected the best format",
                                  {"Points", "Device", "Format", "Resolution", "Framerate"},
                                   {QString::number(highestValue), bestOption.deviceName,
                                    bestOption.format, resolution, bestOption.framerate});

  return bestOption;
}

uint64_t DefaultSettings::calculatePoints(QSize resolution, double fps)
{
  // we give much lower score to low fps values
  if (fps < 30.0)
  {
    return (resolution.width()*resolution.height()/10 + (int)fps);
  }

  return resolution.width()*resolution.height() + (int)fps;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.2  1999/12/02 19:02:57  roddey
 * Get rid of a few statically defined XMLMutex objects, and lazy eval them
 * using atomic compare and swap. I somehow let it get by me that we don't
 * want any static/global objects at all.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:28  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:22  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define PLATFORM_EXPORT     __declspec(dllexport)
#define PLATFORM_IMPORT     __declspec(dllimport)

// ---------------------------------------------------------------------------
//  Indicate that we support native bools
// ---------------------------------------------------------------------------
// #define NO_NATIVE_BOOL

// ---------------------------------------------------------------------------
//  Define our version of the XML character
// ---------------------------------------------------------------------------
typedef wchar_t  XMLCh;

// ---------------------------------------------------------------------------
//  Force on the XML4C debug token if it was on in the build environment
// ---------------------------------------------------------------------------
#ifdef _DEBUG
#define XML4C_DEBUG
#endif

// ---------------------------------------------------------------------------
//  The name of the DLL as built by the Borland projects. At this time, it
//  does not use the versioning stuff.
// ---------------------------------------------------------------------------
const char* const XML4C_DLLName = "XercesLib;
<commit_msg>Updated the Borland compiler header for all of the recent changes and additions of stuff that needs to be defined per compiler.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.3  2000/01/25 23:07:34  roddey
 * Updated the Borland compiler header for all of the recent changes and
 * additions of stuff that needs to be defined per compiler.
 *
 * Revision 1.2  1999/12/02 19:02:57  roddey
 * Get rid of a few statically defined XMLMutex objects, and lazy eval them
 * using atomic compare and swap. I somehow let it get by me that we don't
 * want any static/global objects at all.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:28  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:22  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define PLATFORM_EXPORT     __declspec(dllexport)
#define PLATFORM_IMPORT     __declspec(dllimport)

// ---------------------------------------------------------------------------
//  Indicate that we support native bools
// ---------------------------------------------------------------------------
// #define NO_NATIVE_BOOL

// ---------------------------------------------------------------------------
//  We support L prefixed wide character constants
// ---------------------------------------------------------------------------
#define XML_LSTRSUPPORT

// ---------------------------------------------------------------------------
//  Define our version of the XML character
// ---------------------------------------------------------------------------
typedef wchar_t  XMLCh;

// ---------------------------------------------------------------------------
//  Define our version of a strict UTF16 character
// ---------------------------------------------------------------------------
typedef unsigned short  UTF16Ch;

// ---------------------------------------------------------------------------
//  Define unsigned 16 and 32 bits integers
// ---------------------------------------------------------------------------
typedef unsigned short  XMLUInt16;
typedef unsigned int    XMLUInt32;

// ---------------------------------------------------------------------------
//  Force on the XML4C debug token if it was on in the build environment
// ---------------------------------------------------------------------------
#ifdef _DEBUG
#define XML4C_DEBUG
#endif

// ---------------------------------------------------------------------------
//  The name of the DLL as built by the Borland projects. At this time, it
//  does not use the versioning stuff.
// ---------------------------------------------------------------------------
const char* const XML4C_DLLName = "XercesLib";
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: detreg.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 13:43:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include "scdetect.hxx"

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;

extern "C" {

SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
        const  sal_Char**   ppEnvironmentTypeName,
        uno_Environment**   /* ppEnvironment */           )
{
    *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
}

SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void*   /* pServiceManager */ ,
                                        void*   pRegistryKey    )
{
    Reference< ::registry::XRegistryKey >
            xKey( reinterpret_cast< ::registry::XRegistryKey* >( pRegistryKey ) ) ;

    OUString aDelimiter( RTL_CONSTASCII_USTRINGPARAM("/") );
    OUString aUnoServices( RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") );

    // Eigentliche Implementierung und ihre Services registrieren
    sal_Int32 i;
    Reference< ::registry::XRegistryKey >  xNewKey(xKey->createKey( aDelimiter + ScFilterDetect::impl_getStaticImplementationName() +
                               aUnoServices ));

    Sequence< OUString > aServices(ScFilterDetect::impl_getStaticSupportedServiceNames());
    for(i = 0; i < aServices.getLength(); i++ )
        xNewKey->createKey( aServices.getConstArray()[i] );

    return sal_True;
}

SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplementationName,
                                     void* pServiceManager,
                                     void* /* pRegistryKey */ )
{
    // Set default return value for this operation - if it failed.
    void* pReturn = NULL ;

    if  (
            ( pImplementationName   !=  NULL ) &&
            ( pServiceManager       !=  NULL )
        )
    {
        // Define variables which are used in following macros.
        Reference< XSingleServiceFactory >   xFactory                                                                                ;
        Reference< XMultiServiceFactory >    xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;

        if( ScFilterDetect::impl_getStaticImplementationName().equalsAscii( pImplementationName ) )
        {
            xFactory.set(::cppu::createSingleFactory( xServiceManager,
            ScFilterDetect::impl_getStaticImplementationName(),
            ScFilterDetect::impl_createInstance,
            ScFilterDetect::impl_getStaticSupportedServiceNames() ));
        }

        // Factory is valid - service was found.
        if ( xFactory.is() )
        {
            xFactory->acquire();
            pReturn = xFactory.get();
        }
    }

    // Return with result of this operation.
    return pReturn ;
}
} // extern "C"

<commit_msg>INTEGRATION: CWS impresstables2 (1.7.40); FILE MERGED 2007/07/30 14:39:33 cl 1.7.40.1: fixed namespace errors<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: detreg.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 13:19:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include "scdetect.hxx"

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;

extern "C" {

SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
        const  sal_Char**   ppEnvironmentTypeName,
        uno_Environment**   /* ppEnvironment */           )
{
    *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
}

SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void*   /* pServiceManager */ ,
                                        void*   pRegistryKey    )
{
    Reference< ::registry::XRegistryKey >
            xKey( reinterpret_cast< ::registry::XRegistryKey* >( pRegistryKey ) ) ;

    OUString aDelimiter( RTL_CONSTASCII_USTRINGPARAM("/") );
    OUString aUnoServices( RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") );

    // Eigentliche Implementierung und ihre Services registrieren
    sal_Int32 i;
    Reference< ::registry::XRegistryKey >  xNewKey(xKey->createKey( aDelimiter + ScFilterDetect::impl_getStaticImplementationName() +
                               aUnoServices ));

    Sequence< OUString > aServices(ScFilterDetect::impl_getStaticSupportedServiceNames());
    for(i = 0; i < aServices.getLength(); i++ )
        xNewKey->createKey( aServices.getConstArray()[i] );

    return sal_True;
}

SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplementationName,
                                     void* pServiceManager,
                                     void* /* pRegistryKey */ )
{
    // Set default return value for this operation - if it failed.
    void* pReturn = NULL ;

    if  (
            ( pImplementationName   !=  NULL ) &&
            ( pServiceManager       !=  NULL )
        )
    {
        // Define variables which are used in following macros.
        Reference< XSingleServiceFactory >   xFactory                                                                                ;
        Reference< XMultiServiceFactory >    xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;

        if( ScFilterDetect::impl_getStaticImplementationName().equalsAscii( pImplementationName ) )
        {
            xFactory.set(::cppu::createSingleFactory( xServiceManager,
            ScFilterDetect::impl_getStaticImplementationName(),
            ScFilterDetect::impl_createInstance,
            ScFilterDetect::impl_getStaticSupportedServiceNames() ));
        }

        // Factory is valid - service was found.
        if ( xFactory.is() )
        {
            xFactory->acquire();
            pReturn = xFactory.get();
        }
    }

    // Return with result of this operation.
    return pReturn ;
}
} // extern "C"

<|endoftext|>