<commit_before>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <ox/std/memops.hpp>
#include <ox/std/strops.hpp>
#include "pathiterator.hpp"

namespace ox {

PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
	m_path = path;
	m_maxSize = maxSize;
	m_iterator = iterator;
}

PathIterator::PathIterator(const char *path): PathIterator(path, ox_strlen(path)) {
}

/**
 * @return 0 if no error
 */
Error PathIterator::dirPath(char *out, std::size_t outSize) {
	int idx = ox_lastIndexOf(m_path, '/', m_maxSize);
	std::size_t size = idx + 1;
	if (idx >= 0 && size < outSize) {
		ox_memcpy(out, m_path, size);
		out[size] = 0;
		return OxError(0);
	} else {
		return OxError(1);
	}
}

/**
 * @return 0 if no error
 */
Error PathIterator::fileName(char *out, std::size_t outSize) {
	auto idx = ox_lastIndexOf(m_path, '/', m_maxSize);
	if (idx >= 0) {
		idx++; // pass up the preceding /
		std::size_t fileNameSize = ox_strlen(&m_path[idx]);
		if (fileNameSize < outSize) {
			ox_memcpy(out, &m_path[idx], fileNameSize);
			out[fileNameSize] = 0;
			return OxError(0);
		} else {
			return OxError(1);
		}
	} else {
		return OxError(2);
	}
}

// Gets the get item in the path
Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
	std::size_t size = 0;
	Error retval = 1;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		retval = 0;
		auto start = m_iterator;
		if (m_path[start] == '/') {
			start++;
		}
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
		// cannot fit the output in the output parameter
		if (size >= pathOutSize) {
			return OxError(1);
		}
		ox_memcpy(pathOut, &m_path[start], size);
	}
	// truncate trailing /
	if (size && pathOut[size - 1] == '/') {
		size--;
	}
	pathOut[size] = 0; // end with null terminator
	return OxError(retval);
}

// Gets the get item in the path
Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
	std::size_t size = 0;
	Error retval = 1;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		retval = 0;
		if (m_path[m_iterator] == '/') {
			m_iterator++;
		}
		std::size_t start = m_iterator;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
		// cannot fit the output in the output parameter
		if (size >= pathOutSize) {
			return OxError(1);
		}
		ox_memcpy(pathOut, &m_path[start], size);
	}
	// truncate trailing /
	if (size && pathOut[size - 1] == '/') {
		size--;
	}
	pathOut[size] = 0; // end with null terminator
	m_iterator += size;
	return OxError(retval);
}

/**
 * @return 0 if no error
 */
Error PathIterator::get(BString<MaxFileNameLength> *fileName) {
	return get(fileName->data(), fileName->cap());
}

/**
 * @return 0 if no error
 */
Error PathIterator::next(BString<MaxFileNameLength> *fileName) {
	return next(fileName->data(), fileName->cap());
}

ValErr<std::size_t> PathIterator::nextSize() const {
	std::size_t size = 0;
	Error retval = 1;
	auto it = m_iterator;
	if (it < m_maxSize && ox_strlen(&m_path[it])) {
		retval = 0;
		if (m_path[it] == '/') {
			it++;
		}
		std::size_t start = it;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	it += size;
	return {size, OxError(retval)};
}

bool PathIterator::hasNext() const {
	std::size_t size = 0;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		std::size_t start = m_iterator;
		if (m_path[start] == '/') {
			start++;
		}
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	return size > 0;
}

bool PathIterator::valid() const {
	return m_path[m_iterator] != 0;
}

PathIterator PathIterator::operator+(int i) const {
	std::size_t size = 0;
	auto iterator = m_iterator;
	if (iterator < m_maxSize && ox_strlen(&m_path[iterator])) {
		if (m_path[iterator] == '/') {
			iterator++;
		}
		std::size_t start = iterator;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	iterator += size;
	return PathIterator(m_path, m_maxSize, iterator + i);
}

const char *PathIterator::fullPath() const {
	return m_path;
}

}
<commit_msg>[ox/fs] Fix PathIterator::valid to check iterator against max size<commit_after>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <ox/std/memops.hpp>
#include <ox/std/strops.hpp>
#include "pathiterator.hpp"

namespace ox {

PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
	m_path = path;
	m_maxSize = maxSize;
	m_iterator = iterator;
}

PathIterator::PathIterator(const char *path): PathIterator(path, ox_strlen(path)) {
}

/**
 * @return 0 if no error
 */
Error PathIterator::dirPath(char *out, std::size_t outSize) {
	int idx = ox_lastIndexOf(m_path, '/', m_maxSize);
	std::size_t size = idx + 1;
	if (idx >= 0 && size < outSize) {
		ox_memcpy(out, m_path, size);
		out[size] = 0;
		return OxError(0);
	} else {
		return OxError(1);
	}
}

/**
 * @return 0 if no error
 */
Error PathIterator::fileName(char *out, std::size_t outSize) {
	auto idx = ox_lastIndexOf(m_path, '/', m_maxSize);
	if (idx >= 0) {
		idx++; // pass up the preceding /
		std::size_t fileNameSize = ox_strlen(&m_path[idx]);
		if (fileNameSize < outSize) {
			ox_memcpy(out, &m_path[idx], fileNameSize);
			out[fileNameSize] = 0;
			return OxError(0);
		} else {
			return OxError(1);
		}
	} else {
		return OxError(2);
	}
}

// Gets the get item in the path
Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
	std::size_t size = 0;
	Error retval = 1;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		retval = 0;
		auto start = m_iterator;
		if (m_path[start] == '/') {
			start++;
		}
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
		// cannot fit the output in the output parameter
		if (size >= pathOutSize) {
			return OxError(1);
		}
		ox_memcpy(pathOut, &m_path[start], size);
	}
	// truncate trailing /
	if (size && pathOut[size - 1] == '/') {
		size--;
	}
	pathOut[size] = 0; // end with null terminator
	return OxError(retval);
}

// Gets the get item in the path
Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
	std::size_t size = 0;
	Error retval = 1;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		retval = 0;
		if (m_path[m_iterator] == '/') {
			m_iterator++;
		}
		std::size_t start = m_iterator;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
		// cannot fit the output in the output parameter
		if (size >= pathOutSize) {
			return OxError(1);
		}
		ox_memcpy(pathOut, &m_path[start], size);
	}
	// truncate trailing /
	if (size && pathOut[size - 1] == '/') {
		size--;
	}
	pathOut[size] = 0; // end with null terminator
	m_iterator += size;
	return OxError(retval);
}

/**
 * @return 0 if no error
 */
Error PathIterator::get(BString<MaxFileNameLength> *fileName) {
	return get(fileName->data(), fileName->cap());
}

/**
 * @return 0 if no error
 */
Error PathIterator::next(BString<MaxFileNameLength> *fileName) {
	return next(fileName->data(), fileName->cap());
}

ValErr<std::size_t> PathIterator::nextSize() const {
	std::size_t size = 0;
	Error retval = 1;
	auto it = m_iterator;
	if (it < m_maxSize && ox_strlen(&m_path[it])) {
		retval = 0;
		if (m_path[it] == '/') {
			it++;
		}
		std::size_t start = it;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	it += size;
	return {size, OxError(retval)};
}

bool PathIterator::hasNext() const {
	std::size_t size = 0;
	if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
		std::size_t start = m_iterator;
		if (m_path[start] == '/') {
			start++;
		}
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	return size > 0;
}

bool PathIterator::valid() const {
	return m_iterator < m_maxSize && m_path[m_iterator] != 0;
}

PathIterator PathIterator::operator+(int i) const {
	std::size_t size = 0;
	auto iterator = m_iterator;
	if (iterator < m_maxSize && ox_strlen(&m_path[iterator])) {
		if (m_path[iterator] == '/') {
			iterator++;
		}
		std::size_t start = iterator;
		// end is at the next /
		const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
		// correct end if it is invalid, which happens if there is no next /
		if (!substr) {
			substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
		}
		std::size_t end = substr - m_path;
		size = end - start;
	}
	iterator += size;
	return PathIterator(m_path, m_maxSize, iterator + i);
}

const char *PathIterator::fullPath() const {
	return m_path;
}

}
<|endoftext|>


<commit_before>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * [Partly inspired from the LLVM libcxx sources].
 * Copyright (c) 2009-2013 by the contributors listed in
 * 'LLVM libcxx Credits.txt'. See 'LLVM libcxx License.txt' for details.
 *
 * References are to ISO/IEC 14882:2011(E) Third edition (2011-09-01).
 */

#include <cmsis-plus/iso/malloc.h>
#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/diag/trace.h>

#include <cstdlib>

using namespace os::rtos;

namespace os
{
  namespace estd
  {
    /**
     * @details
     * The malloc() function allocates size bytes of memory and returns a
     * pointer to the allocated memory. Currently it calls
     * the C function.
     *
     * @note Synchronisation is provided by using a scheduler lock.
     */
    void*
    malloc (std::size_t size) noexcept
    {
      void* p;
        {
          // ----- Begin of critical section ----------------------------------
          scheduler::critical_section cs;

          p = ::malloc (size);
          // ----- End of critical section ------------------------------------
        }
#if defined(OS_TRACE_LIBC_MALLOC)
      trace::printf ("%s(%d) %p\n", __func__, size, p);
#endif

      return p;
    }

