<commit_before>extern "C" {

#include "LPC11U6x.h"
#define WEAK          __attribute__ ((weak))
#define ALIAS(f)      __attribute__ ((weak, alias (#f)))
#define AFTER_VECTORS __attribute__ ((section(".after_vectors")))void ResetISR(void);

// Patch the AEABI integer divide functions to use MCU's romdivide library
#ifdef __USE_ROMDIVIDE
// Location in memory that holds the address of the ROM Driver table
#define PTR_ROM_DRIVER_TABLE ((unsigned int *)(0x1FFF1FF8))
// Variables to store addresses of idiv and udiv functions within MCU ROM
unsigned int *pDivRom_idiv;
unsigned int *pDivRom_uidiv;
#endif

extern unsigned int __data_section_table;
extern unsigned int __data_section_table_end;
extern unsigned int __bss_section_table;
extern unsigned int __bss_section_table_end;

extern void __libc_init_array(void);
extern int main(void);
extern void _vStackTop(void);
extern void (* const g_pfnVectors[])(void);

     void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefaultHandler(void);

void PIN_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);
void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void I2C1_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART1_4_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART2_3_IRQHandler (void) ALIAS(IntDefaultHandler);
void SCT0_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
void I2C0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART0_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_FIQHandler (void) ALIAS(IntDefaultHandler);
void ADCA_IRQHandler (void) ALIAS(IntDefaultHandler);
void RTC_IRQHandler (void) ALIAS(IntDefaultHandler);
void BOD_WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);
void DMA_IRQHandler (void) ALIAS(IntDefaultHandler);
void ADCB_IRQHandler (void) ALIAS(IntDefaultHandler);
void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);

__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
	// Core Level - CM0
    &_vStackTop,                     // The initial stack pointer
    ResetISR,                        // The reset handler
    NMI_Handler,                     // The NMI handler
    HardFault_Handler,               // The hard fault handler
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    SVC_Handler,                     // SVCall handler
    0,                               // Reserved
    0,                               // Reserved
    PendSV_Handler,                  // The PendSV handler
    SysTick_Handler,                 // The SysTick handler

    // Chip Level - LPC11U68
    PIN_INT0_IRQHandler,             //  0 - GPIO pin interrupt 0
    PIN_INT1_IRQHandler,             //  1 - GPIO pin interrupt 1
    PIN_INT2_IRQHandler,             //  2 - GPIO pin interrupt 2
    PIN_INT3_IRQHandler,             //  3 - GPIO pin interrupt 3
    PIN_INT4_IRQHandler,             //  4 - GPIO pin interrupt 4
    PIN_INT5_IRQHandler,             //  5 - GPIO pin interrupt 5
    PIN_INT6_IRQHandler,             //  6 - GPIO pin interrupt 6
    PIN_INT7_IRQHandler,             //  7 - GPIO pin interrupt 7
    GINT0_IRQHandler,                //  8 - GPIO GROUP0 interrupt
    GINT1_IRQHandler,                //  9 - GPIO GROUP1 interrupt
    I2C1_IRQHandler,                 // 10 - I2C1
    USART1_4_IRQHandler,             // 11 - combined USART1 & 4 interrupt
    USART2_3_IRQHandler,             // 12 - combined USART2 & 3 interrupt
    SCT0_1_IRQHandler,               // 13 - combined SCT0 and 1 interrupt
    SSP1_IRQHandler,                 // 14 - SPI/SSP1 Interrupt
    I2C0_IRQHandler,                 // 15 - I2C0
    TIMER16_0_IRQHandler,            // 16 - CT16B0 (16-bit Timer 0)
    TIMER16_1_IRQHandler,            // 17 - CT16B1 (16-bit Timer 1)
    TIMER32_0_IRQHandler,            // 18 - CT32B0 (32-bit Timer 0)
    TIMER32_1_IRQHandler,            // 19 - CT32B1 (32-bit Timer 1)
    SSP0_IRQHandler,                 // 20 - SPI/SSP0 Interrupt
    USART0_IRQHandler,               // 21 - USART0
    USB_IRQHandler,                  // 22 - USB IRQ
    USB_FIQHandler,                  // 23 - USB FIQ
    ADCA_IRQHandler,                 // 24 - ADC A(A/D Converter)
    RTC_IRQHandler,                  // 25 - Real Time CLock interrpt
    BOD_WDT_IRQHandler,              // 25 - Combined Brownout/Watchdog interrupt
    FMC_IRQHandler,                  // 27 - IP2111 Flash Memory Controller
    DMA_IRQHandler,                  // 28 - DMA interrupt
    ADCB_IRQHandler,                 // 24 - ADC B (A/D Converter)
    USBWakeup_IRQHandler,            // 30 - USB wake-up interrupt
    0,                               // 31 - Reserved
};
/* End Vector */

AFTER_VECTORS void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
    unsigned int *pulDest = (unsigned int*) start;
    unsigned int *pulSrc = (unsigned int*) romstart;
    unsigned int loop;
    for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = *pulSrc++;
}

AFTER_VECTORS void bss_init(unsigned int start, unsigned int len) {
    unsigned int *pulDest = (unsigned int*) start;
    unsigned int loop;
    for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = 0;
}

/* Reset entry point*/
extern "C" void software_init_hook(void);
extern "C" void pre_main(void) __attribute__((weak));

AFTER_VECTORS void ResetISR(void) {
    unsigned int LoadAddr, ExeAddr, SectionLen;
    unsigned int *SectionTableAddr;

    SectionTableAddr = &__data_section_table;

    while (SectionTableAddr < &__data_section_table_end) {
        LoadAddr = *SectionTableAddr++;
        ExeAddr = *SectionTableAddr++;
        SectionLen = *SectionTableAddr++;
        data_init(LoadAddr, ExeAddr, SectionLen);
    }
    while (SectionTableAddr < &__bss_section_table_end) {
        ExeAddr = *SectionTableAddr++;
        SectionLen = *SectionTableAddr++;
        bss_init(ExeAddr, SectionLen);
    }

    // Patch the AEABI integer divide functions to use MCU's romdivide library
#ifdef __USE_ROMDIVIDE
    // Get address of Integer division routines function table in ROM
    unsigned int *div_ptr = (unsigned int *)((unsigned int *)*(PTR_ROM_DRIVER_TABLE))[4];
    // Get addresses of integer divide routines in ROM
    // These address are then used by the code in aeabi_romdiv_patch.s
    pDivRom_idiv = (unsigned int *)div_ptr[0];
    pDivRom_uidiv = (unsigned int *)div_ptr[1];
#endif

    SystemInit();
    if (pre_main)  { // give control to the RTOS
        software_init_hook();  // this will also call __libc_init_array
    }
    else {           // for BareMetal (non-RTOS) build
        __libc_init_array();
        main();
    }
    while (1) {;}
}

AFTER_VECTORS void NMI_Handler       (void) {}
AFTER_VECTORS void HardFault_Handler (void) {}
AFTER_VECTORS void MemManage_Handler (void) {}
AFTER_VECTORS void BusFault_Handler  (void) {}
AFTER_VECTORS void UsageFault_Handler(void) {}
AFTER_VECTORS void SVC_Handler       (void) {}
AFTER_VECTORS void DebugMon_Handler  (void) {}
AFTER_VECTORS void PendSV_Handler    (void) {}
AFTER_VECTORS void SysTick_Handler   (void) {}
AFTER_VECTORS void IntDefaultHandler (void) {}

int __aeabi_atexit(void *object, void (*destructor)(void *), void *dso_handle) {return 0;}
}
<commit_msg>Prevent multiple __aeabi_atexit definition linker error (GCC_CR)<commit_after>extern "C" {

#include "LPC11U6x.h"
#define WEAK          __attribute__ ((weak))
#define ALIAS(f)      __attribute__ ((weak, alias (#f)))
#define AFTER_VECTORS __attribute__ ((section(".after_vectors")))void ResetISR(void);

// Patch the AEABI integer divide functions to use MCU's romdivide library
#ifdef __USE_ROMDIVIDE
// Location in memory that holds the address of the ROM Driver table
#define PTR_ROM_DRIVER_TABLE ((unsigned int *)(0x1FFF1FF8))
// Variables to store addresses of idiv and udiv functions within MCU ROM
unsigned int *pDivRom_idiv;
unsigned int *pDivRom_uidiv;
#endif

extern unsigned int __data_section_table;
extern unsigned int __data_section_table_end;
extern unsigned int __bss_section_table;
extern unsigned int __bss_section_table_end;

extern void __libc_init_array(void);
extern int main(void);
extern void _vStackTop(void);
extern void (* const g_pfnVectors[])(void);

     void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefaultHandler(void);

void PIN_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIN_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);
void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void I2C1_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART1_4_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART2_3_IRQHandler (void) ALIAS(IntDefaultHandler);
void SCT0_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
void I2C0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
void USART0_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_FIQHandler (void) ALIAS(IntDefaultHandler);
void ADCA_IRQHandler (void) ALIAS(IntDefaultHandler);
void RTC_IRQHandler (void) ALIAS(IntDefaultHandler);
void BOD_WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);
void DMA_IRQHandler (void) ALIAS(IntDefaultHandler);
void ADCB_IRQHandler (void) ALIAS(IntDefaultHandler);
void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);

__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
	// Core Level - CM0
    &_vStackTop,                     // The initial stack pointer
    ResetISR,                        // The reset handler
    NMI_Handler,                     // The NMI handler
    HardFault_Handler,               // The hard fault handler
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    0,                               // Reserved
    SVC_Handler,                     // SVCall handler
    0,                               // Reserved
    0,                               // Reserved
    PendSV_Handler,                  // The PendSV handler
    SysTick_Handler,                 // The SysTick handler

    // Chip Level - LPC11U68
    PIN_INT0_IRQHandler,             //  0 - GPIO pin interrupt 0
    PIN_INT1_IRQHandler,             //  1 - GPIO pin interrupt 1
    PIN_INT2_IRQHandler,             //  2 - GPIO pin interrupt 2
    PIN_INT3_IRQHandler,             //  3 - GPIO pin interrupt 3
    PIN_INT4_IRQHandler,             //  4 - GPIO pin interrupt 4
    PIN_INT5_IRQHandler,             //  5 - GPIO pin interrupt 5
    PIN_INT6_IRQHandler,             //  6 - GPIO pin interrupt 6
    PIN_INT7_IRQHandler,             //  7 - GPIO pin interrupt 7
    GINT0_IRQHandler,                //  8 - GPIO GROUP0 interrupt
    GINT1_IRQHandler,                //  9 - GPIO GROUP1 interrupt
    I2C1_IRQHandler,                 // 10 - I2C1
    USART1_4_IRQHandler,             // 11 - combined USART1 & 4 interrupt
    USART2_3_IRQHandler,             // 12 - combined USART2 & 3 interrupt
    SCT0_1_IRQHandler,               // 13 - combined SCT0 and 1 interrupt
    SSP1_IRQHandler,                 // 14 - SPI/SSP1 Interrupt
    I2C0_IRQHandler,                 // 15 - I2C0
    TIMER16_0_IRQHandler,            // 16 - CT16B0 (16-bit Timer 0)
    TIMER16_1_IRQHandler,            // 17 - CT16B1 (16-bit Timer 1)
    TIMER32_0_IRQHandler,            // 18 - CT32B0 (32-bit Timer 0)
    TIMER32_1_IRQHandler,            // 19 - CT32B1 (32-bit Timer 1)
    SSP0_IRQHandler,                 // 20 - SPI/SSP0 Interrupt
    USART0_IRQHandler,               // 21 - USART0
    USB_IRQHandler,                  // 22 - USB IRQ
    USB_FIQHandler,                  // 23 - USB FIQ
    ADCA_IRQHandler,                 // 24 - ADC A(A/D Converter)
    RTC_IRQHandler,                  // 25 - Real Time CLock interrpt
    BOD_WDT_IRQHandler,              // 25 - Combined Brownout/Watchdog interrupt
    FMC_IRQHandler,                  // 27 - IP2111 Flash Memory Controller
    DMA_IRQHandler,                  // 28 - DMA interrupt
    ADCB_IRQHandler,                 // 24 - ADC B (A/D Converter)
    USBWakeup_IRQHandler,            // 30 - USB wake-up interrupt
    0,                               // 31 - Reserved
};
/* End Vector */

AFTER_VECTORS void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
    unsigned int *pulDest = (unsigned int*) start;
    unsigned int *pulSrc = (unsigned int*) romstart;
    unsigned int loop;
    for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = *pulSrc++;
}

AFTER_VECTORS void bss_init(unsigned int start, unsigned int len) {
    unsigned int *pulDest = (unsigned int*) start;
    unsigned int loop;
    for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = 0;
}

/* Reset entry point*/
extern "C" void software_init_hook(void);
extern "C" void pre_main(void) __attribute__((weak));

AFTER_VECTORS void ResetISR(void) {
    unsigned int LoadAddr, ExeAddr, SectionLen;
    unsigned int *SectionTableAddr;

    SectionTableAddr = &__data_section_table;

    while (SectionTableAddr < &__data_section_table_end) {
        LoadAddr = *SectionTableAddr++;
        ExeAddr = *SectionTableAddr++;
        SectionLen = *SectionTableAddr++;
        data_init(LoadAddr, ExeAddr, SectionLen);
    }
    while (SectionTableAddr < &__bss_section_table_end) {
        ExeAddr = *SectionTableAddr++;
        SectionLen = *SectionTableAddr++;
        bss_init(ExeAddr, SectionLen);
    }

    // Patch the AEABI integer divide functions to use MCU's romdivide library
#ifdef __USE_ROMDIVIDE
    // Get address of Integer division routines function table in ROM
    unsigned int *div_ptr = (unsigned int *)((unsigned int *)*(PTR_ROM_DRIVER_TABLE))[4];
    // Get addresses of integer divide routines in ROM
    // These address are then used by the code in aeabi_romdiv_patch.s
    pDivRom_idiv = (unsigned int *)div_ptr[0];
    pDivRom_uidiv = (unsigned int *)div_ptr[1];
#endif

    SystemInit();
    if (pre_main)  { // give control to the RTOS
        software_init_hook();  // this will also call __libc_init_array
    }
    else {           // for BareMetal (non-RTOS) build
        __libc_init_array();
        main();
    }
    while (1) {;}
}

AFTER_VECTORS void NMI_Handler       (void) {}
AFTER_VECTORS void HardFault_Handler (void) {}
AFTER_VECTORS void MemManage_Handler (void) {}
AFTER_VECTORS void BusFault_Handler  (void) {}
AFTER_VECTORS void UsageFault_Handler(void) {}
AFTER_VECTORS void SVC_Handler       (void) {}
AFTER_VECTORS void DebugMon_Handler  (void) {}
AFTER_VECTORS void PendSV_Handler    (void) {}
AFTER_VECTORS void SysTick_Handler   (void) {}
AFTER_VECTORS void IntDefaultHandler (void) {}
}
<|endoftext|>


<commit_before><commit_msg>coverity#708708 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: strings.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 10:38:24 $
 *
 *  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_xmloff.hxx"

#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#define XMLFORM_IMPLEMENT_STRINGS
#include "strings.hxx"
#undef XMLFORM_IMPLEMENT_STRINGS
#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.4.300); FILE MERGED 2008/03/31 16:28:13 rt 1.4.300.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: strings.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#define XMLFORM_IMPLEMENT_STRINGS
#include "strings.hxx"
#undef XMLFORM_IMPLEMENT_STRINGS
#endif

<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree.
 */
#include "FlipperClient.h"
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>
#include "ConnectionContextStore.h"
#include "FireAndForgetBasedFlipperResponder.h"
#include "FlipperConnectionImpl.h"
#include "FlipperConnectionManagerImpl.h"
#include "FlipperResponderImpl.h"
#include "FlipperState.h"
#include "FlipperStep.h"
#include "Log.h"
#if __ANDROID__
#include "utils/CallstackHelper.h"
#endif
#if __APPLE__
#include <execinfo.h>
#endif

#if FB_SONARKIT_ENABLED