    /**
     * @details
     * The free() function deallocates the memory allocation pointed
     * to by ptr.
     *
     * If ptr is a NULL pointer, no operation is performed.
     *
     * Currently it calls the C function.
     *
     * @note Synchronisation is provided by using a scheduler lock.
     */
    void
    free (void *ptr) noexcept
    {
#if defined(OS_TRACE_LIBC_MALLOC)
      trace::printf ("%s(%p)\n", __func__, ptr);
#endif

        {
          // ----- Begin of critical section ----------------------------------
          scheduler::critical_section cs;

          return ::free (ptr);
          // ----- End of critical section ------------------------------------
        }
    }
  } /* namespace estd */
} /* namespace os */
<commit_msg>libcpp/malloc.cpp: prefix trace with estd::<commit_after>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * [Partly inspired from the LLVM libcxx sources].
 * Copyright (c) 2009-2013 by the contributors listed in
 * 'LLVM libcxx Credits.txt'. See 'LLVM libcxx License.txt' for details.
 *
 * References are to ISO/IEC 14882:2011(E) Third edition (2011-09-01).
 */

#include <cmsis-plus/iso/malloc.h>
#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/diag/trace.h>

#include <cstdlib>

using namespace os::rtos;

namespace os
{
  namespace estd
  {
    /**
     * @details
     * The malloc() function allocates size bytes of memory and returns a
     * pointer to the allocated memory. Currently it calls
     * the C function.
     *
     * @note Synchronisation is provided by using a scheduler lock.
     */
    void*
    malloc (std::size_t size) noexcept
    {
      void* p;
        {
          // ----- Begin of critical section ----------------------------------
          scheduler::critical_section cs;

          p = ::malloc (size);
          // ----- End of critical section ------------------------------------
        }
#if defined(OS_TRACE_LIBC_MALLOC)
      trace::printf ("estd::%s(%d)=%p\n", __func__, size, p);
#endif

      return p;
    }

    /**
     * @details
     * The free() function deallocates the memory allocation pointed
     * to by ptr.
     *
     * If ptr is a NULL pointer, no operation is performed.
     *
     * Currently it calls the C function.
     *
     * @note Synchronisation is provided by using a scheduler lock.
     */
    void
    free (void *ptr) noexcept
    {
#if defined(OS_TRACE_LIBC_MALLOC)
      trace::printf ("estd::%s(%p)\n", __func__, ptr);
#endif

        {
          // ----- Begin of critical section ----------------------------------
          scheduler::critical_section cs;

          return ::free (ptr);
          // ----- End of critical section ------------------------------------
        }
    }
  } /* namespace estd */
} /* namespace os */
<|endoftext|>


<commit_before>

extern "C" {
  struct lua_State;
  struct tolua_Error
  {
          int index;
          int array;
          const char* type;
  };

  void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
  {
    __coverity_panic__();
  }

}
<commit_msg>Delete CoverityModel.cpp<commit_after><|endoftext|>


<commit_before>/******************************************************************************
SparkFunMLX90614.cpp
Source file for the SparkFun IR Thermometer Library

Jim Lindblom @ SparkFun Electronics
October 23, 2015
https://github.com/sparkfun/SparkFun_MLX90614_Arduino_Library

This file defines the SMBus hardware interface(s) for the MLX90614 IR thermometer
and abstracts temperature measurments and other features of the MLX90614

Development environment specifics:
Arduino 1.6.5
SparkFun IR Thermometer Evaluation Board - MLX90614
******************************************************************************/

#include <SparkFunMLX90614.h>

IRTherm::IRTherm()
{
	// Set initial values for all private member variables
	_deviceAddress = 0;
	_defaultUnit = TEMP_C;
	_rawObject = 0;
	_rawAmbient = 0;
	_rawObject2 = 0;
	_rawMax = 0;
	_rawMin = 0;
}

uint8_t IRTherm::begin(uint8_t address)
{
	_deviceAddress = address; // Store the address in a private member

	Wire.begin(); // Initialize I2C
	//! TODO: read a register, return success only if the register
	//! produced a known-good value.
	return 1; // Return success
}

void IRTherm::setUnit(temperature_units unit)
{
	_defaultUnit = unit; // Store the unit into a private member
}

uint8_t IRTherm::read()
{
	// read both the object and ambient temperature values
	if (readObject() && readAmbient())
	{
		// If the reads succeeded, return success
		return 1;
	}
	return 0; // Else return fail
}

uint8_t IRTherm::readRange()
{
	// Read both minimum and maximum values from EEPROM
	if (readMin() && readMax())
	{
		// If the read succeeded, return success
		return 1;
	}
	return 0; // Else return fail
}

float IRTherm::ambient(void)
{
	// Return the calculated ambient temperature
	return calcTemperature(_rawAmbient);
}

float IRTherm::object(void)
{
	// Return the calculated object temperature
	return calcTemperature(_rawObject);
}

float IRTherm::minimum(void)
{
	// Return the calculated minimum temperature
	return calcTemperature(_rawMin);
}

float IRTherm::maximum(void)
{
	// Return the calculated maximum temperature
	return calcTemperature(_rawMax);
}