namespace facebook {
namespace flipper {

static FlipperClient* kInstance;

using folly::dynamic;

void FlipperClient::init(FlipperInitConfig config) {
  auto state = std::make_shared<FlipperState>();
  auto context = std::make_shared<ConnectionContextStore>(config.deviceData);
  kInstance = new FlipperClient(
      std::make_unique<FlipperConnectionManagerImpl>(
          std::move(config), state, context),
      state);
}

FlipperClient* FlipperClient::instance() {
  return kInstance;
}

void FlipperClient::setStateListener(
    std::shared_ptr<FlipperStateUpdateListener> stateListener) {
  performAndReportError([this, &stateListener]() {
    log("Setting state listener");
    flipperState_->setUpdateListener(stateListener);
  });
}

void FlipperClient::addPlugin(std::shared_ptr<FlipperPlugin> plugin) {
  performAndReportError([this, plugin]() {
    log("FlipperClient::addPlugin " + plugin->identifier());
    auto step = flipperState_->start("Add plugin " + plugin->identifier());

    std::lock_guard<std::mutex> lock(mutex_);
    if (plugins_.find(plugin->identifier()) != plugins_.end()) {
      throw std::out_of_range(
          "plugin " + plugin->identifier() + " already added.");
    }
    plugins_[plugin->identifier()] = plugin;
    step->complete();
    if (connected_) {
      refreshPlugins();
      if (plugin->runInBackground()) {
        auto& conn = connections_[plugin->identifier()];
        conn = std::make_shared<FlipperConnectionImpl>(
            socket_.get(), plugin->identifier());
        plugin->didConnect(conn);
      }
    }
  });
}

void FlipperClient::removePlugin(std::shared_ptr<FlipperPlugin> plugin) {
  performAndReportError([this, plugin]() {
    log("FlipperClient::removePlugin " + plugin->identifier());

    std::lock_guard<std::mutex> lock(mutex_);
    if (plugins_.find(plugin->identifier()) == plugins_.end()) {
      throw std::out_of_range("plugin " + plugin->identifier() + " not added.");
    }
    disconnect(plugin);
    plugins_.erase(plugin->identifier());
    if (connected_) {
      refreshPlugins();
    }
  });
}

void FlipperClient::startBackgroundPlugins() {
  std::cout << "Activating Background Plugins..." << std::endl;
  for (std::map<std::string, std::shared_ptr<FlipperPlugin>>::iterator it =
           plugins_.begin();
       it != plugins_.end();
       ++it) {
    std::cout << it->first << std::endl;
    if (it->second.get()->runInBackground()) {
      auto& conn = connections_[it->first];
      conn = std::make_shared<FlipperConnectionImpl>(socket_.get(), it->first);
      it->second.get()->didConnect(conn);
    }
  }
}

std::shared_ptr<FlipperPlugin> FlipperClient::getPlugin(
    const std::string& identifier) {
  std::lock_guard<std::mutex> lock(mutex_);
  if (plugins_.find(identifier) == plugins_.end()) {
    return nullptr;
  }
  return plugins_.at(identifier);
}

bool FlipperClient::hasPlugin(const std::string& identifier) {
  std::lock_guard<std::mutex> lock(mutex_);
  return plugins_.find(identifier) != plugins_.end();
}

void FlipperClient::disconnect(std::shared_ptr<FlipperPlugin> plugin) {
  const auto& conn = connections_.find(plugin->identifier());
  if (conn != connections_.end()) {
    connections_.erase(plugin->identifier());
    plugin->didDisconnect();
  }
}

void FlipperClient::refreshPlugins() {
  performAndReportError([this]() {
    dynamic message = dynamic::object("method", "refreshPlugins");
    socket_->sendMessage(message);
  });
}

void FlipperClient::onConnected() {
  performAndReportError([this]() {
    log("FlipperClient::onConnected");

    std::lock_guard<std::mutex> lock(mutex_);
    connected_ = true;
    startBackgroundPlugins();
  });
}

void FlipperClient::onDisconnected() {
  performAndReportError([this]() {
    log("FlipperClient::onDisconnected");
    auto step = flipperState_->start("Trigger onDisconnected callbacks");
    std::lock_guard<std::mutex> lock(mutex_);
    connected_ = false;
    for (const auto& iter : plugins_) {
      disconnect(iter.second);
    }
    step->complete();
  });
}

void FlipperClient::onMessageReceived(
    const dynamic& message,
    std::unique_ptr<FlipperResponder> uniqueResponder) {
    // Convert to shared pointer so we can hold on to it while passing it to the plugin, and still use it
    // to respond with an error if we catch an exception.
    std::shared_ptr<FlipperResponder> responder = std::move(uniqueResponder);
  try {
    std::lock_guard<std::mutex> lock(mutex_);
    const auto& method = message["method"];
    const auto& params = message.getDefault("params");

    if (method == "getPlugins") {
      dynamic identifiers = dynamic::array();
      for (const auto& elem : plugins_) {
        identifiers.push_back(elem.first);
      }
      dynamic response = dynamic::object("plugins", identifiers);
      responder->success(response);
      return;
    }

    if (method == "init") {
      const auto identifier = params["plugin"].getString();
      if (plugins_.find(identifier) == plugins_.end()) {
        std::string errorMessage = "Plugin " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "PluginNotFound"));
        return;
      }
      const auto plugin = plugins_.at(identifier);
      if (!plugin.get()->runInBackground()) {
        auto& conn = connections_[plugin->identifier()];
        conn = std::make_shared<FlipperConnectionImpl>(
            socket_.get(), plugin->identifier());
        plugin->didConnect(conn);
      }
      return;
    }

    if (method == "deinit") {
      const auto identifier = params["plugin"].getString();
      if (plugins_.find(identifier) == plugins_.end()) {
        std::string errorMessage = "Plugin " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "PluginNotFound"));
        return;
      }
      const auto plugin = plugins_.at(identifier);
      if (!plugin.get()->runInBackground()) {
        disconnect(plugin);
      }
      return;
    }

    if (method == "execute") {
      const auto identifier = params["api"].getString();
      if (connections_.find(identifier) == connections_.end()) {
        std::string errorMessage = "Connection " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "ConnectionNotFound"));
        return;
      }
      const auto& conn = connections_.at(params["api"].getString());
      conn->call(
          params["method"].getString(),
          params.getDefault("params"),
          responder);
      return;
    }

    if (method == "isMethodSupported") {
      const auto identifier = params["api"].getString();
      if (connections_.find(identifier) == connections_.end()) {
        std::string errorMessage = "Connection " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "ConnectionNotFound"));
        return;
      }
      const auto& conn = connections_.at(params["api"].getString());
      bool isSupported = conn->hasReceiver(params["method"].getString());
      responder->success(dynamic::object("isSupported", isSupported));
      return;
    }

    dynamic response =
        dynamic::object("message", "Received unknown method: " + method);
    responder->error(response);
  } catch (std::exception& e) {
    log(std::string("Error: ") + e.what());
    if (responder) {
      responder->error(dynamic::object("message", e.what())(
          "stacktrace", callstack())("name", e.what()));
    }
  } catch (...) {
    log("Unknown error suppressed in FlipperClient");
    if (responder) {
      responder->error(dynamic::object(
          "message",
          "Unknown error during " + message["method"] + ". " +
              folly::toJson(message))("stacktrace", callstack())(
          "name", "Unknown"));
    }
  }
}

std::string FlipperClient::callstack() {
#if __APPLE__
  // For some iOS apps, __Unwind_Backtrace symbol wasn't found in sandcastle
  // builds, thus, for iOS apps, using backtrace c function.
  void* callstack[2048];
  int frames = backtrace(callstack, 2048);
  char** strs = backtrace_symbols(callstack, frames);
  std::string output = "";
  for (int i = 0; i < frames; ++i) {
    output.append(strs[i]);
    output.append("\n");
  }
  return output;
#elif __ANDROID__
  const size_t max = 2048;
  void* buffer[max];
  std::ostringstream oss;

  dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));
  std::string output = std::string(oss.str().c_str());
  return output;
#else
  return "";
#endif
}
void FlipperClient::performAndReportError(const std::function<void()>& func) {
#if FLIPPER_ENABLE_CRASH
  // To debug the stack trace and an exception turn on the compiler flag
  // FLIPPER_ENABLE_CRASH
  func();
#else
  try {
    func();
  } catch (std::exception& e) {
    handleError(e);
  } catch (std::exception* e) {
    if (e) {
      handleError(*e);
    }
  } catch (...) {
    // Generic catch block for the exception of type not belonging to
    // std::exception
    log("Unknown error suppressed in FlipperClient");
  }
#endif
}

void FlipperClient::handleError(std::exception& e) {
  if (connected_) {
    std::string callstack = this->callstack();
    dynamic message = dynamic::object(
        "error",
        dynamic::object("message", e.what())("stacktrace", callstack)(
            "name", e.what()));
    socket_->sendMessage(message);
  } else {
    log("Error: " + std::string(e.what()));
  }
}

std::string FlipperClient::getState() {
  return flipperState_->getState();
}

std::vector<StateElement> FlipperClient::getStateElements() {
  return flipperState_->getStateElements();
}

} // namespace flipper
} // namespace facebook

#endif
<commit_msg>Initialize instance to nullptr<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree.
 */
#include "FlipperClient.h"
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>
#include "ConnectionContextStore.h"
#include "FireAndForgetBasedFlipperResponder.h"
#include "FlipperConnectionImpl.h"
#include "FlipperConnectionManagerImpl.h"
#include "FlipperResponderImpl.h"
#include "FlipperState.h"
#include "FlipperStep.h"
#include "Log.h"
#if __ANDROID__
#include "utils/CallstackHelper.h"
#endif
#if __APPLE__
#include <execinfo.h>
#endif

#if FB_SONARKIT_ENABLED

namespace facebook {
namespace flipper {

static FlipperClient* kInstance{nullptr};

using folly::dynamic;

void FlipperClient::init(FlipperInitConfig config) {
  auto state = std::make_shared<FlipperState>();
  auto context = std::make_shared<ConnectionContextStore>(config.deviceData);
  kInstance = new FlipperClient(
      std::make_unique<FlipperConnectionManagerImpl>(
          std::move(config), state, context),
      state);
}

FlipperClient* FlipperClient::instance() {
  return kInstance;
}

void FlipperClient::setStateListener(
    std::shared_ptr<FlipperStateUpdateListener> stateListener) {
  performAndReportError([this, &stateListener]() {
    log("Setting state listener");
    flipperState_->setUpdateListener(stateListener);
  });
}

void FlipperClient::addPlugin(std::shared_ptr<FlipperPlugin> plugin) {
  performAndReportError([this, plugin]() {
    log("FlipperClient::addPlugin " + plugin->identifier());
    auto step = flipperState_->start("Add plugin " + plugin->identifier());

    std::lock_guard<std::mutex> lock(mutex_);
    if (plugins_.find(plugin->identifier()) != plugins_.end()) {
      throw std::out_of_range(
          "plugin " + plugin->identifier() + " already added.");
    }
    plugins_[plugin->identifier()] = plugin;
    step->complete();
    if (connected_) {
      refreshPlugins();
      if (plugin->runInBackground()) {
        auto& conn = connections_[plugin->identifier()];
        conn = std::make_shared<FlipperConnectionImpl>(
            socket_.get(), plugin->identifier());
        plugin->didConnect(conn);
      }
    }
  });
}

void FlipperClient::removePlugin(std::shared_ptr<FlipperPlugin> plugin) {
  performAndReportError([this, plugin]() {
    log("FlipperClient::removePlugin " + plugin->identifier());

    std::lock_guard<std::mutex> lock(mutex_);
    if (plugins_.find(plugin->identifier()) == plugins_.end()) {
      throw std::out_of_range("plugin " + plugin->identifier() + " not added.");
    }
    disconnect(plugin);
    plugins_.erase(plugin->identifier());
    if (connected_) {
      refreshPlugins();
    }
  });
}

void FlipperClient::startBackgroundPlugins() {
  std::cout << "Activating Background Plugins..." << std::endl;
  for (std::map<std::string, std::shared_ptr<FlipperPlugin>>::iterator it =
           plugins_.begin();
       it != plugins_.end();
       ++it) {
    std::cout << it->first << std::endl;
    if (it->second.get()->runInBackground()) {
      auto& conn = connections_[it->first];
      conn = std::make_shared<FlipperConnectionImpl>(socket_.get(), it->first);
      it->second.get()->didConnect(conn);
    }
  }
}

std::shared_ptr<FlipperPlugin> FlipperClient::getPlugin(
    const std::string& identifier) {
  std::lock_guard<std::mutex> lock(mutex_);
  if (plugins_.find(identifier) == plugins_.end()) {
    return nullptr;
  }
  return plugins_.at(identifier);
}

bool FlipperClient::hasPlugin(const std::string& identifier) {
  std::lock_guard<std::mutex> lock(mutex_);
  return plugins_.find(identifier) != plugins_.end();
}

void FlipperClient::disconnect(std::shared_ptr<FlipperPlugin> plugin) {
  const auto& conn = connections_.find(plugin->identifier());
  if (conn != connections_.end()) {
    connections_.erase(plugin->identifier());
    plugin->didDisconnect();
  }
}

void FlipperClient::refreshPlugins() {
  performAndReportError([this]() {
    dynamic message = dynamic::object("method", "refreshPlugins");
    socket_->sendMessage(message);
  });
}

void FlipperClient::onConnected() {
  performAndReportError([this]() {
    log("FlipperClient::onConnected");

    std::lock_guard<std::mutex> lock(mutex_);
    connected_ = true;
    startBackgroundPlugins();
  });
}

void FlipperClient::onDisconnected() {
  performAndReportError([this]() {
    log("FlipperClient::onDisconnected");
    auto step = flipperState_->start("Trigger onDisconnected callbacks");
    std::lock_guard<std::mutex> lock(mutex_);
    connected_ = false;
    for (const auto& iter : plugins_) {
      disconnect(iter.second);
    }
    step->complete();
  });
}

void FlipperClient::onMessageReceived(
    const dynamic& message,
    std::unique_ptr<FlipperResponder> uniqueResponder) {
    // Convert to shared pointer so we can hold on to it while passing it to the plugin, and still use it
    // to respond with an error if we catch an exception.
    std::shared_ptr<FlipperResponder> responder = std::move(uniqueResponder);
  try {
    std::lock_guard<std::mutex> lock(mutex_);
    const auto& method = message["method"];
    const auto& params = message.getDefault("params");

    if (method == "getPlugins") {
      dynamic identifiers = dynamic::array();
      for (const auto& elem : plugins_) {
        identifiers.push_back(elem.first);
      }
      dynamic response = dynamic::object("plugins", identifiers);
      responder->success(response);
      return;
    }

    if (method == "init") {
      const auto identifier = params["plugin"].getString();
      if (plugins_.find(identifier) == plugins_.end()) {
        std::string errorMessage = "Plugin " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "PluginNotFound"));
        return;
      }
      const auto plugin = plugins_.at(identifier);
      if (!plugin.get()->runInBackground()) {
        auto& conn = connections_[plugin->identifier()];
        conn = std::make_shared<FlipperConnectionImpl>(
            socket_.get(), plugin->identifier());
        plugin->didConnect(conn);
      }
      return;
    }

    if (method == "deinit") {
      const auto identifier = params["plugin"].getString();
      if (plugins_.find(identifier) == plugins_.end()) {
        std::string errorMessage = "Plugin " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "PluginNotFound"));
        return;
      }
      const auto plugin = plugins_.at(identifier);
      if (!plugin.get()->runInBackground()) {
        disconnect(plugin);
      }
      return;
    }

    if (method == "execute") {
      const auto identifier = params["api"].getString();
      if (connections_.find(identifier) == connections_.end()) {
        std::string errorMessage = "Connection " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "ConnectionNotFound"));
        return;
      }
      const auto& conn = connections_.at(params["api"].getString());
      conn->call(
          params["method"].getString(),
          params.getDefault("params"),
          responder);
      return;
    }

    if (method == "isMethodSupported") {
      const auto identifier = params["api"].getString();
      if (connections_.find(identifier) == connections_.end()) {
        std::string errorMessage = "Connection " + identifier +
            " not found for method " + method.getString();
        log(errorMessage);
        responder->error(folly::dynamic::object("message", errorMessage)(
            "name", "ConnectionNotFound"));
        return;
      }
      const auto& conn = connections_.at(params["api"].getString());
      bool isSupported = conn->hasReceiver(params["method"].getString());
      responder->success(dynamic::object("isSupported", isSupported));
      return;
    }

    dynamic response =
        dynamic::object("message", "Received unknown method: " + method);
    responder->error(response);
  } catch (std::exception& e) {
    log(std::string("Error: ") + e.what());
    if (responder) {
      responder->error(dynamic::object("message", e.what())(
          "stacktrace", callstack())("name", e.what()));
    }
  } catch (...) {
    log("Unknown error suppressed in FlipperClient");
    if (responder) {
      responder->error(dynamic::object(
          "message",
          "Unknown error during " + message["method"] + ". " +
              folly::toJson(message))("stacktrace", callstack())(
          "name", "Unknown"));
    }
  }
}

std::string FlipperClient::callstack() {
#if __APPLE__
  // For some iOS apps, __Unwind_Backtrace symbol wasn't found in sandcastle
  // builds, thus, for iOS apps, using backtrace c function.
  void* callstack[2048];
  int frames = backtrace(callstack, 2048);
  char** strs = backtrace_symbols(callstack, frames);
  std::string output = "";
  for (int i = 0; i < frames; ++i) {
    output.append(strs[i]);
    output.append("\n");
  }
  return output;
#elif __ANDROID__
  const size_t max = 2048;
  void* buffer[max];
  std::ostringstream oss;

  dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));
  std::string output = std::string(oss.str().c_str());
  return output;
#else
  return "";