uint8_t IRTherm::readObject()
{
	int16_t rawObj;
	// Read from the TOBJ1 register, store into the rawObj variable
	if (I2CReadWord(MLX90614_REGISTER_TOBJ1, &rawObj))
	{
		// If the read succeeded
		if (rawObj & 0x8000) // If there was a flag error
		{
			return 0; // Return fail
		}
		// Store the object temperature into the class variable
		_rawObject = rawObj;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readObject2()
{
	int16_t rawObj;
	// Read from the TOBJ2 register, store into the rawObj variable
	if (I2CReadWord(MLX90614_REGISTER_TOBJ2, &rawObj))
	{
		// If the read succeeded
		if (rawObj & 0x8000) // If there was a flag error
		{
			return 0; // Return fail
		}
		// Store the object2 temperature into the class variable
		_rawObject2 = rawObj;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readAmbient()
{
	int16_t rawAmb;
	// Read from the TA register, store value in rawAmb
	if (I2CReadWord(MLX90614_REGISTER_TA, &rawAmb))
	{
		// If the read succeeds, store the read value
		_rawAmbient = rawAmb; // return success
		return 1;
	}
	return 0; // else return fail
}

uint8_t IRTherm::readMax()
{
	int16_t toMax;
	// Read from the TOMax EEPROM address, store value in toMax
	if (I2CReadWord(MLX90614_REGISTER_TOMAX, &toMax))
	{
		_rawMax = toMax;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readMin()
{
	int16_t toMin;
	// Read from the TOMin EEPROM address, store value in toMax
	if (I2CReadWord(MLX90614_REGISTER_TOMIN, &toMin))
	{
		_rawMin = toMin;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::setMax(float maxTemp)
{
	// Convert the unit-ed value to a raw ADC value:
	int16_t rawMax = calcRawTemp(maxTemp);
	// Write that value to the TOMAX EEPROM address:
	return writeEEPROM(MLX90614_REGISTER_TOMAX, rawMax);
}

uint8_t IRTherm::setMin(float minTemp)
{
	// Convert the unit-ed value to a raw ADC value:
	int16_t rawMin = calcRawTemp(minTemp);
	// Write that value to the TOMIN EEPROM address:
	return writeEEPROM(MLX90614_REGISTER_TOMIN, rawMin);
}

uint8_t IRTherm::setEmissivity(float emis)
{
	// Make sure emissivity is between 0.1 and 1.0
	if ((emis > 1.0) || (emis < 0.1))
		return 0; // Return fail if not
	// Calculate the raw 16-bit value:
	uint16_t ke = uint16_t(65535.0 * emis);
	ke = constrain(ke, 0x2000, 0xFFFF);

	// Write that value to the ke register
	return writeEEPROM(MLX90614_REGISTER_KE, (int16_t)ke);
}

float IRTherm::readEmissivity(void)
{
	int16_t ke;
	if (I2CReadWord(MLX90614_REGISTER_KE, &ke))
	{
		// If we successfully read from the ke register
		// calculate the emissivity between 0.1 and 1.0:
		return (((float)((uint16_t)ke)) / 65535.0);
	}
	return 0; // Else return fail
}

uint8_t IRTherm::readAddress(void)
{
	int16_t tempAdd;
	// Read from the 7-bit I2C address EEPROM storage address:
	if (I2CReadWord(MLX90614_REGISTER_ADDRESS, &tempAdd))
	{
		// If read succeeded, return the address:
		return (uint8_t) tempAdd;
	}
	return 0; // Else return fail
}

uint8_t IRTherm::setAddress(uint8_t newAdd)
{
	int16_t tempAdd;
	// Make sure the address is within the proper range:
	if ((newAdd >= 0x80) || (newAdd == 0x00))
		return 0; // Return fail if out of range
	// Read from the I2C address address first:
	if (I2CReadWord(MLX90614_REGISTER_ADDRESS, &tempAdd))
	{
		tempAdd &= 0xFF00; // Mask out the address (MSB is junk?)
		tempAdd |= newAdd; // Add the new address

		// Write the new addres back to EEPROM:
		return writeEEPROM(MLX90614_REGISTER_ADDRESS, tempAdd);
	}
	return 0;
}

uint8_t IRTherm::readID(void)
{
	for (int i=0; i<4; i++)
	{
		int16_t temp = 0;
		// Read from all four ID registers, beginning at the first:
		if (!I2CReadWord(MLX90614_REGISTER_ID0 + i, &temp))
			return 0;
		// If the read succeeded, store the ID into the id array:
		id[i] = (uint16_t)temp;
	}
	return 1;
}

uint32_t IRTherm::getIDH(void)
{
	// Return the upper 32 bits of the ID
	return ((uint32_t)id[3] << 16) | id[2];
}

uint32_t IRTherm::getIDL(void)
{
	// Return the lower 32 bits of the ID
	return ((uint32_t)id[1] << 16) | id[0];
}

uint8_t IRTherm::sleep(void)
{
	// Calculate a crc8 value.
	// Bits sent: _deviceAddress (shifted left 1) + 0xFF
	uint8_t crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, MLX90614_REGISTER_SLEEP);

	// Manually send the sleep command:
	Wire.beginTransmission(_deviceAddress);
	Wire.write(MLX90614_REGISTER_SLEEP);
	Wire.write(crc);
	Wire.endTransmission(true);

	// Set the SCL pin LOW, and SDA pin HIGH (should be pulled up)
	pinMode(SCL, OUTPUT);
	digitalWrite(SCL, LOW);
	pinMode(SDA, INPUT);
}

uint8_t IRTherm::wake(void)
{
	// Wake operation from datasheet. (Doesn't seem to be working.)
	pinMode(SCL, INPUT); // SCL high
	pinMode(SDA, OUTPUT);
	digitalWrite(SDA, LOW); // SDA low
	delay(50); // delay at least 33ms
	pinMode(SDA, INPUT); // SDA high
	delay(250);
	// PWM to SMBus mode:
	pinMode(SCL, OUTPUT);
	digitalWrite(SCL, LOW); // SCL low
	delay(10); // Delay at least 1.44ms
	pinMode(SCL, INPUT); // SCL high
	Wire.begin();
}

int16_t IRTherm::calcRawTemp(float calcTemp)
{
	int16_t rawTemp; // Value to eventually be returned

	if (_defaultUnit == TEMP_RAW)
	{
		// If unit is set to raw, just return that:
		rawTemp = (int16_t) calcTemp;
	}
	else
	{
		float tempFloat;
		// First convert each temperature to Kelvin:
		if (_defaultUnit == TEMP_F)
		{
			// Convert from farenheit to Kelvin
			tempFloat = (calcTemp - 32.0) * 5.0 / 9.0 + 273.15;
		}
		else if (_defaultUnit == TEMP_C)
		{
			tempFloat = calcTemp + 273.15;
		}
		else if (_defaultUnit == TEMP_K)
		{
			tempFloat = calcTemp;
		}
		// Then multiply by 0.02 degK / bit
		tempFloat *= 50;
		rawTemp = (int16_t) tempFloat;
	}
	return rawTemp;
}

float IRTherm::calcTemperature(int16_t rawTemp)
{
	float retTemp;

	if (_defaultUnit == TEMP_RAW)
	{
		retTemp = (float) rawTemp;
	}
	else
	{
		retTemp = float(rawTemp) * 0.02;
		if (_defaultUnit != TEMP_K)
		{
			retTemp -= 273.15;
			if (_defaultUnit == TEMP_F)
			{
				retTemp = retTemp * 9.0 / 5.0 + 32;
			}
		}
	}

	return retTemp;
}

uint8_t IRTherm::I2CReadWord(byte reg, int16_t * dest)
{
	int timeout = I2C_READ_TIMEOUT;

	Wire.beginTransmission(_deviceAddress);
	Wire.write(reg);

	Wire.endTransmission(false); // Send restart
	Wire.requestFrom(_deviceAddress, (uint8_t) 3);

	while ((Wire.available() < 3) && (timeout-- > 0))
		delay(1);
	if (timeout <= 0)
		return 0;

	uint8_t lsb = Wire.read();
	uint8_t msb = Wire.read();
	uint8_t pec = Wire.read();

	uint8_t crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, reg);
	crc = crc8(crc, (_deviceAddress << 1) + 1);
	crc = crc8(crc, lsb);
	crc = crc8(crc, msb);

	if (crc == pec)
	{
		*dest = (msb << 8) | lsb;
		return 1;
	}
	else
	{
		return 0;
	}
}

uint8_t IRTherm::writeEEPROM(byte reg, int16_t data)
{
	// Clear out EEPROM first:
	if (I2CWriteWord(reg, 0) != 0)
		return 0; // If the write failed, return 0
	delay(5); // Delay tErase

	uint8_t i2cRet = I2CWriteWord(reg, data);
	delay(5); // Delay tWrite

	if (i2cRet == 0)
		return 1;
	else
		return 0;
}

uint8_t IRTherm::I2CWriteWord(byte reg, int16_t data)
{
	uint8_t crc;
	uint8_t lsb = data & 0x00FF;
	uint8_t msb = (data >> 8);

	crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, reg);
	crc = crc8(crc, lsb);
	crc = crc8(crc, msb);

	Wire.beginTransmission(_deviceAddress);
	Wire.write(reg);
	Wire.write(lsb);
	Wire.write(msb);
	Wire.write(crc);
	return Wire.endTransmission(true);
}

uint8_t IRTherm::crc8 (uint8_t inCrc, uint8_t inData)
{
	uint8_t i;
	uint8_t data;
	data = inCrc ^ inData;
	for ( i = 0; i < 8; i++ )
	{
		if (( data & 0x80 ) != 0 )
		{
			data <<= 1;
			data ^= 0x07;
		}
		else
		{
			data <<= 1;
		}
	}
	return data;
}
<commit_msg>Wake Up FIX<commit_after>/******************************************************************************
SparkFunMLX90614.cpp
Source file for the SparkFun IR Thermometer Library

Jim Lindblom @ SparkFun Electronics
October 23, 2015
https://github.com/sparkfun/SparkFun_MLX90614_Arduino_Library

This file defines the SMBus hardware interface(s) for the MLX90614 IR thermometer
and abstracts temperature measurments and other features of the MLX90614

Development environment specifics:
Arduino 1.6.5
SparkFun IR Thermometer Evaluation Board - MLX90614
******************************************************************************/

#include <SparkFunMLX90614.h>

IRTherm::IRTherm()
{
	// Set initial values for all private member variables
	_deviceAddress = 0;
	_defaultUnit = TEMP_C;
	_rawObject = 0;
	_rawAmbient = 0;
	_rawObject2 = 0;
	_rawMax = 0;
	_rawMin = 0;
}

uint8_t IRTherm::begin(uint8_t address)
{
	_deviceAddress = address; // Store the address in a private member

	Wire.begin(); // Initialize I2C
	//! TODO: read a register, return success only if the register
	//! produced a known-good value.
	return 1; // Return success
}

void IRTherm::setUnit(temperature_units unit)
{
	_defaultUnit = unit; // Store the unit into a private member
}

uint8_t IRTherm::read()
{
	// read both the object and ambient temperature values
	if (readObject() && readAmbient())
	{
		// If the reads succeeded, return success
		return 1;
	}
	return 0; // Else return fail
}

uint8_t IRTherm::readRange()
{
	// Read both minimum and maximum values from EEPROM
	if (readMin() && readMax())
	{
		// If the read succeeded, return success
		return 1;
	}
	return 0; // Else return fail
}

float IRTherm::ambient(void)
{
	// Return the calculated ambient temperature
	return calcTemperature(_rawAmbient);
}

float IRTherm::object(void)
{
	// Return the calculated object temperature
	return calcTemperature(_rawObject);
}

float IRTherm::minimum(void)
{
	// Return the calculated minimum temperature
	return calcTemperature(_rawMin);
}

float IRTherm::maximum(void)
{
	// Return the calculated maximum temperature
	return calcTemperature(_rawMax);
}

uint8_t IRTherm::readObject()
{
	int16_t rawObj;
	// Read from the TOBJ1 register, store into the rawObj variable
	if (I2CReadWord(MLX90614_REGISTER_TOBJ1, &rawObj))
	{
		// If the read succeeded
		if (rawObj & 0x8000) // If there was a flag error
		{
			return 0; // Return fail
		}
		// Store the object temperature into the class variable
		_rawObject = rawObj;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readObject2()
{
	int16_t rawObj;
	// Read from the TOBJ2 register, store into the rawObj variable
	if (I2CReadWord(MLX90614_REGISTER_TOBJ2, &rawObj))
	{
		// If the read succeeded
		if (rawObj & 0x8000) // If there was a flag error
		{
			return 0; // Return fail
		}
		// Store the object2 temperature into the class variable
		_rawObject2 = rawObj;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readAmbient()
{
	int16_t rawAmb;
	// Read from the TA register, store value in rawAmb
	if (I2CReadWord(MLX90614_REGISTER_TA, &rawAmb))
	{
		// If the read succeeds, store the read value
		_rawAmbient = rawAmb; // return success
		return 1;
	}
	return 0; // else return fail
}

uint8_t IRTherm::readMax()
{
	int16_t toMax;
	// Read from the TOMax EEPROM address, store value in toMax
	if (I2CReadWord(MLX90614_REGISTER_TOMAX, &toMax))
	{
		_rawMax = toMax;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::readMin()
{
	int16_t toMin;
	// Read from the TOMin EEPROM address, store value in toMax
	if (I2CReadWord(MLX90614_REGISTER_TOMIN, &toMin))
	{
		_rawMin = toMin;
		return 1;
	}
	return 0;
}

uint8_t IRTherm::setMax(float maxTemp)
{
	// Convert the unit-ed value to a raw ADC value:
	int16_t rawMax = calcRawTemp(maxTemp);
	// Write that value to the TOMAX EEPROM address:
	return writeEEPROM(MLX90614_REGISTER_TOMAX, rawMax);
}

uint8_t IRTherm::setMin(float minTemp)
{
	// Convert the unit-ed value to a raw ADC value:
	int16_t rawMin = calcRawTemp(minTemp);
	// Write that value to the TOMIN EEPROM address:
	return writeEEPROM(MLX90614_REGISTER_TOMIN, rawMin);
}

uint8_t IRTherm::setEmissivity(float emis)
{
	// Make sure emissivity is between 0.1 and 1.0
	if ((emis > 1.0) || (emis < 0.1))
		return 0; // Return fail if not
	// Calculate the raw 16-bit value:
	uint16_t ke = uint16_t(65535.0 * emis);
	ke = constrain(ke, 0x2000, 0xFFFF);

	// Write that value to the ke register
	return writeEEPROM(MLX90614_REGISTER_KE, (int16_t)ke);
}

float IRTherm::readEmissivity(void)
{
	int16_t ke;
	if (I2CReadWord(MLX90614_REGISTER_KE, &ke))
	{
		// If we successfully read from the ke register
		// calculate the emissivity between 0.1 and 1.0:
		return (((float)((uint16_t)ke)) / 65535.0);
	}
	return 0; // Else return fail
}

uint8_t IRTherm::readAddress(void)
{
	int16_t tempAdd;
	// Read from the 7-bit I2C address EEPROM storage address:
	if (I2CReadWord(MLX90614_REGISTER_ADDRESS, &tempAdd))
	{
		// If read succeeded, return the address:
		return (uint8_t) tempAdd;
	}
	return 0; // Else return fail
}

uint8_t IRTherm::setAddress(uint8_t newAdd)
{
	int16_t tempAdd;
	// Make sure the address is within the proper range:
	if ((newAdd >= 0x80) || (newAdd == 0x00))
		return 0; // Return fail if out of range
	// Read from the I2C address address first:
	if (I2CReadWord(MLX90614_REGISTER_ADDRESS, &tempAdd))
	{
		tempAdd &= 0xFF00; // Mask out the address (MSB is junk?)
		tempAdd |= newAdd; // Add the new address

		// Write the new addres back to EEPROM:
		return writeEEPROM(MLX90614_REGISTER_ADDRESS, tempAdd);
	}
	return 0;
}

uint8_t IRTherm::readID(void)
{
	for (int i=0; i<4; i++)
	{
		int16_t temp = 0;
		// Read from all four ID registers, beginning at the first:
		if (!I2CReadWord(MLX90614_REGISTER_ID0 + i, &temp))
			return 0;
		// If the read succeeded, store the ID into the id array:
		id[i] = (uint16_t)temp;
	}
	return 1;
}

uint32_t IRTherm::getIDH(void)
{
	// Return the upper 32 bits of the ID
	return ((uint32_t)id[3] << 16) | id[2];
}

uint32_t IRTherm::getIDL(void)
{
	// Return the lower 32 bits of the ID
	return ((uint32_t)id[1] << 16) | id[0];
}

uint8_t IRTherm::sleep(void)
{
	// Calculate a crc8 value.
	// Bits sent: _deviceAddress (shifted left 1) + 0xFF
	uint8_t crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, MLX90614_REGISTER_SLEEP);

	// Manually send the sleep command:
	Wire.beginTransmission(_deviceAddress);
	Wire.write(MLX90614_REGISTER_SLEEP);
	Wire.write(crc);
	Wire.endTransmission(true);

	// Set the SCL pin LOW, and SDA pin HIGH (should be pulled up)
	pinMode(SCL, OUTPUT);
	digitalWrite(SCL, LOW);
	pinMode(SDA, INPUT);
}

uint8_t IRTherm::wake(void)
{
	// Wake operation from datasheet
	Wire.end(); // stop i2c bus to send wake up request via digital pins
	pinMode(SCL, INPUT); // SCL high
	pinMode(SDA, OUTPUT);
	digitalWrite(SDA, LOW); // SDA low
	delay(50); // delay at least 33ms
	pinMode(SDA, INPUT); // SDA high
	delay(250);
	// PWM to SMBus mode:
	pinMode(SCL, OUTPUT);
	digitalWrite(SCL, LOW); // SCL low
	delay(10); // Delay at least 1.44ms
	pinMode(SCL, INPUT); // SCL high
	Wire.begin();
}

int16_t IRTherm::calcRawTemp(float calcTemp)
{
	int16_t rawTemp; // Value to eventually be returned

	if (_defaultUnit == TEMP_RAW)
	{
		// If unit is set to raw, just return that:
		rawTemp = (int16_t) calcTemp;
	}
	else
	{
		float tempFloat;
		// First convert each temperature to Kelvin:
		if (_defaultUnit == TEMP_F)
		{
			// Convert from farenheit to Kelvin
			tempFloat = (calcTemp - 32.0) * 5.0 / 9.0 + 273.15;
		}
		else if (_defaultUnit == TEMP_C)
		{
			tempFloat = calcTemp + 273.15;
		}
		else if (_defaultUnit == TEMP_K)
		{
			tempFloat = calcTemp;
		}
		// Then multiply by 0.02 degK / bit
		tempFloat *= 50;
		rawTemp = (int16_t) tempFloat;
	}
	return rawTemp;
}

float IRTherm::calcTemperature(int16_t rawTemp)
{
	float retTemp;

	if (_defaultUnit == TEMP_RAW)
	{
		retTemp = (float) rawTemp;
	}
	else
	{
		retTemp = float(rawTemp) * 0.02;
		if (_defaultUnit != TEMP_K)
		{
			retTemp -= 273.15;
			if (_defaultUnit == TEMP_F)
			{
				retTemp = retTemp * 9.0 / 5.0 + 32;
			}
		}
	}

	return retTemp;
}

uint8_t IRTherm::I2CReadWord(byte reg, int16_t * dest)
{
	int timeout = I2C_READ_TIMEOUT;

	Wire.beginTransmission(_deviceAddress);
	Wire.write(reg);

	Wire.endTransmission(false); // Send restart
	Wire.requestFrom(_deviceAddress, (uint8_t) 3);

	while ((Wire.available() < 3) && (timeout-- > 0))
		delay(1);
	if (timeout <= 0)
		return 0;

	uint8_t lsb = Wire.read();
	uint8_t msb = Wire.read();
	uint8_t pec = Wire.read();

	uint8_t crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, reg);
	crc = crc8(crc, (_deviceAddress << 1) + 1);
	crc = crc8(crc, lsb);
	crc = crc8(crc, msb);

	if (crc == pec)
	{
		*dest = (msb << 8) | lsb;
		return 1;
	}
	else
	{
		return 0;
	}
}

uint8_t IRTherm::writeEEPROM(byte reg, int16_t data)
{
	// Clear out EEPROM first:
	if (I2CWriteWord(reg, 0) != 0)
		return 0; // If the write failed, return 0
	delay(5); // Delay tErase

	uint8_t i2cRet = I2CWriteWord(reg, data);
	delay(5); // Delay tWrite

	if (i2cRet == 0)
		return 1;
	else
		return 0;
}

uint8_t IRTherm::I2CWriteWord(byte reg, int16_t data)
{
	uint8_t crc;
	uint8_t lsb = data & 0x00FF;
	uint8_t msb = (data >> 8);

	crc = crc8(0, (_deviceAddress << 1));
	crc = crc8(crc, reg);
	crc = crc8(crc, lsb);
	crc = crc8(crc, msb);

	Wire.beginTransmission(_deviceAddress);
	Wire.write(reg);
	Wire.write(lsb);
	Wire.write(msb);
	Wire.write(crc);
	return Wire.endTransmission(true);
}

uint8_t IRTherm::crc8 (uint8_t inCrc, uint8_t inData)
{
	uint8_t i;
	uint8_t data;
	data = inCrc ^ inData;
	for ( i = 0; i < 8; i++ )
	{
		if (( data & 0x80 ) != 0 )
		{
			data <<= 1;
			data ^= 0x07;
		}
		else
		{
			data <<= 1;
		}
	}
	return data;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <stan/math/special_functions.hpp>
#include <stan/prob/distributions/univariate/discrete/ordered_logistic.hpp>
#include <boost/random/mersenne_twister.hpp>
#include<boost/math/distributions.hpp>

using Eigen::Matrix;
using Eigen::Dynamic;

typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d;

vector_d
get_simplex(double lambda,
           const vector_d& c) {
  using stan::math::inv_logit;
  int K = c.size() + 1;
  vector_d theta(K);
  theta(0) = 1.0 - inv_logit(lambda - c(0));
  for (int k = 1; k < (K - 1); ++k)
    theta(k) = inv_logit(lambda - c(k - 1)) - inv_logit(lambda - c(k));
  theta(K-1) = inv_logit(lambda - c(K-2)); // - 0.0
  return theta;
}

TEST(ProbDistributions,ordered_logistic_vals) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 5;
  Matrix<double,Dynamic,1> c(K-1);
  c << -1.7, -0.3, 1.2, 2.6;
  double lambda = 1.1;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(6,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_vals_2) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 3;
  Matrix<double,Dynamic,1> c(K-1);
  c << -0.2, 4;
  double lambda = -0.9;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(4,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_default_policy) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -0.3, 0.1, 1.2;
  double lambda = 0.5;
  EXPECT_THROW(ordered_logistic_log(-1,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(5,lambda,c),std::domain_error);
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero; // init size zero
  EXPECT_EQ(0,c_zero.size());
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_zero),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord_2),std::domain_error);

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  EXPECT_THROW(ordered_logistic_log(1,nan,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(1,inf,c),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);
  cbad[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);
  cbad1[0] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
  cbad3[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);

}

using boost::math::policies::policy;
using boost::math::policies::evaluation_error;
using boost::math::policies::domain_error;
using boost::math::policies::overflow_error;
using boost::math::policies::domain_error;
using boost::math::policies::pole_error;
using boost::math::policies::errno_on_error;

typedef policy<
  domain_error<errno_on_error>,
  pole_error<errno_on_error>,
  overflow_error<errno_on_error>,
  evaluation_error<errno_on_error>
  > errno_policy;

void expect_nan(double x) {
  EXPECT_TRUE(std::isnan(x));
}

TEST(ProbDistributions,ordered_logistic_errno_policy) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -2.1, 0.1, 1.2;
  double lambda = 0.5;

  expect_nan(ordered_logistic_log(-1,lambda,c, errno_policy()));

  expect_nan(ordered_logistic_log(0,lambda,c,errno_policy()));
  expect_nan(ordered_logistic_log(5,lambda,c,errno_policy()));
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero;
  EXPECT_EQ(0,c_zero.size());
  expect_nan(ordered_logistic_log(1,lambda,c_zero,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  expect_nan(ordered_logistic_log(1,lambda,c_unord,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  expect_nan(ordered_logistic_log(1,lambda,c_unord_2,errno_policy()));

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  expect_nan(ordered_logistic_log(1,nan,c,errno_policy()));
  expect_nan(ordered_logistic_log(1,inf,c,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  expect_nan(ordered_logistic_log(1,1.0,cbad,errno_policy()));
  cbad[1] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  expect_nan(ordered_logistic_log(1,1.0,cbad1,errno_policy()));
  cbad1[0] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad1,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  expect_nan(ordered_logistic_log(1,1.0,cbad3,errno_policy()));
  cbad3[1] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad3,errno_policy()));

}

TEST(ProbDistributionOrderedLogistic, random) {
  boost::random::mt19937 rng;
  Matrix<double,Dynamic,Dynamic> c(3,1);
  c << 2.0,
    -2.0,
    11.0;
  EXPECT_NO_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng));
}

<commit_msg>fixed rng test for ordered logistic<commit_after>#include <gtest/gtest.h>
#include <stan/math/special_functions.hpp>
#include <stan/prob/distributions/univariate/discrete/ordered_logistic.hpp>
#include <boost/random/mersenne_twister.hpp>
#include<boost/math/distributions.hpp>

using Eigen::Matrix;
using Eigen::Dynamic;

typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d;

vector_d
get_simplex(double lambda,
           const vector_d& c) {
  using stan::math::inv_logit;
  int K = c.size() + 1;
  vector_d theta(K);
  theta(0) = 1.0 - inv_logit(lambda - c(0));
  for (int k = 1; k < (K - 1); ++k)
    theta(k) = inv_logit(lambda - c(k - 1)) - inv_logit(lambda - c(k));
  theta(K-1) = inv_logit(lambda - c(K-2)); // - 0.0
  return theta;
}

TEST(ProbDistributions,ordered_logistic_vals) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 5;
  Matrix<double,Dynamic,1> c(K-1);
  c << -1.7, -0.3, 1.2, 2.6;
  double lambda = 1.1;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(6,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_vals_2) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 3;
  Matrix<double,Dynamic,1> c(K-1);
  c << -0.2, 4;
  double lambda = -0.9;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(4,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_default_policy) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -0.3, 0.1, 1.2;
  double lambda = 0.5;
  EXPECT_THROW(ordered_logistic_log(-1,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(5,lambda,c),std::domain_error);
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero; // init size zero
  EXPECT_EQ(0,c_zero.size());
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_zero),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord_2),std::domain_error);

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  EXPECT_THROW(ordered_logistic_log(1,nan,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(1,inf,c),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);
  cbad[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);
  cbad1[0] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
  cbad3[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);

}

using boost::math::policies::policy;
using boost::math::policies::evaluation_error;
using boost::math::policies::domain_error;
using boost::math::policies::overflow_error;
using boost::math::policies::domain_error;
using boost::math::policies::pole_error;
using boost::math::policies::errno_on_error;

typedef policy<
  domain_error<errno_on_error>,
  pole_error<errno_on_error>,
  overflow_error<errno_on_error>,
  evaluation_error<errno_on_error>
  > errno_policy;

void expect_nan(double x) {
  EXPECT_TRUE(std::isnan(x));
}

TEST(ProbDistributions,ordered_logistic_errno_policy) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -2.1, 0.1, 1.2;
  double lambda = 0.5;

  expect_nan(ordered_logistic_log(-1,lambda,c, errno_policy()));

  expect_nan(ordered_logistic_log(0,lambda,c,errno_policy()));
  expect_nan(ordered_logistic_log(5,lambda,c,errno_policy()));
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero;
  EXPECT_EQ(0,c_zero.size());
  expect_nan(ordered_logistic_log(1,lambda,c_zero,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  expect_nan(ordered_logistic_log(1,lambda,c_unord,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  expect_nan(ordered_logistic_log(1,lambda,c_unord_2,errno_policy()));

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  expect_nan(ordered_logistic_log(1,nan,c,errno_policy()));
  expect_nan(ordered_logistic_log(1,inf,c,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  expect_nan(ordered_logistic_log(1,1.0,cbad,errno_policy()));
  cbad[1] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  expect_nan(ordered_logistic_log(1,1.0,cbad1,errno_policy()));
  cbad1[0] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad1,errno_policy()));

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  expect_nan(ordered_logistic_log(1,1.0,cbad3,errno_policy()));
  cbad3[1] = nan;
  expect_nan(ordered_logistic_log(1,1.0,cbad3,errno_policy()));

}

TEST(ProbDistributionOrderedLogistic, random) {
  boost::random::mt19937 rng;
  Matrix<double,Dynamic,Dynamic> c(3,1);
  c << 2.0,
    -2.0,
    11.0;
  EXPECT_NO_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng));
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <boost/property_tree/ptree.hpp>

#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"
#include "osquery/sql/sqlite_util.h"

namespace pt = boost::property_tree;

namespace osquery {
namespace tables {

/**
 * @brief The Apple reference date offset.
 *
 * Some Apple epoch dates use 1/1/2001 UTC as the beginning of time.
 * Since *most* things in osquery are UNIX epoch, append the 1970's offset.
 */
const size_t kReferenceDateOffset = 978307200;

/// Basic GLOB pattern for discovering caches.
const std::string kQuicklookPattern =
    "/private/var/folders/%/%/%/com.apple.QuickLook.thumbnailcache/"
    "index.sqlite";

void genQuicklookRow(sqlite3_stmt* stmt, Row& r) {
  for (int i = 0; i < sqlite3_column_count(stmt); i++) {
    auto column_name = std::string(sqlite3_column_name(stmt, i));
    auto column_type = sqlite3_column_type(stmt, i);
    if (column_type == SQLITE_TEXT) {
      auto value = sqlite3_column_text(stmt, i);
      if (value != nullptr) {
        r[column_name] = std::string((const char*)value);
      }
    } else if (column_type == SQLITE_INTEGER) {
      // Handle INTEGER columns explicitly to handle the date-value offset.
      auto value = sqlite3_column_int(stmt, i);
      if (column_name == "last_hit_date") {
        value += kReferenceDateOffset;
      }
      r[column_name] = INTEGER(value);
    } else if (column_type == SQLITE_BLOB) {
      // Handle BLOB values explicitly to avoid the default char* termination
      // for binary-plist data.
      auto getField = [](const pt::ptree& tree, const std::string& field) {
        if (field == "mtime" && tree.count(field) > 0) {
          // Apply a special case for embedded date-value fields.
          return INTEGER(tree.get<size_t>(field) + kReferenceDateOffset);
        }
        return (tree.count(field) > 0) ? tree.get<std::string>(field) : "";
      };

      if (column_name == "version") {
        pt::ptree tree;
        auto version = std::string((const char*)sqlite3_column_blob(stmt, i),
                                   sqlite3_column_bytes(stmt, i));
        if (parsePlistContent(version, tree)) {
          r["mtime"] = getField(tree, "date");
          r["size"] = getField(tree, "size");
          r["label"] = getField(tree, "gen");
        }
      }
    }
  }

  // Transform the folder/file_name into an aggregate path.
  r["path"] = std::move(r["folder"]) + "/" + std::move(r["file_name"]);
  r.erase("folder");
  r.erase("file_name");

  // Transform the encoded fs_id.
  auto details = osquery::split(r["fs_id"], "=.");
  if (details.size() == 4) {
    r["volume_id"] = details[2];
    r["inode"] = details[3];
  }
}

QueryData genQuicklookCache(QueryContext& context) {
  QueryData results;

  // There may be several quick look caches.
  // Apply a GLOB search since the folder is randomized.
  std::vector<std::string> databases;
  if (!resolveFilePattern(kQuicklookPattern, databases)) {
    return results;
  }

  for (const auto& index : databases) {
    sqlite3* db = nullptr;
    auto rc = sqlite3_open_v2(
        index.c_str(), &db,
        (SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE | SQLITE_OPEN_NOMUTEX),
        nullptr);
    if (rc != SQLITE_OK || db == nullptr) {
      VLOG(1) << "Cannot open " << index << " read only: "
              << rc << " " << getStringForSQLiteReturnCode(rc);
      if (db != nullptr) {
        free(db);
      }
      continue;
    }

    // QueryData file_results;
    std::string query =
        "SELECT f.*, last_hit_date, hit_count, icon_mode FROM (SELECT rowid, * "
        "FROM files) f, (SELECT *, max(last_hit_date) AS last_hit_date FROM "
        "thumbnails GROUP BY file_id) t WHERE t.file_id = rowid;";
    sqlite3_stmt* stmt = nullptr;
    rc = sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr);
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
      Row r;
      genQuicklookRow(stmt, r);

      // For each row added to the results from this database, add the path to
      // the database, then move into the table's result set.
      r["cache_path"] = index;
      results.push_back(r);
    }

    // Clean up.
    sqlite3_finalize(stmt);
    free(db);
  }

  return results;
}
}
}
<commit_msg>Fix an sqlite3 memory leak in quicklook_cache (#3552)<commit_after>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <boost/property_tree/ptree.hpp>

#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"
#include "osquery/sql/sqlite_util.h"

namespace pt = boost::property_tree;

namespace osquery {
namespace tables {

/**
 * @brief The Apple reference date offset.
 *
 * Some Apple epoch dates use 1/1/2001 UTC as the beginning of time.
 * Since *most* things in osquery are UNIX epoch, append the 1970's offset.
 */
const size_t kReferenceDateOffset = 978307200;

/// Basic GLOB pattern for discovering caches.
const std::string kQuicklookPattern =
    "/private/var/folders/%/%/%/com.apple.QuickLook.thumbnailcache/"
    "index.sqlite";

void genQuicklookRow(sqlite3_stmt* stmt, Row& r) {
  for (int i = 0; i < sqlite3_column_count(stmt); i++) {
    auto column_name = std::string(sqlite3_column_name(stmt, i));
    auto column_type = sqlite3_column_type(stmt, i);
    if (column_type == SQLITE_TEXT) {
      auto value = sqlite3_column_text(stmt, i);
      if (value != nullptr) {
        r[column_name] = std::string((const char*)value);
      }
    } else if (column_type == SQLITE_INTEGER) {
      // Handle INTEGER columns explicitly to handle the date-value offset.
      auto value = sqlite3_column_int(stmt, i);
      if (column_name == "last_hit_date") {
        value += kReferenceDateOffset;
      }
      r[column_name] = INTEGER(value);
    } else if (column_type == SQLITE_BLOB) {
      // Handle BLOB values explicitly to avoid the default char* termination
      // for binary-plist data.
      auto getField = [](const pt::ptree& tree, const std::string& field) {
        if (field == "mtime" && tree.count(field) > 0) {
          // Apply a special case for embedded date-value fields.
          return INTEGER(tree.get<size_t>(field) + kReferenceDateOffset);
        }
        return (tree.count(field) > 0) ? tree.get<std::string>(field) : "";
      };

      if (column_name == "version") {
        pt::ptree tree;
        auto version = std::string((const char*)sqlite3_column_blob(stmt, i),
                                   sqlite3_column_bytes(stmt, i));
        if (parsePlistContent(version, tree)) {
          r["mtime"] = getField(tree, "date");
          r["size"] = getField(tree, "size");
          r["label"] = getField(tree, "gen");
        }
      }
    }
  }

  // Transform the folder/file_name into an aggregate path.
  r["path"] = std::move(r["folder"]) + "/" + std::move(r["file_name"]);
  r.erase("folder");
  r.erase("file_name");

  // Transform the encoded fs_id.
  auto details = osquery::split(r["fs_id"], "=.");
  if (details.size() == 4) {
    r["volume_id"] = details[2];
    r["inode"] = details[3];
  }
}

QueryData genQuicklookCache(QueryContext& context) {
  QueryData results;

  // There may be several quick look caches.
  // Apply a GLOB search since the folder is randomized.
  std::vector<std::string> databases;
  if (!resolveFilePattern(kQuicklookPattern, databases)) {
    return results;
  }

  for (const auto& index : databases) {
    sqlite3* db = nullptr;
    auto rc = sqlite3_open_v2(
        index.c_str(), &db,
        (SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE | SQLITE_OPEN_NOMUTEX),
        nullptr);
    if (rc != SQLITE_OK || db == nullptr) {
      VLOG(1) << "Cannot open " << index << " read only: "
              << rc << " " << getStringForSQLiteReturnCode(rc);
      if (db != nullptr) {
        sqlite3_close(db);
      }
      continue;
    }

    // QueryData file_results;
    std::string query =
        "SELECT f.*, last_hit_date, hit_count, icon_mode FROM (SELECT rowid, * "
        "FROM files) f, (SELECT *, max(last_hit_date) AS last_hit_date FROM "
        "thumbnails GROUP BY file_id) t WHERE t.file_id = rowid;";
    sqlite3_stmt* stmt = nullptr;
    rc = sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr);
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
      Row r;
      genQuicklookRow(stmt, r);

      // For each row added to the results from this database, add the path to
      // the database, then move into the table's result set.
      r["cache_path"] = index;
      results.push_back(r);
    }

    // Clean up.
    sqlite3_finalize(stmt);
    sqlite3_close(db);
  }

  return results;
}
}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "does_p.h"

using namespace Cutelyst;

Does::Does() :
    d_ptr(new DoesPrivate)
{
}

Does::~Does()
{
    delete d_ptr;
}

bool Does::init(const QVariantHash &args)
{
    Q_UNUSED(args)
    return true;
}

bool Does::execute(Context *ctx)
{
    Q_D(Does);

    if (d->proccessRoles) {
        Q_FOREACH (Does *does, d->beforeRoles) {
            if (!does->beforeExecute(ctx)) {
                return false;
            }
        }

        DoesCode code;
        code.execute = this;
        code.stack = d->aroundRoles;
        if (!aroundExecute(ctx, code)) {
            return false;
        }

        Q_FOREACH (Does *does, d->afterRoles) {
            if (!does->afterExecute(ctx)) {
                return false;
            }
        }
    }

    return doExecute(ctx);
}

bool Does::beforeExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

bool Does::aroundExecute(Context *ctx, Cutelyst::Does::DoesCode code) const
{
    Q_UNUSED(ctx)

    if (!code.stack.isEmpty()) {
        Does *does = code.stack.pop();
        return does->aroundExecute(ctx, code);
    }

    return code.execute->doExecute(ctx);
}

bool Does::afterExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

bool Does::doExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

void Does::applyRoles(const QStack<Cutelyst::Does *> &roles)
{
    Q_D(Does);

    for (int i = 0; i < roles.size(); ++i) {
        Does *does = roles.at(i);
        if (does->modifiers() & BeforeExecute) {
            d->beforeRoles.push(does);
        }

        if (does->modifiers() & AroundExecute) {
            d->aroundRoles.push(does);
        }

        if (does->modifiers() & AfterExecute) {
            d->afterRoles.push(does);
        }
    }
    d->roles = roles;
    d->proccessRoles = true;
}

bool Does::dispatcherReady(const Dispatcher *dispatch, Controller *controller)
{
    Q_D(Does);

    for (int i = 0; i < d->roles.size(); ++i) {
        Does *does = d->roles.at(i);
        does->dispatcherReady(dispatch, controller);
    }
    return true;
}
<commit_msg>Do not call doExecute twice on Does<commit_after>/*
 * Copyright (C) 2014 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "does_p.h"

using namespace Cutelyst;

Does::Does() :
    d_ptr(new DoesPrivate)
{
}

Does::~Does()
{
    delete d_ptr;
}

bool Does::init(const QVariantHash &args)
{
    Q_UNUSED(args)
    return true;
}

bool Does::execute(Context *ctx)
{
    Q_D(Does);

    if (d->proccessRoles) {
        Q_FOREACH (Does *does, d->beforeRoles) {
            if (!does->beforeExecute(ctx)) {
                return false;
            }
        }

        DoesCode code;
        code.execute = this;
        code.stack = d->aroundRoles;
        if (!aroundExecute(ctx, code)) {
            return false;
        }

        Q_FOREACH (Does *does, d->afterRoles) {
            if (!does->afterExecute(ctx)) {
                return false;
            }
        }

        // Do not call doExecute twice
        return true;
    }

    return doExecute(ctx);
}

bool Does::beforeExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

bool Does::aroundExecute(Context *ctx, Cutelyst::Does::DoesCode code) const
{
    Q_UNUSED(ctx)

    if (!code.stack.isEmpty()) {
        Does *does = code.stack.pop();
        return does->aroundExecute(ctx, code);
    }

    return code.execute->doExecute(ctx);
}

bool Does::afterExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

bool Does::doExecute(Context *ctx) const
{
    Q_UNUSED(ctx)
    return true;
}

void Does::applyRoles(const QStack<Cutelyst::Does *> &roles)
{
    Q_D(Does);

    for (int i = 0; i < roles.size(); ++i) {
        Does *does = roles.at(i);
        if (does->modifiers() & BeforeExecute) {
            d->beforeRoles.push(does);
        }

        if (does->modifiers() & AroundExecute) {
            d->aroundRoles.push(does);
        }

        if (does->modifiers() & AfterExecute) {
            d->afterRoles.push(does);
        }
    }
    d->roles = roles;
    d->proccessRoles = true;
}

bool Does::dispatcherReady(const Dispatcher *dispatch, Controller *controller)
{
    Q_D(Does);

    for (int i = 0; i < d->roles.size(); ++i) {
        Does *does = d->roles.at(i);
        does->dispatcherReady(dispatch, controller);
    }
    return true;
}
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

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

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

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

#include "Test/AbstractOpenGLTester.h"

#include <sstream>

#include "Context.h"
#include "DebugMessage.h"
#include "Extensions.h"

#ifdef MAGNUM_BUILD_DEPRECATED
#include "DebugMarker.h"
#endif

namespace Magnum { namespace Test {

class DebugGLTest: public AbstractOpenGLTester {
    public:
        explicit DebugGLTest();

        void insertMessageNoOp();
        void insertMessage();
        void insertMessageFallback();

        void deprecated();
};

DebugGLTest::DebugGLTest() {
    addTests({&DebugGLTest::insertMessageNoOp,
              &DebugGLTest::insertMessage,
              &DebugGLTest::insertMessageFallback,

              #ifdef MAGNUM_BUILD_DEPRECATED
              &DebugGLTest::deprecated
              #endif
              });
}

void DebugGLTest::insertMessageNoOp() {
    if(Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() ||
       Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_marker>() ||
       Context::current()->isExtensionSupported<Extensions::GL::GREMEDY::string_marker>())
        CORRADE_SKIP("The extensions are supported, cannot test.");

    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    MAGNUM_VERIFY_NO_ERROR();
}

void DebugGLTest::insertMessage() {
    if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>())
        CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported"));

    Renderer::setFeature(Renderer::Feature::DebugOutput, true);

    Renderer::setFeature(Renderer::Feature::DebugOutputSynchronous, true);
    std::ostringstream out;
    Debug::setOutput(&out);
    DebugMessage::setDefaultCallback();
    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    Renderer::setFeature(Renderer::Feature::DebugOutput, false);

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(out.str(),
        "DebugMessage::Source::Application DebugMessage::Type::Marker 1337 DebugMessage::Severity::Notification \n"
        "    Hello from OpenGL command stream!\n");
}

void DebugGLTest::insertMessageFallback() {
    if(Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() ||
     (!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_marker>() &&
      !Context::current()->isExtensionSupported<Extensions::GL::GREMEDY::string_marker>()))
        CORRADE_SKIP("No proper extension is supported");

    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    MAGNUM_VERIFY_NO_ERROR();
}

#ifdef MAGNUM_BUILD_DEPRECATED
void DebugGLTest::deprecated() {
    DebugMarker::mark("hello");

    MAGNUM_VERIFY_NO_ERROR();
}
#endif

}}

CORRADE_TEST_MAIN(Magnum::Test::DebugGLTest)
<commit_msg>Fixed compilation of test on ES2.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

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

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

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

#include "Test/AbstractOpenGLTester.h"

#include <sstream>

#include "Context.h"
#include "DebugMessage.h"
#include "Extensions.h"

#ifdef MAGNUM_BUILD_DEPRECATED
#include "DebugMarker.h"
#endif

namespace Magnum { namespace Test {

class DebugGLTest: public AbstractOpenGLTester {
    public:
        explicit DebugGLTest();

        void insertMessageNoOp();
        void insertMessage();
        void insertMessageFallback();

        void deprecated();
};

DebugGLTest::DebugGLTest() {
    addTests({&DebugGLTest::insertMessageNoOp,
              &DebugGLTest::insertMessage,
              &DebugGLTest::insertMessageFallback,

              #ifdef MAGNUM_BUILD_DEPRECATED
              &DebugGLTest::deprecated
              #endif
              });
}

void DebugGLTest::insertMessageNoOp() {
    if(Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() ||
       Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_marker>()
       #ifndef MAGNUM_TARGET_GLES
       || Context::current()->isExtensionSupported<Extensions::GL::GREMEDY::string_marker>()
       #endif
    )
        CORRADE_SKIP("The extensions are supported, cannot test.");

    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    MAGNUM_VERIFY_NO_ERROR();
}

void DebugGLTest::insertMessage() {
    if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>())
        CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported"));

    Renderer::setFeature(Renderer::Feature::DebugOutput, true);

    Renderer::setFeature(Renderer::Feature::DebugOutputSynchronous, true);
    std::ostringstream out;
    Debug::setOutput(&out);
    DebugMessage::setDefaultCallback();
    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    Renderer::setFeature(Renderer::Feature::DebugOutput, false);

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(out.str(),
        "DebugMessage::Source::Application DebugMessage::Type::Marker 1337 DebugMessage::Severity::Notification \n"
        "    Hello from OpenGL command stream!\n");
}

void DebugGLTest::insertMessageFallback() {
    if(Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() ||
     (!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_marker>()
   #ifndef MAGNUM_TARGET_GLES
   && !Context::current()->isExtensionSupported<Extensions::GL::GREMEDY::string_marker>()
   #endif
    ))
        CORRADE_SKIP("No proper extension is supported");

    DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker,
        1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!");

    MAGNUM_VERIFY_NO_ERROR();
}

#ifdef MAGNUM_BUILD_DEPRECATED
void DebugGLTest::deprecated() {
    DebugMarker::mark("hello");

    MAGNUM_VERIFY_NO_ERROR();
}
#endif

}}

CORRADE_TEST_MAIN(Magnum::Test::DebugGLTest)
<|endoftext|>


<commit_before>/*
 *    Copyright (c) <2002-2009> <Jean-Philippe Barrette-LaPierre>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files
 *    (curlpp), to deal in the Software without restriction,
 *    including without limitation the rights to use, copy, modify, merge,
 *    publish, distribute, sublicense, and/or sell copies of the Software,
 *    and to permit persons to whom the Software is furnished to do so,
 *    subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be included
 *    in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 *    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef CURLPP_CURLPP_HPP
#define CURLPP_CURLPP_HPP

#define LIBCURLPP_VERSION "0.7.3-pre2"
#define LIBCURLPP_VERSION_NUM 0x000703

#include "internal/buildconfig.h"

#include <curl/curl.h>

#include <string>
#include <cstdlib>

namespace curlpp
{

	/**
	* This function takes care of initializing curlpp (also libcURL).
	*
	* If you want to cleanup cURL before your application quits just call curlpp::terminate().
	* This function should only be called once (no matter how many threads or
	* libcurl sessions that'll be used) by every application that uses libcurl,
	* it will throw a logic_error if you call it twice.
	*
	* The flags option is a bit pattern that tells  libcurl  exact what  features
	* to init, as described below. Set the desired bits by ORing the values together.
	*
	* CURL_GLOBAL_ALL
	* Initialize  everything  possible.  This  sets all known bits.
	*
	* CURL_GLOBAL_SSL
	* Initialize SSL
	*
	* CURL_GLOBAL_WIN32
	* Initialize  the  Win32  socket  libraries.
	*
	* CURL_GLOBAL_NOTHING
	* Initialise nothing extra. This sets no bit.
	*
	* NOTE: you should never call this function twice.
	*/

	void CURLPPAPI initialize(long flags = CURL_GLOBAL_ALL);

	/**
	* This function takes care of cleaning up curlpp (also libcURL).
	*
	* See curlpp::initialize(long flags) for more documentation.
	* NOTE: you cannot call this function if curlpp is not loaded, or if you already
	* called in once; it will throw a logic_error if you do otherwise.
	*/

	void CURLPPAPI terminate();

	/**
	* \depreciated This is an obsolete class. DO NOT use it.
	*
	* The only reason it's still here,
	* is to be sure that it is backward compatible. This class was taking care of
	* initialization and cleaning up curlpp (also libcURL) (it was calling
	* curlpp:terminate() in his destructor). However, from now on, you do not need
	* this class. Note that the removal of this class was done because it was
	* raising some threading issues.
	*
	* Old documentation of that class:
	*
	* If you want to be sure that curlpp is cleaned up after you reached
	* the end of scope of a specific function using curlpp, instantiate
	* this class. This function call curlpp::initialize() in his
	* constructor, so you don't have to call it by yourself, when you have
	* decided to use it.
	*
	* See curlpp::initialize(long flags) and curlpp:terminate() for more documentation.
	*/

	class CURLPPAPI Cleanup
	{

	public:

		Cleanup();
		~Cleanup();

	};

	/**
	* URL encodes string.
	*
	* This  function  will  convert  the given input string to an URL encoded
	* string and return that as a new allocated string. All input  characters
	* that  are  not a-z, A-Z or 0-9 will be converted to their "URL escaped"
	* version (%NN where NN is a two-digit hexadecimal number).
	*/

	std::string CURLPPAPI escape(const std::string & url);

	/**
	* Decodes URL encoded string.
	*
	* This  function  will  convert  the  given  URL encoded input string to a
	* "plain string" and return that as a new allocated string. All input
	* characters that are URL encoded (%XX) where XX is a two-digit
	* hexadecimal number, or +) will be converted to their plain text versions
	* (up to a ? letter, no + letters to the right of a ? letter will be
	* converted).
	*/

	std::string CURLPPAPI unescape(const std::string & url);

	/**
	* Portable wrapper for the getenv() function.
	*
	* It's meant to emulate
	* its behaviour and provide an identical interface for all operating
	* systems libcurl builds on (including win32). Under unix operating
	* systems, there isn't any point in returning an allocated memory,
	* although other systems won't work  properly if this isn't done. The unix
	* implementation thus have to suffer slightly from the drawbacks of other
	* systems.
	*/

	std::string CURLPPAPI getenv(const std::string & name);

	/**
	* Returns  a  human readable string with the version number of libcurl and
	* some of its important components  (like  OpenSSL version).
	*
	* Note:  this  returns  the  actual running lib's version, you might have
	* installed a newer lib's include files in your system  which may turn
	* your LIBCURL_VERSION #define value to differ from this result.
	*/
	std::string CURLPPAPI libcurlVersion();

	/**
	* This function returns the number of  seconds  since  January 1st  1970,
	* for the date and time that the datestring parameter specifies. The now
	* parameter is there and should hold the current time to allow the
	* datestring to specify relative dates/times. Read further in the date
	* string parser section below.
	*
	* PARSING DATES AND TIMES
	* A  "date" is a string, possibly empty, containing many items separated
	* by whitespace.  The whitespace may be omitted when no ambiguity
	* arises.  The empty string means the beginning of today (i.e., midnight).
	* Order of the items is immaterial. A date string may contain many
	* flavors of items:
	*
	* calendar date items
	* This can be specified in a number of different ways. Including
	* 1970-09-17, 70-9-17, 70-09-17, 9/17/72, 24 September 1972, 24 Sept 72,
	* 24 Sep 72, Sep 24, 1972, 24-sep-72, 24sep72.  The year can also  be
	* omitted, for example: 9/17 or "sep 17".
	*
	* time of the day items
	* This  string specifies the time on a given day. Syntax supported
	* includes: 18:19:0, 18:19, 6:19pm, 18:19-0500 (for specifying the time
	* zone as well).
	*
	* time zone items
	* Specifies international time zone. There are a few acronyms
	* supported, but in general you should instead use the specific
	* realtive time compared to UTC. Supported formats include: -1200, MST,
	* +0100.
	*
	* day of the week items
	* Specifies a day of the week. If this is mentioned alone it means that
	* day of the week in the future. Days of the week may be spelled out in
	* full: `Sunday', `Monday', etc or they may be abbreviated to their
	* first three letters, optionally followed by a period. The special
	* abbreviations `Tues' for `Tuesday', `Wednes' for `Wednesday' and `Thur'
	* or `Thurs' for `Thursday' are also allowed. A number may precede a day
	* of the week item to move forward supplementary weeks. It is best
	* used in expression like `third monday'. In this context, `last DAY'
	* or `next DAY' is also acceptable; they move one week before or after
	* the day that DAY by itself would represent.
	*
	* relative items
	* A relative item adjusts a date (or the current date if none) forward
	* or backward. Example syntax includes: "1 year", "1 year ago",
	* "2 days", "4 weeks". The string `tomorrow' is worth one day in the
	* future (equivalent to `day'), the string `yesterday' is worth one
	* day in the past (equivalent to `day ago').
	*
	* pure numbers
	* If the decimal number is of the form YYYYMMDD and no other calendar date
	* item appears before it in the date string, then YYYY is read as
	* the year, MM as the month number and DD as the day of the month, for the
	* specified calendar date.
	*/

	time_t CURLPPAPI getdate(const std::string & date, time_t * now = 0);

} // namespace curlpp

namespace cURLpp = curlpp;

#endif // #ifndef CURLPP_CURLPP_HPP
<commit_msg>0.7.3<commit_after>/*
 *    Copyright (c) <2002-2009> <Jean-Philippe Barrette-LaPierre>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files
 *    (curlpp), to deal in the Software without restriction,
 *    including without limitation the rights to use, copy, modify, merge,
 *    publish, distribute, sublicense, and/or sell copies of the Software,
 *    and to permit persons to whom the Software is furnished to do so,
 *    subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be included
 *    in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 *    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef CURLPP_CURLPP_HPP
#define CURLPP_CURLPP_HPP

#define LIBCURLPP_VERSION "0.7.3"
#define LIBCURLPP_VERSION_NUM 0x000703

#include "internal/buildconfig.h"

#include <curl/curl.h>

#include <string>
#include <cstdlib>

namespace curlpp
{

	/**
	* This function takes care of initializing curlpp (also libcURL).
	*
	* If you want to cleanup cURL before your application quits just call curlpp::terminate().
	* This function should only be called once (no matter how many threads or
	* libcurl sessions that'll be used) by every application that uses libcurl,
	* it will throw a logic_error if you call it twice.
	*
	* The flags option is a bit pattern that tells  libcurl  exact what  features
	* to init, as described below. Set the desired bits by ORing the values together.
	*
	* CURL_GLOBAL_ALL
	* Initialize  everything  possible.  This  sets all known bits.
	*
	* CURL_GLOBAL_SSL
	* Initialize SSL
	*
	* CURL_GLOBAL_WIN32
	* Initialize  the  Win32  socket  libraries.
	*
	* CURL_GLOBAL_NOTHING
	* Initialise nothing extra. This sets no bit.
	*
	* NOTE: you should never call this function twice.
	*/

	void CURLPPAPI initialize(long flags = CURL_GLOBAL_ALL);

	/**
	* This function takes care of cleaning up curlpp (also libcURL).
	*
	* See curlpp::initialize(long flags) for more documentation.
	* NOTE: you cannot call this function if curlpp is not loaded, or if you already
	* called in once; it will throw a logic_error if you do otherwise.
	*/

	void CURLPPAPI terminate();

	/**
	* \depreciated This is an obsolete class. DO NOT use it.
	*
	* The only reason it's still here,
	* is to be sure that it is backward compatible. This class was taking care of
	* initialization and cleaning up curlpp (also libcURL) (it was calling
	* curlpp:terminate() in his destructor). However, from now on, you do not need
	* this class. Note that the removal of this class was done because it was
	* raising some threading issues.
	*
	* Old documentation of that class:
	*
	* If you want to be sure that curlpp is cleaned up after you reached
	* the end of scope of a specific function using curlpp, instantiate
	* this class. This function call curlpp::initialize() in his
	* constructor, so you don't have to call it by yourself, when you have
	* decided to use it.
	*
	* See curlpp::initialize(long flags) and curlpp:terminate() for more documentation.
	*/

	class CURLPPAPI Cleanup
	{

	public:

		Cleanup();
		~Cleanup();

	};

	/**
	* URL encodes string.
	*
	* This  function  will  convert  the given input string to an URL encoded
	* string and return that as a new allocated string. All input  characters
	* that  are  not a-z, A-Z or 0-9 will be converted to their "URL escaped"
	* version (%NN where NN is a two-digit hexadecimal number).
	*/

	std::string CURLPPAPI escape(const std::string & url);

	/**
	* Decodes URL encoded string.
	*
	* This  function  will  convert  the  given  URL encoded input string to a
	* "plain string" and return that as a new allocated string. All input
	* characters that are URL encoded (%XX) where XX is a two-digit
	* hexadecimal number, or +) will be converted to their plain text versions
	* (up to a ? letter, no + letters to the right of a ? letter will be
	* converted).
	*/

	std::string CURLPPAPI unescape(const std::string & url);

	/**
	* Portable wrapper for the getenv() function.
	*
	* It's meant to emulate
	* its behaviour and provide an identical interface for all operating
	* systems libcurl builds on (including win32). Under unix operating
	* systems, there isn't any point in returning an allocated memory,
	* although other systems won't work  properly if this isn't done. The unix
	* implementation thus have to suffer slightly from the drawbacks of other
	* systems.
	*/

	std::string CURLPPAPI getenv(const std::string & name);

	/**
	* Returns  a  human readable string with the version number of libcurl and
	* some of its important components  (like  OpenSSL version).
	*
	* Note:  this  returns  the  actual running lib's version, you might have
	* installed a newer lib's include files in your system  which may turn
	* your LIBCURL_VERSION #define value to differ from this result.
	*/
	std::string CURLPPAPI libcurlVersion();

	/**
	* This function returns the number of  seconds  since  January 1st  1970,
	* for the date and time that the datestring parameter specifies. The now
	* parameter is there and should hold the current time to allow the
	* datestring to specify relative dates/times. Read further in the date
	* string parser section below.
	*
	* PARSING DATES AND TIMES
	* A  "date" is a string, possibly empty, containing many items separated
	* by whitespace.  The whitespace may be omitted when no ambiguity
	* arises.  The empty string means the beginning of today (i.e., midnight).
	* Order of the items is immaterial. A date string may contain many
	* flavors of items:
	*
	* calendar date items
	* This can be specified in a number of different ways. Including
	* 1970-09-17, 70-9-17, 70-09-17, 9/17/72, 24 September 1972, 24 Sept 72,
	* 24 Sep 72, Sep 24, 1972, 24-sep-72, 24sep72.  The year can also  be
	* omitted, for example: 9/17 or "sep 17".
	*
	* time of the day items
	* This  string specifies the time on a given day. Syntax supported
	* includes: 18:19:0, 18:19, 6:19pm, 18:19-0500 (for specifying the time
	* zone as well).
	*
	* time zone items
	* Specifies international time zone. There are a few acronyms
	* supported, but in general you should instead use the specific
	* realtive time compared to UTC. Supported formats include: -1200, MST,
	* +0100.
	*
	* day of the week items
	* Specifies a day of the week. If this is mentioned alone it means that
	* day of the week in the future. Days of the week may be spelled out in
	* full: `Sunday', `Monday', etc or they may be abbreviated to their
	* first three letters, optionally followed by a period. The special
	* abbreviations `Tues' for `Tuesday', `Wednes' for `Wednesday' and `Thur'
	* or `Thurs' for `Thursday' are also allowed. A number may precede a day
	* of the week item to move forward supplementary weeks. It is best
	* used in expression like `third monday'. In this context, `last DAY'
	* or `next DAY' is also acceptable; they move one week before or after
	* the day that DAY by itself would represent.
	*
	* relative items
	* A relative item adjusts a date (or the current date if none) forward
	* or backward. Example syntax includes: "1 year", "1 year ago",
	* "2 days", "4 weeks". The string `tomorrow' is worth one day in the
	* future (equivalent to `day'), the string `yesterday' is worth one
	* day in the past (equivalent to `day ago').
	*
	* pure numbers
	* If the decimal number is of the form YYYYMMDD and no other calendar date
	* item appears before it in the date string, then YYYY is read as
	* the year, MM as the month number and DD as the day of the month, for the
	* specified calendar date.
	*/

	time_t CURLPPAPI getdate(const std::string & date, time_t * now = 0);

} // namespace curlpp

namespace cURLpp = curlpp;

#endif // #ifndef CURLPP_CURLPP_HPP
<|endoftext|>