#endif
}
void FlipperClient::performAndReportError(const std::function<void()>& func) {
#if FLIPPER_ENABLE_CRASH
  // To debug the stack trace and an exception turn on the compiler flag
  // FLIPPER_ENABLE_CRASH
  func();
#else
  try {
    func();
  } catch (std::exception& e) {
    handleError(e);
  } catch (std::exception* e) {
    if (e) {
      handleError(*e);
    }
  } catch (...) {
    // Generic catch block for the exception of type not belonging to
    // std::exception
    log("Unknown error suppressed in FlipperClient");
  }
#endif
}

void FlipperClient::handleError(std::exception& e) {
  if (connected_) {
    std::string callstack = this->callstack();
    dynamic message = dynamic::object(
        "error",
        dynamic::object("message", e.what())("stacktrace", callstack)(
            "name", e.what()));
    socket_->sendMessage(message);
  } else {
    log("Error: " + std::string(e.what()));
  }
}

std::string FlipperClient::getState() {
  return flipperState_->getState();
}

std::vector<StateElement> FlipperClient::getStateElements() {
  return flipperState_->getStateElements();
}

} // namespace flipper
} // namespace facebook

#endif
<|endoftext|>


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

#include <android/log.h>
#include <jni.h>

#include <array>
#include <cstdlib>
#include <cstring>

#include "include/flac_parser.h"

#define LOG_TAG "flac_jni"
#define ALOGE(...) \
  ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define ALOGV(...) \
  ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))

#define DECODER_FUNC(RETURN_TYPE, NAME, ...)                             \
  extern "C" {                                                           \
  JNIEXPORT RETURN_TYPE                                                  \
      Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
          JNIEnv *env, jobject thiz, ##__VA_ARGS__);                     \
  }                                                                      \
  JNIEXPORT RETURN_TYPE                                                  \
      Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
          JNIEnv *env, jobject thiz, ##__VA_ARGS__)

class JavaDataSource : public DataSource {
 public:
  void setFlacDecoderJni(JNIEnv *env, jobject flacDecoderJni) {
    this->env = env;
    this->flacDecoderJni = flacDecoderJni;
    if (mid == NULL) {
      jclass cls = env->GetObjectClass(flacDecoderJni);
      mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
      env->DeleteLocalRef(cls);
    }
  }

  ssize_t readAt(off64_t offset, void *const data, size_t size) {
    jobject byteBuffer = env->NewDirectByteBuffer(data, size);
    int result = env->CallIntMethod(flacDecoderJni, mid, byteBuffer);
    if (env->ExceptionCheck()) {
      // Exception is thrown in Java when returning from the native call.
      result = -1;
    }
    env->DeleteLocalRef(byteBuffer);
    return result;
  }

 private:
  JNIEnv *env;
  jobject flacDecoderJni;
  jmethodID mid;
};

struct Context {
  JavaDataSource *source;
  FLACParser *parser;

  Context() {
    source = new JavaDataSource();
    parser = new FLACParser(source);
  }

  ~Context() {
    delete parser;
    delete source;
  }
};

DECODER_FUNC(jlong, flacInit) {
  Context *context = new Context;
  if (!context->parser->init()) {
    delete context;
    return 0;
  }
  return reinterpret_cast<intptr_t>(context);
}

DECODER_FUNC(jobject, flacDecodeMetadata, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  if (!context->parser->decodeMetadata()) {
    return NULL;
  }

  jclass arrayListClass = env->FindClass("java/util/ArrayList");
  jmethodID arrayListConstructor =
      env->GetMethodID(arrayListClass, "<init>", "()V");
  jobject commentList = env->NewObject(arrayListClass, arrayListConstructor);
  jmethodID arrayListAddMethod =
      env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");

  if (context->parser->areVorbisCommentsValid()) {
    std::vector<std::string> vorbisComments =
        context->parser->getVorbisComments();
    for (std::vector<std::string>::const_iterator vorbisComment =
             vorbisComments.begin();
         vorbisComment != vorbisComments.end(); ++vorbisComment) {
      jstring commentString = env->NewStringUTF((*vorbisComment).c_str());
      env->CallBooleanMethod(commentList, arrayListAddMethod, commentString);
      env->DeleteLocalRef(commentString);
    }
  }

  jobject pictureFrames = env->NewObject(arrayListClass, arrayListConstructor);
  bool picturesValid = context->parser->arePicturesValid();
  if (picturesValid) {
    std::vector<FlacPicture> pictures = context->parser->getPictures();
    jclass pictureFrameClass = env->FindClass(
        "com/google/android/exoplayer2/metadata/flac/PictureFrame");
    jmethodID pictureFrameConstructor =
        env->GetMethodID(pictureFrameClass, "<init>",
                         "(ILjava/lang/String;Ljava/lang/String;IIII[B)V");
    for (std::vector<FlacPicture>::const_iterator picture = pictures.begin();
         picture != pictures.end(); ++picture) {
      jstring mimeType = env->NewStringUTF(picture->mimeType.c_str());
      jstring description = env->NewStringUTF(picture->description.c_str());
      jbyteArray pictureData = env->NewByteArray(picture->data.size());
      env->SetByteArrayRegion(pictureData, 0, picture->data.size(),
                              (signed char *)&picture->data[0]);
      jobject pictureFrame = env->NewObject(
          pictureFrameClass, pictureFrameConstructor, picture->type, mimeType,
          description, picture->width, picture->height, picture->depth,
          picture->colors, pictureData);
      env->CallBooleanMethod(pictureFrames, arrayListAddMethod, pictureFrame);
      env->DeleteLocalRef(mimeType);
      env->DeleteLocalRef(description);
      env->DeleteLocalRef(pictureData);
    }
  }

  const FLAC__StreamMetadata_StreamInfo &streamInfo =
      context->parser->getStreamInfo();

  jclass flacStreamMetadataClass = env->FindClass(
      "com/google/android/exoplayer2/extractor/"
      "FlacStreamMetadata");
  jmethodID flacStreamMetadataConstructor =
      env->GetMethodID(flacStreamMetadataClass, "<init>",
                       "(IIIIIIIJLjava/util/ArrayList;Ljava/util/ArrayList;)V");

  return env->NewObject(flacStreamMetadataClass, flacStreamMetadataConstructor,
                        streamInfo.min_blocksize, streamInfo.max_blocksize,
                        streamInfo.min_framesize, streamInfo.max_framesize,
                        streamInfo.sample_rate, streamInfo.channels,
                        streamInfo.bits_per_sample, streamInfo.total_samples,
                        commentList, pictureFrames);
}

DECODER_FUNC(jint, flacDecodeToBuffer, jlong jContext, jobject jOutputBuffer) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer);
  jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer);
  return context->parser->readBuffer(outputBuffer, outputSize);
}

DECODER_FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL);
  jint outputSize = env->GetArrayLength(jOutputArray);
  int count = context->parser->readBuffer(outputBuffer, outputSize);
  env->ReleaseByteArrayElements(jOutputArray, outputBuffer, 0);
  return count;
}

DECODER_FUNC(jlong, flacGetDecodePosition, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getDecodePosition();
}

DECODER_FUNC(jlong, flacGetLastFrameTimestamp, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getLastFrameTimestamp();
}

DECODER_FUNC(jlong, flacGetLastFrameFirstSampleIndex, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getLastFrameFirstSampleIndex();
}

DECODER_FUNC(jlong, flacGetNextFrameFirstSampleIndex, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getNextFrameFirstSampleIndex();
}

DECODER_FUNC(jboolean, flacGetSeekPoints, jlong jContext, jlong timeUs,
             jlongArray outSeekPoints) {
  Context *context = reinterpret_cast<Context *>(jContext);
  std::array<int64_t, 4> result;
  bool success = context->parser->getSeekPositions(timeUs, result);
  if (success) {
    env->SetLongArrayRegion(outSeekPoints, 0, result.size(), result.data());
  }
  return success;
}

DECODER_FUNC(jstring, flacGetStateString, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  const char *str = context->parser->getDecoderStateString();
  return env->NewStringUTF(str);
}

DECODER_FUNC(jboolean, flacIsDecoderAtEndOfStream, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->isDecoderAtEndOfStream();
}

DECODER_FUNC(void, flacFlush, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->parser->flush();
}

DECODER_FUNC(void, flacReset, jlong jContext, jlong newPosition) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->parser->reset(newPosition);
}

DECODER_FUNC(void, flacRelease, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  delete context;
}
<commit_msg>Fix flac extension<commit_after>/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <android/log.h>
#include <jni.h>

#include <array>
#include <cstdlib>
#include <cstring>

#include "include/flac_parser.h"

#define LOG_TAG "flac_jni"
#define ALOGE(...) \
  ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define ALOGV(...) \
  ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))

#define DECODER_FUNC(RETURN_TYPE, NAME, ...)                             \
  extern "C" {                                                           \
  JNIEXPORT RETURN_TYPE                                                  \
      Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
          JNIEnv *env, jobject thiz, ##__VA_ARGS__);                     \
  }                                                                      \
  JNIEXPORT RETURN_TYPE                                                  \
      Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME( \
          JNIEnv *env, jobject thiz, ##__VA_ARGS__)

class JavaDataSource : public DataSource {
 public:
  void setFlacDecoderJni(JNIEnv *env, jobject flacDecoderJni) {
    this->env = env;
    this->flacDecoderJni = flacDecoderJni;
    if (mid == NULL) {
      jclass cls = env->GetObjectClass(flacDecoderJni);
      mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
      env->DeleteLocalRef(cls);
    }
  }

  ssize_t readAt(off64_t offset, void *const data, size_t size) {
    jobject byteBuffer = env->NewDirectByteBuffer(data, size);
    int result = env->CallIntMethod(flacDecoderJni, mid, byteBuffer);
    if (env->ExceptionCheck()) {
      // Exception is thrown in Java when returning from the native call.
      result = -1;
    }
    env->DeleteLocalRef(byteBuffer);
    return result;
  }

 private:
  JNIEnv *env;
  jobject flacDecoderJni;
  jmethodID mid;
};

struct Context {
  JavaDataSource *source;
  FLACParser *parser;

  Context() {
    source = new JavaDataSource();
    parser = new FLACParser(source);
  }

  ~Context() {
    delete parser;
    delete source;
  }
};

DECODER_FUNC(jlong, flacInit) {
  Context *context = new Context;
  if (!context->parser->init()) {
    delete context;
    return 0;
  }
  return reinterpret_cast<intptr_t>(context);
}

DECODER_FUNC(jobject, flacDecodeMetadata, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  if (!context->parser->decodeMetadata()) {
    return NULL;
  }

  jclass arrayListClass = env->FindClass("java/util/ArrayList");
  jmethodID arrayListConstructor =
      env->GetMethodID(arrayListClass, "<init>", "()V");
  jobject commentList = env->NewObject(arrayListClass, arrayListConstructor);
  jmethodID arrayListAddMethod =
      env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");

  if (context->parser->areVorbisCommentsValid()) {
    std::vector<std::string> vorbisComments =
        context->parser->getVorbisComments();
    for (std::vector<std::string>::const_iterator vorbisComment =
             vorbisComments.begin();
         vorbisComment != vorbisComments.end(); ++vorbisComment) {
      jstring commentString = env->NewStringUTF((*vorbisComment).c_str());
      env->CallBooleanMethod(commentList, arrayListAddMethod, commentString);
      env->DeleteLocalRef(commentString);
    }
  }

  jobject pictureFrames = env->NewObject(arrayListClass, arrayListConstructor);
  bool picturesValid = context->parser->arePicturesValid();
  if (picturesValid) {
    std::vector<FlacPicture> pictures = context->parser->getPictures();
    jclass pictureFrameClass = env->FindClass(
        "com/google/android/exoplayer2/metadata/vorbis/PictureFrame");
    jmethodID pictureFrameConstructor =
        env->GetMethodID(pictureFrameClass, "<init>",
                         "(ILjava/lang/String;Ljava/lang/String;IIII[B)V");
    for (std::vector<FlacPicture>::const_iterator picture = pictures.begin();
         picture != pictures.end(); ++picture) {
      jstring mimeType = env->NewStringUTF(picture->mimeType.c_str());
      jstring description = env->NewStringUTF(picture->description.c_str());
      jbyteArray pictureData = env->NewByteArray(picture->data.size());
      env->SetByteArrayRegion(pictureData, 0, picture->data.size(),
                              (signed char *)&picture->data[0]);
      jobject pictureFrame = env->NewObject(
          pictureFrameClass, pictureFrameConstructor, picture->type, mimeType,
          description, picture->width, picture->height, picture->depth,
          picture->colors, pictureData);
      env->CallBooleanMethod(pictureFrames, arrayListAddMethod, pictureFrame);
      env->DeleteLocalRef(mimeType);
      env->DeleteLocalRef(description);
      env->DeleteLocalRef(pictureData);
    }
  }

  const FLAC__StreamMetadata_StreamInfo &streamInfo =
      context->parser->getStreamInfo();

  jclass flacStreamMetadataClass = env->FindClass(
      "com/google/android/exoplayer2/extractor/"
      "FlacStreamMetadata");
  jmethodID flacStreamMetadataConstructor =
      env->GetMethodID(flacStreamMetadataClass, "<init>",
                       "(IIIIIIIJLjava/util/ArrayList;Ljava/util/ArrayList;)V");

  return env->NewObject(flacStreamMetadataClass, flacStreamMetadataConstructor,
                        streamInfo.min_blocksize, streamInfo.max_blocksize,
                        streamInfo.min_framesize, streamInfo.max_framesize,
                        streamInfo.sample_rate, streamInfo.channels,
                        streamInfo.bits_per_sample, streamInfo.total_samples,
                        commentList, pictureFrames);
}

DECODER_FUNC(jint, flacDecodeToBuffer, jlong jContext, jobject jOutputBuffer) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer);
  jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer);
  return context->parser->readBuffer(outputBuffer, outputSize);
}

DECODER_FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->source->setFlacDecoderJni(env, thiz);
  jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL);
  jint outputSize = env->GetArrayLength(jOutputArray);
  int count = context->parser->readBuffer(outputBuffer, outputSize);
  env->ReleaseByteArrayElements(jOutputArray, outputBuffer, 0);
  return count;
}

DECODER_FUNC(jlong, flacGetDecodePosition, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getDecodePosition();
}

DECODER_FUNC(jlong, flacGetLastFrameTimestamp, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getLastFrameTimestamp();
}

DECODER_FUNC(jlong, flacGetLastFrameFirstSampleIndex, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getLastFrameFirstSampleIndex();
}

DECODER_FUNC(jlong, flacGetNextFrameFirstSampleIndex, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->getNextFrameFirstSampleIndex();
}

DECODER_FUNC(jboolean, flacGetSeekPoints, jlong jContext, jlong timeUs,
             jlongArray outSeekPoints) {
  Context *context = reinterpret_cast<Context *>(jContext);
  std::array<int64_t, 4> result;
  bool success = context->parser->getSeekPositions(timeUs, result);
  if (success) {
    env->SetLongArrayRegion(outSeekPoints, 0, result.size(), result.data());
  }
  return success;
}

DECODER_FUNC(jstring, flacGetStateString, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  const char *str = context->parser->getDecoderStateString();
  return env->NewStringUTF(str);
}

DECODER_FUNC(jboolean, flacIsDecoderAtEndOfStream, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  return context->parser->isDecoderAtEndOfStream();
}

DECODER_FUNC(void, flacFlush, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->parser->flush();
}

DECODER_FUNC(void, flacReset, jlong jContext, jlong newPosition) {
  Context *context = reinterpret_cast<Context *>(jContext);
  context->parser->reset(newPosition);
}

DECODER_FUNC(void, flacRelease, jlong jContext) {
  Context *context = reinterpret_cast<Context *>(jContext);
  delete context;
}
<|endoftext|>


<commit_before>
#include "gtest/gtest.h"

#include <iostream>

#include <lua.hpp>

#include <BT/BehaviorLuaFactory.hpp>

using namespace BT;

int printOut(lua_State* L)
{
    const char* str = lua_tostring(L, 1);

    std::cout << str << std::endl;

    return 0;
}

int a0 = 0;
int a1 = 0;
int a2 = 0;

int activate0(lua_State* L)
{
    ++a0;
    return 0;
}

int activate1(lua_State* L)
{
    ++a1;
    return 0;
}

int activate2(lua_State* L)
{
    ++a2;
    return 0;
}

struct A
{
    A() :
    state(0)
    {}

    int state;
};

int setState(lua_State* L)
{
    A* a = *((A**)lua_getextraspace(L));
    a->state = lua_tointeger(L, -1);

    return 0;
}

TEST(BehaviorLuaFactory, Factory)
{
    BehaviorLuaFactory blf(false);

    blf.exposeFunction(printOut, "printOut");
    blf.exposeFunction(activate0, "activate0");
    blf.exposeFunction(activate1, "activate1");
    blf.exposeFunction(activate2, "activate2");

    {
        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript.lua");
        ASSERT_TRUE(tree);

        tree->activate();

        EXPECT_EQ(1, a0);
        EXPECT_EQ(1, a1);
        EXPECT_EQ(1, a2);

        tree->activate();

        EXPECT_EQ(2, a0);
        EXPECT_EQ(2, a1);
        EXPECT_EQ(2, a2);
    }

    a0 = 0;
    {
        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript2.lua");
        ASSERT_TRUE(tree);

        tree->activate();

        EXPECT_EQ(1, a0);
    }

    {
        A a{};
        *((A**)lua_getextraspace(blf.getLuaState())) = &a;

        EXPECT_EQ(0, a.state);

        blf.exposeFunction(setState, "setState");

        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript3.lua");
        ASSERT_TRUE(tree);

        EXPECT_EQ(tree->activate().stateType, BehaviorNode::State::READY_SUCCESS);

        EXPECT_EQ(1, a.state);
    }
}

<commit_msg>Minor fixes in UnitTest<commit_after>
#include "gtest/gtest.h"

#include <iostream>

#include <lua.hpp>

#include <BT/BehaviorLuaFactory.hpp>

using namespace BT;

int printOut(lua_State* L)
{
    const char* str = lua_tostring(L, 1);

    std::cout << str << std::endl;

    return 0;
}

int a0 = 0;
int a1 = 0;
int a2 = 0;

int activate0(lua_State* L)
{
    ++a0;
    return 0;
}

int activate1(lua_State* L)
{
    ++a1;
    return 0;
}

int activate2(lua_State* L)
{
    ++a2;
    return 0;
}

struct A
{
    A() :
    state(0)
    {}

    int state;
};

int setState(lua_State* L)
{
    A* a = *((A**)lua_getextraspace(L));
    a->state = lua_tointeger(L, -1);

    return 0;
}

TEST(BehaviorLuaFactory, Factory)
{
    BehaviorLuaFactory blf(false);

    blf.exposeFunction(printOut, "printOut");
    blf.exposeFunction(activate0, "activate0");
    blf.exposeFunction(activate1, "activate1");
    blf.exposeFunction(activate2, "activate2");

    {
        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript.lua");
        ASSERT_TRUE(tree);

        EXPECT_EQ(tree->activate().stateType, BehaviorNode::State::READY_SUCCESS);

        EXPECT_EQ(1, a0);
        EXPECT_EQ(1, a1);
        EXPECT_EQ(1, a2);

        EXPECT_EQ(tree->activate().stateType, BehaviorNode::State::READY_SUCCESS);

        EXPECT_EQ(2, a0);
        EXPECT_EQ(2, a1);
        EXPECT_EQ(2, a2);
    }

    a0 = 0;
    {
        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript2.lua");
        ASSERT_TRUE(tree);

        EXPECT_EQ(tree->activate().stateType, BehaviorNode::State::READY_SUCCESS);

        EXPECT_EQ(1, a0);
    }

    {
        A a{};
        *((A**)lua_getextraspace(blf.getLuaState())) = &a;

        EXPECT_EQ(0, a.state);

        blf.exposeFunction(setState, "setState");

        BehaviorNode::Ptr tree = blf.createTreeFromFile("TestLuaFactoryScript3.lua");
        ASSERT_TRUE(tree);

        EXPECT_EQ(tree->activate().stateType, BehaviorNode::State::READY_SUCCESS);

        EXPECT_EQ(1, a.state);
    }
}

<|endoftext|>


<commit_before><commit_msg>cv: background model update stuff<commit_after><|endoftext|>


<commit_before>#pragma once

#include "rapidcheck/gen/Tuple.h"
#include "rapidcheck/detail/ApplyTuple.h"

namespace rc {
namespace gen {
namespace detail {

// Member variables
template <typename Type, typename T>
class Lens<T(Type::*)> {
public:
  typedef T(Type::*MemberPtr);
  typedef Type Target;
  typedef T ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    obj.*m_ptr = std::move(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with single argument
template <typename Type, typename Ret, typename T>
class Lens<Ret (Type::*)(T)> {
public:
  typedef Ret (Type::*MemberPtr)(T);
  typedef Type Target;
  typedef Decay<T> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    (obj.*m_ptr)(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with multiple arguments
template <typename Type, typename Ret, typename T1, typename T2, typename... Ts>
class Lens<Ret (Type::*)(T1, T2, Ts...)> {
public:
  typedef Ret (Type::*MemberPtr)(T1, T2, Ts...);
  typedef Type Target;
  typedef std::tuple<Decay<T1>, Decay<T2>, Decay<Ts>...> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    rc::detail::applyTuple(
        std::forward<Arg>(arg),
        [&](Decay<T1> &&arg1, Decay<T2> &&arg2, Decay<Ts> &&... args) {
          (obj.*m_ptr)(std::move(arg1), std::move(arg2), std::move(args)...);
        });
  }

private:
  MemberPtr m_ptr;
};

template <typename Member, typename SourceType>
struct Binding {
  Binding(Lens<Member> &&l, Gen<SourceType> &&g)
      : lens(std::move(l))
      , gen(std::move(g)) {}

  Lens<Member> lens;
  Gen<SourceType> gen;
};

template <typename T>
T &deref(T &x) {
  return x;
}

template <typename T>
T &deref(std::unique_ptr<T> &x) {
  return *x;
}

template <typename T>
T &deref(std::shared_ptr<T> &x) {
  return *x;
}

template <typename T, typename Indexes, typename... Lenses>
class BuildMapper;

template <typename T, typename... Lenses, std::size_t... Indexes>
class BuildMapper<T, rc::detail::IndexSequence<Indexes...>, Lenses...> {
public:
  BuildMapper(const Lenses &... lenses)
      : m_lenses(lenses...) {}

  T operator()(std::tuple<T, typename Lenses::ValueType...> &&tuple) const {
    T &obj = std::get<0>(tuple);
    auto dummy = {(std::get<Indexes>(m_lenses).set(
                       deref(obj), std::move(std::get<Indexes + 1>(tuple))),
                   0)...};
    (void)dummy; // Silence warning

    return std::move(obj);
  }

private:
  std::tuple<Lenses...> m_lenses;
};

} // namespace detail

template <typename T, typename... Args>
Gen<T> construct(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) { return T(std::move(args)...); });
                  });
}

template <typename T, typename Arg, typename... Args>
Gen<T> construct() {
  return gen::construct<T>(gen::arbitrary<Arg>(), gen::arbitrary<Args>()...);
}

template <typename T, typename... Args>
Gen<std::unique_ptr<T>> makeUnique(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) {
                          return std::unique_ptr<T>(new T(std::move(args)...));
                        });
                  });
}

template <typename T, typename... Args>
Gen<std::shared_ptr<T>> makeShared(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(std::move(argsTuple),
                                                  [](Args &&... args) {
                                                    return std::make_shared<T>(
                                                        std::move(args)...);
                                                  });
                  });
}

template <typename Member, typename T>
detail::Binding<Member, T> set(Member member, Gen<T> gen) {
  return detail::Binding<Member, T>(detail::Lens<Member>(member),
                                    std::move(gen));
}

template <typename Member>
detail::Binding<Member, typename detail::Lens<Member>::ValueType>
set(Member member) {
  using T = typename detail::Lens<Member>::ValueType;
  return set(member, gen::arbitrary<T>());
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(Gen<T> gen, const detail::Binding<Members, SourceTypes> &... bs) {
  using Mapper =
      detail::BuildMapper<T,
                          rc::detail::MakeIndexSequence<sizeof...(Members)>,
                          detail::Lens<Members>...>;

  // GCC HACK - Variadics + lambdas don't work very well in GCC so we use an old
  // fashioned function object (the Mapper thing) to prevent GCC from crashing.
  // Use lambdas and applyTuple once we drop support for the crashing ones.
  return gen::map(gen::tuple(std::move(gen), std::move(bs.gen)...),
                  Mapper(bs.lens...));
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(const detail::Binding<Members, SourceTypes> &... bs) {
  return build<T>(fn::constant(shrinkable::lambda([] { return T(); })), bs...);
}

} // namespace gen
} // namespace rc
<commit_msg>Allow aggregate initialization in gen::construct and gen::makeUnique<commit_after>#pragma once

#include "rapidcheck/gen/Tuple.h"
#include "rapidcheck/detail/ApplyTuple.h"

namespace rc {
namespace gen {
namespace detail {

// Member variables
template <typename Type, typename T>
class Lens<T(Type::*)> {
public:
  typedef T(Type::*MemberPtr);
  typedef Type Target;
  typedef T ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    obj.*m_ptr = std::move(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with single argument
template <typename Type, typename Ret, typename T>
class Lens<Ret (Type::*)(T)> {
public:
  typedef Ret (Type::*MemberPtr)(T);
  typedef Type Target;
  typedef Decay<T> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    (obj.*m_ptr)(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with multiple arguments
template <typename Type, typename Ret, typename T1, typename T2, typename... Ts>
class Lens<Ret (Type::*)(T1, T2, Ts...)> {
public:
  typedef Ret (Type::*MemberPtr)(T1, T2, Ts...);
  typedef Type Target;
  typedef std::tuple<Decay<T1>, Decay<T2>, Decay<Ts>...> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    rc::detail::applyTuple(
        std::forward<Arg>(arg),
        [&](Decay<T1> &&arg1, Decay<T2> &&arg2, Decay<Ts> &&... args) {
          (obj.*m_ptr)(std::move(arg1), std::move(arg2), std::move(args)...);
        });
  }

private:
  MemberPtr m_ptr;
};

template <typename Member, typename SourceType>
struct Binding {
  Binding(Lens<Member> &&l, Gen<SourceType> &&g)
      : lens(std::move(l))
      , gen(std::move(g)) {}

  Lens<Member> lens;
  Gen<SourceType> gen;
};

template <typename T>
T &deref(T &x) {
  return x;
}

template <typename T>
T &deref(std::unique_ptr<T> &x) {
  return *x;
}

template <typename T>
T &deref(std::shared_ptr<T> &x) {
  return *x;
}

template <typename T, typename Indexes, typename... Lenses>
class BuildMapper;

template <typename T, typename... Lenses, std::size_t... Indexes>
class BuildMapper<T, rc::detail::IndexSequence<Indexes...>, Lenses...> {
public:
  BuildMapper(const Lenses &... lenses)
      : m_lenses(lenses...) {}

  T operator()(std::tuple<T, typename Lenses::ValueType...> &&tuple) const {
    T &obj = std::get<0>(tuple);
    auto dummy = {(std::get<Indexes>(m_lenses).set(
                       deref(obj), std::move(std::get<Indexes + 1>(tuple))),
                   0)...};
    (void)dummy; // Silence warning

    return std::move(obj);
  }

private:
  std::tuple<Lenses...> m_lenses;
};

} // namespace detail

template <typename T, typename... Args>
Gen<T> construct(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) { return T{std::move(args)...}; });
                  });
}

template <typename T, typename Arg, typename... Args>
Gen<T> construct() {
  return gen::construct<T>(gen::arbitrary<Arg>(), gen::arbitrary<Args>()...);
}

template <typename T, typename... Args>
Gen<std::unique_ptr<T>> makeUnique(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) {
                          return std::unique_ptr<T>(new T{std::move(args)...});
                        });
                  });
}

template <typename T, typename... Args>
Gen<std::shared_ptr<T>> makeShared(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(std::move(argsTuple),
                                                  [](Args &&... args) {
                                                    return std::make_shared<T>(
                                                        std::move(args)...);
                                                  });
                  });
}

template <typename Member, typename T>
detail::Binding<Member, T> set(Member member, Gen<T> gen) {
  return detail::Binding<Member, T>(detail::Lens<Member>(member),
                                    std::move(gen));
}

template <typename Member>
detail::Binding<Member, typename detail::Lens<Member>::ValueType>
set(Member member) {
  using T = typename detail::Lens<Member>::ValueType;
  return set(member, gen::arbitrary<T>());
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(Gen<T> gen, const detail::Binding<Members, SourceTypes> &... bs) {
  using Mapper =
      detail::BuildMapper<T,
                          rc::detail::MakeIndexSequence<sizeof...(Members)>,
                          detail::Lens<Members>...>;

  // GCC HACK - Variadics + lambdas don't work very well in GCC so we use an old
  // fashioned function object (the Mapper thing) to prevent GCC from crashing.
  // Use lambdas and applyTuple once we drop support for the crashing ones.
  return gen::map(gen::tuple(std::move(gen), std::move(bs.gen)...),
                  Mapper(bs.lens...));
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(const detail::Binding<Members, SourceTypes> &... bs) {
  return build<T>(fn::constant(shrinkable::lambda([] { return T(); })), bs...);
}

} // namespace gen
} // namespace rc
<|endoftext|>


<commit_before>#ifndef TMXPP_STRONG_TYPEDEF_HPP
#define TMXPP_STRONG_TYPEDEF_HPP

#include <type_safe/strong_typedef.hpp>

namespace tmxpp {

template <class T, class Phantom>
class Strong_typedef
  : public type_safe::strong_typedef<Phantom, T>
  , type_safe::strong_typedef_op::equality_comparison<
        Strong_typedef<T, Phantom>, bool>
  , type_safe::strong_typedef_op::relational_comparison<
        Strong_typedef<T, Phantom>, bool> {
public:
    using type_safe::strong_typedef<Phantom, T>::strong_typedef;
};

} // namespace tmxpp

#endif // TMXPP_STRONG_TYPEDEF_HPP
<commit_msg>Update to type_safe library<commit_after>#ifndef TMXPP_STRONG_TYPEDEF_HPP
#define TMXPP_STRONG_TYPEDEF_HPP

#include <type_safe/strong_typedef.hpp>

namespace tmxpp {

template <class T, class Phantom>
class Strong_typedef
  : public type_safe::strong_typedef<Phantom, T>
  , public type_safe::strong_typedef_op::equality_comparison<
        Strong_typedef<T, Phantom>>
  , public type_safe::strong_typedef_op::relational_comparison<
        Strong_typedef<T, Phantom>> {
public:
    using type_safe::strong_typedef<Phantom, T>::strong_typedef;
};

} // namespace tmxpp

#endif // TMXPP_STRONG_TYPEDEF_HPP
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <string>

using std::cout;
using std::endl;

struct Test final {
  template <typename... A>
  explicit Test(A...) = delete;

  template <typename A>
  void operator=(A) = delete;

  template <typename A>
  operator A(void) = delete;

  template <typename A>
  static inline bool assertEquals(const char* const msg, A expected, A actual) {
    bool ret = expected == actual;

    if (ret) {
      cout << "SUCCESS:" << endl
           << "\texpected(" << expected << ") ";
    } else {
      cout << "FAILURE:" << endl
           << "\t" << msg << "expected(" << expected << ") !";
    }

    cout << "= actual(" << actual << ")." << endl;

    return ret;
  }

  template <typename A>
  static inline bool assertEquals(std::string msg, A expected, A actual) {
    return Test::assertEquals<A>(msg.c_str(), expected, actual);
  }

  template <typename A>
  static inline bool assertEquals(A expected, A actual) {
    return Test::assertEquals<A>("", expected, actual);
  }

  template <typename C, template <class...> class A, template <class...> class B>
  static inline void assertEquals(const A<C>& expected, const B<C>& actual) {
    auto success = 0, failure = 0;

    for (auto iter1 = expected.cbegin(), iter2 = actual.cbegin();
         iter1 != expected.cend() && iter2 != actual.cend(); ++iter1, ++iter2) {
      if (Test::assertEquals<C>(*iter1, *iter2)) {
        ++success;
      } else {
        ++failure;
      }
    }

    cout << "Success: " << success << endl
         << "Failure: " << failure << endl;
  }

};
<commit_msg>add size assert add exception and assert headers for later will try to include a version of assertEquals that is passed a tuple to represent function argument to deal with any possible exceptions it might throw<commit_after>#pragma once

#include <iostream>
#include <string>
#include <cassert>
#include <exception>

using std::cout;
using std::endl;

struct Test final {
  template <typename... A>
  explicit Test(A...) = delete;

  template <typename A>
  void operator=(A) = delete;

  template <typename A>
  operator A(void) = delete;

  template <typename A>
  static inline bool assertEquals(const char* const msg, A expected, A actual) {
    bool ret = expected == actual;

    if (ret) {
      cout << "SUCCESS:" << endl
           << "\texpected(" << expected << ") ";
    } else {
      cout << "FAILURE:" << endl
           << "\t" << msg << "expected(" << expected << ") !";
    }

    cout << "= actual(" << actual << ")." << endl;

    return ret;
  }

  template <typename A>
  static inline bool assertEquals(std::string msg, A expected, A actual) {
    return Test::assertEquals<A>(msg.c_str(), expected, actual);
  }

  template <typename A>
  static inline bool assertEquals(A expected, A actual) {
    return Test::assertEquals<A>("", expected, actual);
  }

  template <typename C, template <class...> class A, template <class...> class B>
  static inline void assertEquals(const A<C>& expected, const B<C>& actual) {
    assert(expected.size() == actual.size());
    auto success = 0, failure = 0;

    for (auto iter1 = expected.cbegin(), iter2 = actual.cbegin();
         iter1 != expected.cend() && iter2 != actual.cend(); ++iter1, ++iter2) {
      if (Test::assertEquals<C>(*iter1, *iter2)) {
        ++success;
      } else {
        ++failure;
      }
    }

    cout << "Success: " << success << endl
         << "Failure: " << failure << endl;
  }

};
<|endoftext|>