<commit_before>/*
===============================================================================

  FILE:  mydefs.hpp

  CONTENTS:

    Basic data type definitions and operations to be robust across platforms.

  PROGRAMMERS:

    martin.isenburg@rapidlasso.com  -  http://rapidlasso.com

  COPYRIGHT:

    (c) 2005-2015, martin isenburg, rapidlasso - fast tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    28 October 2015 -- adding DLL bindings via 'COMPILE_AS_DLL' and 'USE_AS_DLL'
    10 January 2011 -- licensing change for LGPL release and libLAS integration
    13 July 2005 -- created after returning with many mosquito bites from OBX

===============================================================================
*/
#ifndef MYDEFS_HPP
#define MYDEFS_HPP

#ifndef _WIN32
#define LASLIB_DLL
#else  // _WIN32
#ifdef COMPILE_AS_DLL
#define LASLIB_DLL __declspec(dllexport)
#elif USE_AS_DLL
#define LASLIB_DLL __declspec(dllimport)
#else
#define LASLIB_DLL
#endif
#endif // _WIN32

typedef char               CHAR;

typedef int                I32;
typedef short              I16;
typedef char               I8;

typedef unsigned int       U32;
typedef unsigned short     U16;
typedef unsigned char      U8;

#if defined(_WIN32) && ! defined (__MINGW32__) // 64 byte integer under Windows
typedef unsigned __int64   U64;
typedef __int64            I64;
#else                                          // 64 byte integer elsewhere ...
typedef unsigned long long U64;
typedef long long          I64;
#endif

typedef float              F32;
typedef double             F64;

#if defined(_MSC_VER) && (_MSC_VER < 1300) || defined (__MINGW32__)
typedef int                BOOL;
#else
typedef bool               BOOL;
#endif

typedef union U32I32F32 { U32 u32; I32 i32; F32 f32; } U32I32F32;
typedef union U64I64F64 { U64 u64; I64 i64; F64 f64; } U64I64F64;

#define F32_MAX            +2.0e+37f
#define F32_MIN            -2.0e+37f

#define F64_MAX            +2.0e+307
#define F64_MIN            -2.0e+307

#define U8_MIN             ((U8)0x0)  // 0
#define U8_MAX             ((U8)0xFF) // 255
#define U8_MAX_MINUS_ONE   ((U8)0xFE) // 254
#define U8_MAX_PLUS_ONE    0x0100     // 256

#define U16_MIN            ((U16)0x0)    // 0
#define U16_MAX            ((U16)0xFFFF) // 65535
#define U16_MAX_MINUS_ONE  ((U16)0xFFFE) // 65534
#define U16_MAX_PLUS_ONE   0x00010000    // 65536

#define U32_MIN            ((U32)0x0)            // 0
#define U32_MAX            ((U32)0xFFFFFFFF)     // 4294967295
#define U32_MAX_MINUS_ONE  ((U32)0xFFFFFFFE)     // 4294967294
#if defined(WIN32)            // 64 byte unsigned int constant under Windows
#define U32_MAX_PLUS_ONE   0x0000000100000000    // 4294967296
#else                         // 64 byte unsigned int constant elsewhere ...
#define U32_MAX_PLUS_ONE   0x0000000100000000ull // 4294967296
#endif

#define I8_MIN             ((I8)0x80) // -128
#define I8_MAX             ((I8)0x7F) // 127

#define I16_MIN            ((I16)0x8000) // -32768
#define I16_MAX            ((I16)0x7FFF) // 32767

#define I32_MIN            ((I32)0x80000000) // -2147483648
#define I32_MAX            ((I32)0x7FFFFFFF) //  2147483647

#define I64_MIN            ((I64)0x8000000000000000)
#define I64_MAX            ((I64)0x7FFFFFFFFFFFFFFF)

#define U8_FOLD(n)      (((n) < U8_MIN) ? (n+U8_MAX_PLUS_ONE) : (((n) > U8_MAX) ? (n-U8_MAX_PLUS_ONE) : (n)))

#define I8_CLAMP(n)     (((n) <= I8_MIN) ? I8_MIN : (((n) >= I8_MAX) ? I8_MAX : ((I8)(n))))
#define U8_CLAMP(n)     (((n) <= U8_MIN) ? U8_MIN : (((n) >= U8_MAX) ? U8_MAX : ((U8)(n))))

#define I16_CLAMP(n)    (((n) <= I16_MIN) ? I16_MIN : (((n) >= I16_MAX) ? I16_MAX : ((I16)(n))))
#define U16_CLAMP(n)    (((n) <= U16_MIN) ? U16_MIN : (((n) >= U16_MAX) ? U16_MAX : ((U16)(n))))

#define I32_CLAMP(n)    (((n) <= I32_MIN) ? I32_MIN : (((n) >= I32_MAX) ? I32_MAX : ((I32)(n))))
#define U32_CLAMP(n)    (((n) <= U32_MIN) ? U32_MIN : (((n) >= U32_MAX) ? U32_MAX : ((U32)(n))))

#define I8_QUANTIZE(n) (((n) >= 0) ? (I8)((n)+0.5f) : (I8)((n)-0.5f))
#define U8_QUANTIZE(n) (((n) >= 0) ? (U8)((n)+0.5f) : (U8)(0))

#define I16_QUANTIZE(n) (((n) >= 0) ? (I16)((n)+0.5f) : (I16)((n)-0.5f))
#define U16_QUANTIZE(n) (((n) >= 0) ? (U16)((n)+0.5f) : (U16)(0))

#define I32_QUANTIZE(n) (((n) >= 0) ? (I32)((n)+0.5f) : (I32)((n)-0.5f))
#define U32_QUANTIZE(n) (((n) >= 0) ? (U32)((n)+0.5f) : (U32)(0))

#define I64_QUANTIZE(n) (((n) >= 0) ? (I64)((n)+0.5f) : (I64)((n)-0.5f))
#define U64_QUANTIZE(n) (((n) >= 0) ? (U64)((n)+0.5f) : (U64)(0))

#define I16_FLOOR(n) ((((I16)(n)) > (n)) ? (((I16)(n))-1) : ((I16)(n)))
#define I32_FLOOR(n) ((((I32)(n)) > (n)) ? (((I32)(n))-1) : ((I32)(n)))
#define I64_FLOOR(n) ((((I64)(n)) > (n)) ? (((I64)(n))-1) : ((I64)(n)))

#define I16_CEIL(n) ((((I16)(n)) < (n)) ? (((I16)(n))+1) : ((I16)(n)))
#define I32_CEIL(n) ((((I32)(n)) < (n)) ? (((I32)(n))+1) : ((I32)(n)))
#define I64_CEIL(n) ((((I64)(n)) < (n)) ? (((I64)(n))+1) : ((I64)(n)))

#define I8_FITS_IN_RANGE(n) (((n) >= I8_MIN) && ((n) <= I8_MAX) ? TRUE : FALSE)
#define U8_FITS_IN_RANGE(n) (((n) >= U8_MIN) && ((n) <= U8_MAX) ? TRUE : FALSE)
#define I16_FITS_IN_RANGE(n) (((n) >= I16_MIN) && ((n) <= I16_MAX) ? TRUE : FALSE)
#define U16_FITS_IN_RANGE(n) (((n) >= U16_MIN) && ((n) <= U16_MAX) ? TRUE : FALSE)
#define I32_FITS_IN_RANGE(n) (((n) >= I32_MIN) && ((n) <= I32_MAX) ? TRUE : FALSE)
#define U32_FITS_IN_RANGE(n) (((n) >= U32_MIN) && ((n) <= U32_MAX) ? TRUE : FALSE)

#define F32_IS_FINITE(n) ((F32_MIN < (n)) && ((n) < F32_MAX))
#define F64_IS_FINITE(n) ((F64_MIN < (n)) && ((n) < F64_MAX))

#define U32_ZERO_BIT_0(n) (((n)&(U32)0xFFFFFFFE))
#define U32_ZERO_BIT_0_1(n) (((n)&(U32)0xFFFFFFFC))

#ifndef FALSE
#define FALSE   0
#endif

#ifndef TRUE
#define TRUE    1
#endif

#ifndef NULL
#define NULL    0
#endif

inline BOOL IS_LITTLE_ENDIAN()
{
  const U32 i = 1;
  return (*((U8*)&i) == 1);
}

#define ENDIANSWAP16(n) \
	( ((((U16) n) << 8) & 0xFF00) | \
	  ((((U16) n) >> 8) & 0x00FF) )

#define ENDIANSWAP32(n) \
	( ((((U32) n) << 24) & 0xFF000000) |	\
	  ((((U32) n) <<  8) & 0x00FF0000) |	\
	  ((((U32) n) >>  8) & 0x0000FF00) |	\
	  ((((U32) n) >> 24) & 0x000000FF) )

inline void ENDIAN_SWAP_16(U8* field)
{
  U8 help = field[0];
  field[0] = field[1];
  field[1] = help;
}

inline void ENDIAN_SWAP_32(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[3];
  field[3] = help;
  help = field[1];
  field[1] = field[2];
  field[2] = help;
}

inline void ENDIAN_SWAP_64(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[7];
  field[7] = help;
  help = field[1];
  field[1] = field[6];
  field[6] = help;
  help = field[2];
  field[2] = field[5];
  field[5] = help;
  help = field[3];
  field[3] = field[4];
  field[4] = help;
}

inline void ENDIAN_SWAP_16(const U8* from, U8* to)
{
  to[0] = from[1];
  to[1] = from[0];
}

inline void ENDIAN_SWAP_32(const U8* from, U8* to)
{
  to[0] = from[3];
  to[1] = from[2];
  to[2] = from[1];
  to[3] = from[0];
}

inline void ENDIAN_SWAP_64(const U8* from, U8* to)
{
  to[0] = from[7];
  to[1] = from[6];
  to[2] = from[5];
  to[3] = from[4];
  to[4] = from[3];
  to[5] = from[2];
  to[6] = from[1];
  to[7] = from[0];
}

#endif
<commit_msg>minor changes (and line ending test)<commit_after>/*
===============================================================================

  FILE:  mydefs.hpp

  CONTENTS:

    Basic data type definitions and operations to be robust across platforms.

  PROGRAMMERS:

    martin.isenburg@rapidlasso.com  -  http://rapidlasso.com

  COPYRIGHT:

    (c) 2005-2015, martin isenburg, rapidlasso - fast tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    28 October 2015 -- adding DLL bindings via 'COMPILE_AS_DLL' and 'USE_AS_DLL'
    10 January 2011 -- licensing change for LGPL release and libLAS integration
    13 July 2005 -- created after returning with many mosquito bites from OBX

===============================================================================
*/
#ifndef MYDEFS_HPP
#define MYDEFS_HPP

#ifndef _WIN32
#define LASLIB_DLL
#else  // _WIN32
#ifdef COMPILE_AS_DLL
#define LASLIB_DLL __declspec(dllexport)
#elif USE_AS_DLL
#define LASLIB_DLL __declspec(dllimport)
#else
#define LASLIB_DLL
#endif
#endif // _WIN32

typedef char               CHAR;

typedef int                I32;
typedef short              I16;
typedef char               I8;

typedef unsigned int       U32;
typedef unsigned short     U16;
typedef unsigned char      U8;

#if defined(_WIN32) && ! defined (__MINGW32__) // 64 byte integer under Windows
typedef unsigned __int64   U64;
typedef __int64            I64;
#else                                          // 64 byte integer elsewhere ...
typedef unsigned long long U64;
typedef long long          I64;
#endif

typedef float              F32;
typedef double             F64;

#if defined(_MSC_VER) || defined (__MINGW32__)
typedef int                BOOL;
#else
typedef bool               BOOL;
#endif

typedef union U32I32F32 { U32 u32; I32 i32; F32 f32; } U32I32F32;
typedef union U64I64F64 { U64 u64; I64 i64; F64 f64; } U64I64F64;
typedef union I64U32I32F32 { I64 i64; U32 u32[2]; I32 i32[2]; F32 f32[2]; } I64U32I32F32;

#define F32_MAX            +2.0e+37f
#define F32_MIN            -2.0e+37f

#define F64_MAX            +2.0e+307
#define F64_MIN            -2.0e+307

#define U8_MIN             ((U8)0x0)  // 0
#define U8_MAX             ((U8)0xFF) // 255
#define U8_MAX_MINUS_ONE   ((U8)0xFE) // 254
#define U8_MAX_PLUS_ONE    0x0100     // 256

#define U16_MIN            ((U16)0x0)    // 0
#define U16_MAX            ((U16)0xFFFF) // 65535
#define U16_MAX_MINUS_ONE  ((U16)0xFFFE) // 65534
#define U16_MAX_PLUS_ONE   0x00010000    // 65536

#define U32_MIN            ((U32)0x0)            // 0
#define U32_MAX            ((U32)0xFFFFFFFF)     // 4294967295
#define U32_MAX_MINUS_ONE  ((U32)0xFFFFFFFE)     // 4294967294
#if defined(WIN32)            // 64 byte unsigned int constant under Windows
#define U32_MAX_PLUS_ONE   0x0000000100000000    // 4294967296
#else                         // 64 byte unsigned int constant elsewhere ...
#define U32_MAX_PLUS_ONE   0x0000000100000000ull // 4294967296
#endif

#define I8_MIN             ((I8)0x80) // -128
#define I8_MAX             ((I8)0x7F) // 127

#define I16_MIN            ((I16)0x8000) // -32768
#define I16_MAX            ((I16)0x7FFF) // 32767

#define I32_MIN            ((I32)0x80000000) // -2147483648
#define I32_MAX            ((I32)0x7FFFFFFF) //  2147483647

#define I64_MIN            ((I64)0x8000000000000000)
#define I64_MAX            ((I64)0x7FFFFFFFFFFFFFFF)

#define U8_FOLD(n)      (((n) < U8_MIN) ? (n+U8_MAX_PLUS_ONE) : (((n) > U8_MAX) ? (n-U8_MAX_PLUS_ONE) : (n)))

#define I8_CLAMP(n)     (((n) <= I8_MIN) ? I8_MIN : (((n) >= I8_MAX) ? I8_MAX : ((I8)(n))))
#define U8_CLAMP(n)     (((n) <= U8_MIN) ? U8_MIN : (((n) >= U8_MAX) ? U8_MAX : ((U8)(n))))

#define I16_CLAMP(n)    (((n) <= I16_MIN) ? I16_MIN : (((n) >= I16_MAX) ? I16_MAX : ((I16)(n))))
#define U16_CLAMP(n)    (((n) <= U16_MIN) ? U16_MIN : (((n) >= U16_MAX) ? U16_MAX : ((U16)(n))))

#define I32_CLAMP(n)    (((n) <= I32_MIN) ? I32_MIN : (((n) >= I32_MAX) ? I32_MAX : ((I32)(n))))
#define U32_CLAMP(n)    (((n) <= U32_MIN) ? U32_MIN : (((n) >= U32_MAX) ? U32_MAX : ((U32)(n))))

#define I8_QUANTIZE(n) (((n) >= 0) ? (I8)((n)+0.5f) : (I8)((n)-0.5f))
#define U8_QUANTIZE(n) (((n) >= 0) ? (U8)((n)+0.5f) : (U8)(0))

#define I16_QUANTIZE(n) (((n) >= 0) ? (I16)((n)+0.5f) : (I16)((n)-0.5f))
#define U16_QUANTIZE(n) (((n) >= 0) ? (U16)((n)+0.5f) : (U16)(0))

#define I32_QUANTIZE(n) (((n) >= 0) ? (I32)((n)+0.5f) : (I32)((n)-0.5f))
#define U32_QUANTIZE(n) (((n) >= 0) ? (U32)((n)+0.5f) : (U32)(0))

#define I64_QUANTIZE(n) (((n) >= 0) ? (I64)((n)+0.5f) : (I64)((n)-0.5f))
#define U64_QUANTIZE(n) (((n) >= 0) ? (U64)((n)+0.5f) : (U64)(0))

#define I16_FLOOR(n) ((((I16)(n)) > (n)) ? (((I16)(n))-1) : ((I16)(n)))
#define I32_FLOOR(n) ((((I32)(n)) > (n)) ? (((I32)(n))-1) : ((I32)(n)))
#define I64_FLOOR(n) ((((I64)(n)) > (n)) ? (((I64)(n))-1) : ((I64)(n)))

#define I16_CEIL(n) ((((I16)(n)) < (n)) ? (((I16)(n))+1) : ((I16)(n)))
#define I32_CEIL(n) ((((I32)(n)) < (n)) ? (((I32)(n))+1) : ((I32)(n)))
#define I64_CEIL(n) ((((I64)(n)) < (n)) ? (((I64)(n))+1) : ((I64)(n)))

#define I8_FITS_IN_RANGE(n) (((n) >= I8_MIN) && ((n) <= I8_MAX) ? TRUE : FALSE)
#define U8_FITS_IN_RANGE(n) (((n) >= U8_MIN) && ((n) <= U8_MAX) ? TRUE : FALSE)
#define I16_FITS_IN_RANGE(n) (((n) >= I16_MIN) && ((n) <= I16_MAX) ? TRUE : FALSE)
#define U16_FITS_IN_RANGE(n) (((n) >= U16_MIN) && ((n) <= U16_MAX) ? TRUE : FALSE)
#define I32_FITS_IN_RANGE(n) (((n) >= I32_MIN) && ((n) <= I32_MAX) ? TRUE : FALSE)
#define U32_FITS_IN_RANGE(n) (((n) >= U32_MIN) && ((n) <= U32_MAX) ? TRUE : FALSE)

#define F32_IS_FINITE(n) ((F32_MIN < (n)) && ((n) < F32_MAX))
#define F64_IS_FINITE(n) ((F64_MIN < (n)) && ((n) < F64_MAX))

#define U32_ZERO_BIT_0(n) (((n)&(U32)0xFFFFFFFE))
#define U32_ZERO_BIT_0_1(n) (((n)&(U32)0xFFFFFFFC))

#ifndef FALSE
#define FALSE   0
#endif

#ifndef TRUE
#define TRUE    1
#endif

#ifndef NULL
#define NULL    0
#endif

inline BOOL IS_LITTLE_ENDIAN()
{
  const U32 i = 1;
  return (*((U8*)&i) == 1);
}

#define ENDIANSWAP16(n) \
	( ((((U16) n) << 8) & 0xFF00) | \
	  ((((U16) n) >> 8) & 0x00FF) )

#define ENDIANSWAP32(n) \
	( ((((U32) n) << 24) & 0xFF000000) |	\
	  ((((U32) n) <<  8) & 0x00FF0000) |	\
	  ((((U32) n) >>  8) & 0x0000FF00) |	\
	  ((((U32) n) >> 24) & 0x000000FF) )

inline void ENDIAN_SWAP_16(U8* field)
{
  U8 help = field[0];
  field[0] = field[1];
  field[1] = help;
}

inline void ENDIAN_SWAP_32(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[3];
  field[3] = help;
  help = field[1];
  field[1] = field[2];
  field[2] = help;
}

inline void ENDIAN_SWAP_64(U8* field)
{
  U8 help;
  help = field[0];
  field[0] = field[7];
  field[7] = help;
  help = field[1];
  field[1] = field[6];
  field[6] = help;
  help = field[2];
  field[2] = field[5];
  field[5] = help;
  help = field[3];
  field[3] = field[4];
  field[4] = help;
}

inline void ENDIAN_SWAP_16(const U8* from, U8* to)
{
  to[0] = from[1];
  to[1] = from[0];
}

inline void ENDIAN_SWAP_32(const U8* from, U8* to)
{
  to[0] = from[3];
  to[1] = from[2];
  to[2] = from[1];
  to[3] = from[0];
}

inline void ENDIAN_SWAP_64(const U8* from, U8* to)
{
  to[0] = from[7];
  to[1] = from[6];
  to[2] = from[5];
  to[3] = from[4];
  to[4] = from[3];
  to[5] = from[2];
  to[6] = from[1];
  to[7] = from[0];
}

#endif
<|endoftext|>


<commit_before>// Copyright 2015 Toggl Desktop developers.

#include "../src/netconf.h"

#include <string>
#include <sstream>

#include "./https_client.h"

#include "Poco/Environment.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPCredentials.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "Poco/UnicodeConverter.h"

#ifdef __MACH__
#include <CoreFoundation/CoreFoundation.h>  // NOLINT
#include <CoreServices/CoreServices.h>  // NOLINT
#endif

#ifdef _WIN32
#include <winhttp.h>
#pragma comment(lib, "winhttp")
#endif

namespace toggl {

error Netconf::autodetectProxy(
    const std::string encoded_url,
    std::vector<std::string> *proxy_strings) {

    poco_assert(proxy_strings);

    proxy_strings->clear();

    if (encoded_url.empty()) {
        return noError;
    }

#ifdef _WIN32
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = { 0 };
    if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
        std::stringstream ss;
        ss << "WinHttpGetIEProxyConfigForCurrentUser error: "
           << GetLastError();
        return ss.str();
    }
    if (ie_config.lpszProxy) {
        std::wstring proxy_url_wide(ie_config.lpszProxy);
        std::string s("");
        Poco::UnicodeConverter::toUTF8(proxy_url_wide, s);
        proxy_strings->push_back(s);
    }
#endif

    // Inspired by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/darwin/netconf.c
#ifdef __MACH__
    CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
    if (NULL != dicRef) {
        const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPProxy);
        const CFNumberRef portCFnum = (const CFNumberRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPPort);
        if (NULL != proxyCFstr && NULL != portCFnum) {
            int port = 0;
            if (!CFNumberGetValue(portCFnum, kCFNumberIntType, &port)) {
                CFRelease(dicRef);
                return noError;
            }

            const std::size_t kBufsize(4096);
            char host_buffer[kBufsize];
            memset(host_buffer, 0, sizeof(host_buffer));
            if (CFStringGetCString(proxyCFstr, host_buffer, sizeof(host_buffer)
                                   - 1, kCFStringEncodingUTF8)) {
                char buffer[kBufsize];
                snprintf(buffer, kBufsize, "%s:%d", host_buffer, port);
                proxy_strings->push_back(std::string(buffer));
            }
        }

        CFRelease(dicRef);
    }
#endif

    // Inspired by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/posix/netconf.c
#ifdef __linux__

    posix_spawn_file_actions_t actions;
    posix_spawn_file_actions_init(&actions);
    posix_spawn_file_actions_addopen(&actions, STDIN_FILENO, "/dev/null",
                                     O_RDONLY, 0644);
    int fd[2];
    posix_spawn_file_actions_adddup2(&actions, fd[1], STDOUT_FILENO);

    posix_spawnattr_init(&attr);
    {
        sigset_t set;
        sigemptyset(&set);

        posix_spawnattr_t attr;
        posix_spawnattr_setsigmask(&attr, &set);
        sigaddset(&set, SIGPIPE);
        posix_spawnattr_setsigdefault(&attr, &set);
        posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF
                                 | POSIX_SPAWN_SETSIGMASK);
    }

    pid_t pid;
    char *argv[3] = { const_cast<char *>("proxy"),
                      const_cast<char *>(encoded_url.c_str()), NULL
                    };
    if (posix_spawnp(&pid, "proxy", &actions, &attr, argv, environ)) {
        pid = -1;
    }

    posix_spawnattr_destroy(&attr);
    posix_spawn_file_actions_destroy(&actions);
    close(fd[1]);

    if (-1 == pid) {
        close(fd[0]);
        return error("Failed to run proxy command")
    }

           char buf[1024];
    size_t len = 0;
    do {
        ssize_t val = read(fd[0], buf + len, sizeof (buf) - len);
        if (val <= 0) {
            break;
        }
        len += val;
    } while (len < sizeof (buf));

    close(fd[0]);

    while (true) {
        int status = {0};
        if (-1 != waitpid(pid, &status, 0) == -1) {
            break;
        }
    }

    if (len >= 9 && !strncasecmp(buf, "direct://", 9)) {
        return noError;
    }

    char *end = memchr(buf, '\n', len);
    if (end != NULL) {
        *end = '\0';
        proxy_strings->push_back(std::string(buf));
    }
#endif

    return noError;
}

error Netconf::ConfigureProxy(
    const std::string encoded_url,
    Poco::Net::HTTPSClientSession *session) {

    Poco::Logger &logger = Poco::Logger::get("ConfigureProxy");

    std::string proxy_url("");
    if (HTTPSClient::Config.AutodetectProxy) {
        if (Poco::Environment::has("HTTP_PROXY")) {
            proxy_url = Poco::Environment::get("HTTP_PROXY");
        }
        if (Poco::Environment::has("http_proxy")) {
            proxy_url = Poco::Environment::get("http_proxy");
        }
        if (proxy_url.empty()) {
            std::vector<std::string> proxy_strings;
            error err = autodetectProxy(encoded_url, &proxy_strings);
            if (err != noError) {
                return err;
            }
            // FIXME: libproxy will return array of proxy strings
            if (!proxy_strings.empty()) {
                proxy_url = proxy_strings[0];
            }
        }
        if (proxy_url.find("://") == std::string::npos) {
            proxy_url = "http://" + proxy_url;
        }
        Poco::URI proxy_uri(proxy_url);

        std::stringstream ss;
        ss << "Proxy detected URI=" + proxy_uri.toString()
           << " host=" << proxy_uri.getHost()
           << " port=" << proxy_uri.getPort();
        logger.debug(ss.str());

        session->setProxy(
            proxy_uri.getHost(),
            proxy_uri.getPort());

        if (!proxy_uri.getUserInfo().empty()) {
            Poco::Net::HTTPCredentials credentials;
            credentials.fromUserInfo(proxy_uri.getUserInfo());
            session->setProxyCredentials(
                credentials.getUsername(),
                credentials.getPassword());

            logger.debug("Proxy credentials detected username="
                         + credentials.getUsername());
        }
    }

    // Try to use user-configured proxy
    if (proxy_url.empty() && HTTPSClient::Config.UseProxy &&
            HTTPSClient::Config.ProxySettings.IsConfigured()) {
        session->setProxy(
            HTTPSClient::Config.ProxySettings.Host(),
            static_cast<Poco::UInt16>(
                HTTPSClient::Config.ProxySettings.Port()));

        std::stringstream ss;
        ss << "Proxy configured "
           << " host=" << HTTPSClient::Config.ProxySettings.Host()
           << " port=" << HTTPSClient::Config.ProxySettings.Port();
        logger.debug(ss.str());

        if (HTTPSClient::Config.ProxySettings.HasCredentials()) {
            session->setProxyCredentials(
                HTTPSClient::Config.ProxySettings.Username(),
                HTTPSClient::Config.ProxySettings.Password());

            logger.debug("Proxy credentials configured username="
                         + HTTPSClient::Config.ProxySettings.Username());
        }
    }

    return noError;
}

}   // namespace toggl
<commit_msg>Linux proxy developments (linux)<commit_after>// Copyright 2015 Toggl Desktop developers.

#include "../src/netconf.h"

#include <string>
#include <sstream>

#include "./https_client.h"

#include "Poco/Environment.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPCredentials.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "Poco/UnicodeConverter.h"

#ifdef __MACH__
#include <CoreFoundation/CoreFoundation.h>  // NOLINT
#include <CoreServices/CoreServices.h>  // NOLINT
#endif

#ifdef _WIN32
#include <winhttp.h>
#pragma comment(lib, "winhttp")
#endif

#ifdef __linux__
#include <sys/types.h>
#include <sys/wait.h>
#include <spawn.h>
#endif

namespace toggl {

error Netconf::autodetectProxy(
    const std::string encoded_url,
    std::vector<std::string> *proxy_strings) {

    poco_assert(proxy_strings);

    proxy_strings->clear();

    if (encoded_url.empty()) {
        return noError;
    }

#ifdef _WIN32
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = { 0 };
    if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
        std::stringstream ss;
        ss << "WinHttpGetIEProxyConfigForCurrentUser error: "
           << GetLastError();
        return ss.str();
    }
    if (ie_config.lpszProxy) {
        std::wstring proxy_url_wide(ie_config.lpszProxy);
        std::string s("");
        Poco::UnicodeConverter::toUTF8(proxy_url_wide, s);
        proxy_strings->push_back(s);
    }
#endif

    // Inspired by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/darwin/netconf.c
#ifdef __MACH__
    CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
    if (NULL != dicRef) {
        const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPProxy);
        const CFNumberRef portCFnum = (const CFNumberRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPPort);
        if (NULL != proxyCFstr && NULL != portCFnum) {
            int port = 0;
            if (!CFNumberGetValue(portCFnum, kCFNumberIntType, &port)) {
                CFRelease(dicRef);
                return noError;
            }

            const std::size_t kBufsize(4096);
            char host_buffer[kBufsize];
            memset(host_buffer, 0, sizeof(host_buffer));
            if (CFStringGetCString(proxyCFstr, host_buffer, sizeof(host_buffer)
                                   - 1, kCFStringEncodingUTF8)) {
                char buffer[kBufsize];
                snprintf(buffer, kBufsize, "%s:%d", host_buffer, port);
                proxy_strings->push_back(std::string(buffer));
            }
        }

        CFRelease(dicRef);
    }
#endif

    // Inspired by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/posix/netconf.c
#ifdef __linux__

    posix_spawn_file_actions_t actions;
    posix_spawn_file_actions_init(&actions);
    posix_spawn_file_actions_addopen(&actions, STDIN_FILENO, "/dev/null",
                                     O_RDONLY, 0644);
    int fd[2];
    posix_spawn_file_actions_adddup2(&actions, fd[1], STDOUT_FILENO);

    posix_spawnattr_t attr;
    posix_spawnattr_init(&attr);
    {
        sigset_t set;
        sigemptyset(&set);

        posix_spawnattr_setsigmask(&attr, &set);
        sigaddset(&set, SIGPIPE);
        posix_spawnattr_setsigdefault(&attr, &set);
        posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF
                                 | POSIX_SPAWN_SETSIGMASK);
    }

    pid_t pid;
    char *argv[3] = { const_cast<char *>("proxy"),
                      const_cast<char *>(encoded_url.c_str()), NULL
                    };
    if (posix_spawnp(&pid, "proxy", &actions, &attr, argv, environ)) {
        pid = -1;
    }

    posix_spawnattr_destroy(&attr);
    posix_spawn_file_actions_destroy(&actions);
    close(fd[1]);

    if (-1 == pid) {
        close(fd[0]);
        return error("Failed to run proxy command");
    }

    char buf[1024];
    size_t len = 0;
    do {
        ssize_t val = read(fd[0], buf + len, sizeof (buf) - len);
        if (val <= 0) {
            break;
        }
        len += val;
    } while (len < sizeof (buf));

    close(fd[0]);

    while (true) {
        int status = {0};
        if (-1 != waitpid(pid, &status, 0)) {
            break;
        }
    }

    if (len >= 9 && !strncasecmp(buf, "direct://", 9)) {
        return noError;
    }

    char *end = (char *)memchr(buf, '\n', len);
    if (end != NULL) {
        *end = '\0';
        proxy_strings->push_back(std::string(buf));
    }
#endif

    return noError;
}

error Netconf::ConfigureProxy(
    const std::string encoded_url,
    Poco::Net::HTTPSClientSession *session) {

    Poco::Logger &logger = Poco::Logger::get("ConfigureProxy");

    std::string proxy_url("");
    if (HTTPSClient::Config.AutodetectProxy) {
        if (Poco::Environment::has("HTTPS_PROXY")) {
            proxy_url = Poco::Environment::get("HTTPS_PROXY");
        }
        if (Poco::Environment::has("https_proxy")) {
            proxy_url = Poco::Environment::get("https_proxy");
        }
        if (Poco::Environment::has("HTTP_PROXY")) {
            proxy_url = Poco::Environment::get("HTTP_PROXY");
        }
        if (Poco::Environment::has("http_proxy")) {
            proxy_url = Poco::Environment::get("http_proxy");
        }
        if (proxy_url.empty()) {
            std::vector<std::string> proxy_strings;
            error err = autodetectProxy(encoded_url, &proxy_strings);
            if (err != noError) {
                return err;
            }
            if (!proxy_strings.empty()) {
                proxy_url = proxy_strings[0];
            }
        }

	if (!proxy_url.empty()) {
		if (proxy_url.find("://") == std::string::npos) {
		    proxy_url = "http://" + proxy_url;
		}
		Poco::URI proxy_uri(proxy_url);

		std::stringstream ss;
		ss << "Using proxy URI=" + proxy_uri.toString()
		   << " host=" << proxy_uri.getHost()
		   << " port=" << proxy_uri.getPort();
		logger.debug(ss.str());

		session->setProxy(
		    proxy_uri.getHost(),
		    proxy_uri.getPort());

		if (!proxy_uri.getUserInfo().empty()) {
		    Poco::Net::HTTPCredentials credentials;
		    credentials.fromUserInfo(proxy_uri.getUserInfo());
		    session->setProxyCredentials(
			credentials.getUsername(),
			credentials.getPassword());

		    logger.debug("Proxy credentials detected username="
				 + credentials.getUsername());
		}
	}
    }

    // Try to use user-configured proxy
    if (proxy_url.empty() && HTTPSClient::Config.UseProxy &&
            HTTPSClient::Config.ProxySettings.IsConfigured()) {
        session->setProxy(
            HTTPSClient::Config.ProxySettings.Host(),
            static_cast<Poco::UInt16>(
                HTTPSClient::Config.ProxySettings.Port()));

        std::stringstream ss;
        ss << "Proxy configured "
           << " host=" << HTTPSClient::Config.ProxySettings.Host()
           << " port=" << HTTPSClient::Config.ProxySettings.Port();
        logger.debug(ss.str());

        if (HTTPSClient::Config.ProxySettings.HasCredentials()) {
            session->setProxyCredentials(
                HTTPSClient::Config.ProxySettings.Username(),
                HTTPSClient::Config.ProxySettings.Password());

            logger.debug("Proxy credentials configured username="
                         + HTTPSClient::Config.ProxySettings.Username());
        }
    }

    return noError;
}

}   // namespace toggl
<|endoftext|>


<commit_before>/*
// $Id$
// Fennel is a library of data storage and processing components.
// Copyright (C) 2005-2009 The Eigenbase Project
// Copyright (C) 2005-2009 SQLstream, Inc.
// Copyright (C) 2005-2009 LucidEra, Inc.
// Portions Copyright (C) 2004-2009 John V. Sichi
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version approved by The Eigenbase Project.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "fennel/common/CommonPreamble.h"
#include "fennel/exec/ExecStreamGovernor.h"
#include "fennel/common/StatsTarget.h"

FENNEL_BEGIN_CPPFILE("$Id$");

using std::string;
using std::ostream;
using std::endl;

ExecStreamGovernor::ExecStreamGovernor(
    ExecStreamResourceKnobs const &knobSettingsInit,
    ExecStreamResourceQuantity const &resourcesAvailableInit,
    SharedTraceTarget pTraceTargetInit,
    string nameInit)
    : TraceSource(pTraceTargetInit, nameInit)
{
    knobSettings.cacheReservePercentage =
        knobSettingsInit.cacheReservePercentage;
    knobSettings.expectedConcurrentStatements =
        knobSettingsInit.expectedConcurrentStatements;

    resourcesAvailable.nCachePages =
        resourcesAvailableInit.nCachePages
        * (100 - knobSettings.cacheReservePercentage) / 100;
    resourcesAssigned.nCachePages = 0;
}

inline ostream& operator<< (ostream& os, const ExecStreamGovernor& gov)
{
    gov.print(os);
    return os;
}

ExecStreamGovernor::~ExecStreamGovernor()
{
    if (!resourceMap.empty()) {
        FENNEL_TRACE(
            TRACE_SEVERE,
            "ExecStreamGovernor deleted still holding resources; " << *this);
        assert(false);
    }
}

void ExecStreamGovernor::traceCachePageRequest(
    uint assigned,
    ExecStreamResourceRequirements const &reqt,
    string const &name)
{
    switch (reqt.optType) {
    case EXEC_RESOURCE_ACCURATE:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on accurate (min,opt) request of " << "("
            << reqt.minReqt << "," << reqt.optReqt << ") pages");
        break;
    case EXEC_RESOURCE_ESTIMATE:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on estimated (min,opt) request of " << "("
            << reqt.minReqt << "," << reqt.optReqt << ") pages");
        break;
    case EXEC_RESOURCE_UNBOUNDED:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on an unbounded opt request with "
            << reqt.minReqt << " min pages");
    }
}

void ExecStreamGovernor::writeStats(StatsTarget &target)
{
    StrictMutexGuard mutexGuard(mutex);
    target.writeCounter(
        "ExpectedConcurrentStatements",
        knobSettings.expectedConcurrentStatements);
    target.writeCounter(
        "CacheReservePercentage",
        knobSettings.cacheReservePercentage);
    target.writeCounter(
        "CachePagesGoverned",
        resourcesAvailable.nCachePages);
    target.writeCounter(
        "CachePagesReserved",
        resourcesAssigned.nCachePages);
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceKnobs& k)
{
    os << " expectedConcurrentStatements=" << k.expectedConcurrentStatements;
    os << " cacheReservePercentage=" << k.cacheReservePercentage;
    return os;
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceQuantity& q)
{
    os << " nThreads=" << q.nThreads;
    os << " nCachePages=" << q.nCachePages;
    return os;
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceType t)
{
    switch (t) {
    case EXEC_RESOURCE_THREADS:
        return os << "threads";
    case EXEC_RESOURCE_CACHE_PAGES:
        return os << "cache pages";
    default:
        return os << "??";
    }
}

inline ostream& operator<< (
    ostream& os, const ExecStreamResourceRequirements& req)
{
    os << req.optType << " min=" << req.minReqt << " opt=" << req.optReqt;
    return os;
}

void ExecStreamGovernor::print(ostream& os) const
{
    os << "knobs: " << knobSettings << endl;
    os << "resources available: " << resourcesAvailable << endl;
    os << "resources assigned:  " << resourcesAssigned << endl;
    os << "resource map: {" << endl;
    for (ExecStreamGraphResourceMap::const_iterator
             p = resourceMap.begin(); p != resourceMap.end(); ++p)
    {
        os << "  stream graph " << p->first
           << " => (" << *(p->second) << ")" << endl;
    }
    os << "}" << endl;
}

FENNEL_END_CPPFILE("$Id$");

// End ExecStreamGovernor.cpp
<commit_msg>FENNEL: If ExecStreamGovernor deleted still holding resources, trace as SEVERE but don't assert.<commit_after>/*
// $Id$
// Fennel is a library of data storage and processing components.
// Copyright (C) 2005-2009 The Eigenbase Project
// Copyright (C) 2005-2009 SQLstream, Inc.
// Copyright (C) 2005-2009 LucidEra, Inc.
// Portions Copyright (C) 2004-2009 John V. Sichi
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version approved by The Eigenbase Project.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "fennel/common/CommonPreamble.h"
#include "fennel/exec/ExecStreamGovernor.h"
#include "fennel/common/StatsTarget.h"

FENNEL_BEGIN_CPPFILE("$Id$");

using std::string;
using std::ostream;
using std::endl;

ExecStreamGovernor::ExecStreamGovernor(
    ExecStreamResourceKnobs const &knobSettingsInit,
    ExecStreamResourceQuantity const &resourcesAvailableInit,
    SharedTraceTarget pTraceTargetInit,
    string nameInit)
    : TraceSource(pTraceTargetInit, nameInit)
{
    knobSettings.cacheReservePercentage =
        knobSettingsInit.cacheReservePercentage;
    knobSettings.expectedConcurrentStatements =
        knobSettingsInit.expectedConcurrentStatements;

    resourcesAvailable.nCachePages =
        resourcesAvailableInit.nCachePages
        * (100 - knobSettings.cacheReservePercentage) / 100;
    resourcesAssigned.nCachePages = 0;
}

inline ostream& operator<< (ostream& os, const ExecStreamGovernor& gov)
{
    gov.print(os);
    return os;
}

ExecStreamGovernor::~ExecStreamGovernor()
{
    if (!resourceMap.empty()) {
        FENNEL_TRACE(
            TRACE_SEVERE,
            "ExecStreamGovernor deleted still holding resources; " << *this);
        // REVIEW mb 7/09: this resource leak is not an irrecoverable condition,
        // so do not abort,
        // assert(false);
    }
}

void ExecStreamGovernor::traceCachePageRequest(
    uint assigned,
    ExecStreamResourceRequirements const &reqt,
    string const &name)
{
    switch (reqt.optType) {
    case EXEC_RESOURCE_ACCURATE:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on accurate (min,opt) request of " << "("
            << reqt.minReqt << "," << reqt.optReqt << ") pages");
        break;
    case EXEC_RESOURCE_ESTIMATE:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on estimated (min,opt) request of " << "("
            << reqt.minReqt << "," << reqt.optReqt << ") pages");
        break;
    case EXEC_RESOURCE_UNBOUNDED:
        FENNEL_TRACE(
            TRACE_FINER,
            "Stream " << name << " assigned " << assigned
            << " pages based on an unbounded opt request with "
            << reqt.minReqt << " min pages");
    }
}

void ExecStreamGovernor::writeStats(StatsTarget &target)
{
    StrictMutexGuard mutexGuard(mutex);
    target.writeCounter(
        "ExpectedConcurrentStatements",
        knobSettings.expectedConcurrentStatements);
    target.writeCounter(
        "CacheReservePercentage",
        knobSettings.cacheReservePercentage);
    target.writeCounter(
        "CachePagesGoverned",
        resourcesAvailable.nCachePages);
    target.writeCounter(
        "CachePagesReserved",
        resourcesAssigned.nCachePages);
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceKnobs& k)
{
    os << " expectedConcurrentStatements=" << k.expectedConcurrentStatements;
    os << " cacheReservePercentage=" << k.cacheReservePercentage;
    return os;
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceQuantity& q)
{
    os << " nThreads=" << q.nThreads;
    os << " nCachePages=" << q.nCachePages;
    return os;
}

inline ostream& operator<< (ostream& os, const ExecStreamResourceType t)
{
    switch (t) {
    case EXEC_RESOURCE_THREADS:
        return os << "threads";
    case EXEC_RESOURCE_CACHE_PAGES:
        return os << "cache pages";
    default:
        return os << "??";
    }
}

inline ostream& operator<< (
    ostream& os, const ExecStreamResourceRequirements& req)
{
    os << req.optType << " min=" << req.minReqt << " opt=" << req.optReqt;
    return os;
}

void ExecStreamGovernor::print(ostream& os) const
{
    os << "knobs: " << knobSettings << endl;
    os << "resources available: " << resourcesAvailable << endl;
    os << "resources assigned:  " << resourcesAssigned << endl;
    os << "resource map: {" << endl;
    for (ExecStreamGraphResourceMap::const_iterator
             p = resourceMap.begin(); p != resourceMap.end(); ++p)
    {
        os << "  stream graph " << p->first
           << " => (" << *(p->second) << ")" << endl;
    }
    os << "}" << endl;
}

FENNEL_END_CPPFILE("$Id$");

// End ExecStreamGovernor.cpp
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "FileChooser.h"

#include "Document.h"
#include "FrameView.h"
#include "Icon.h"
#include "LocalizedStrings.h"
#include "RenderObject.h"
#include "RenderThemeWin.h"
#include "RenderView.h"
#include "StringTruncator.h"
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>

namespace WebCore {

void FileChooser::openFileChooser(Document* document)
{
    FrameView* view = document->view();
    if (!view)
        return;

    TCHAR fileBuf[MAX_PATH];
    OPENFILENAME ofn;

    memset(&ofn, 0, sizeof(ofn));

    // Need to zero out the first char of fileBuf so GetOpenFileName doesn't think it's an initialization string
    fileBuf[0] = '\0';

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = view->hostWindow()->platformWindow();
    String allFiles = allFilesText();
    allFiles.append(TEXT("\0*.*\0\0"), 6);
    ofn.lpstrFilter = allFiles.charactersWithNullTermination();
    ofn.lpstrFile = fileBuf;
    ofn.nMaxFile = sizeof(fileBuf);
    String dialogTitle = uploadFileText();
    ofn.lpstrTitle = dialogTitle.charactersWithNullTermination();
    ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;

    // We need this protector because otherwise we can be deleted if the file upload control is detached while
    // we're within the GetOpenFileName call.
    RefPtr<FileChooser> protector(this);

    if (GetOpenFileName(&ofn))
        chooseFile(String(fileBuf));
}

String FileChooser::basenameForWidth(const Font& font, int width) const
{
    if (width <= 0)
        return String();

    String string;
    if (m_filename.isEmpty())
        string = fileButtonNoFileSelectedLabel();
    else {
        String tmpFilename = m_filename;
        LPTSTR basename = PathFindFileName(tmpFilename.charactersWithNullTermination());
        string = String(basename);
    }

    return StringTruncator::centerTruncate(string, width, font, false);
}

}<commit_msg>Fix Win bustage.<commit_after>/*
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "FileChooser.h"

#include "Document.h"
#include "FrameView.h"
#include "HostWindow.h"
#include "Icon.h"
#include "LocalizedStrings.h"
#include "RenderObject.h"
#include "RenderThemeWin.h"
#include "RenderView.h"
#include "StringTruncator.h"
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>

namespace WebCore {

void FileChooser::openFileChooser(Document* document)
{
    FrameView* view = document->view();
    if (!view)
        return;

    TCHAR fileBuf[MAX_PATH];
    OPENFILENAME ofn;

    memset(&ofn, 0, sizeof(ofn));

    // Need to zero out the first char of fileBuf so GetOpenFileName doesn't think it's an initialization string
    fileBuf[0] = '\0';

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = view->hostWindow()->platformWindow();
    String allFiles = allFilesText();
    allFiles.append(TEXT("\0*.*\0\0"), 6);
    ofn.lpstrFilter = allFiles.charactersWithNullTermination();
    ofn.lpstrFile = fileBuf;
    ofn.nMaxFile = sizeof(fileBuf);
    String dialogTitle = uploadFileText();
    ofn.lpstrTitle = dialogTitle.charactersWithNullTermination();
    ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;

    // We need this protector because otherwise we can be deleted if the file upload control is detached while
    // we're within the GetOpenFileName call.
    RefPtr<FileChooser> protector(this);

    if (GetOpenFileName(&ofn))
        chooseFile(String(fileBuf));
}

String FileChooser::basenameForWidth(const Font& font, int width) const
{
    if (width <= 0)
        return String();

    String string;
    if (m_filename.isEmpty())
        string = fileButtonNoFileSelectedLabel();
    else {
        String tmpFilename = m_filename;
        LPTSTR basename = PathFindFileName(tmpFilename.charactersWithNullTermination());
        string = String(basename);
    }

    return StringTruncator::centerTruncate(string, width, font, false);
}

}<|endoftext|>


<commit_before>/* -*- c++ -*- */
/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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 <assert.h>
#include "s_expression.h"

s_symbol::s_symbol(const char *str, size_t n)
{
   /* Assume the given string is already nul-terminated and in memory that
    * will live as long as this node.
    */
   assert(str[n] == '\0');
   this->str = str;
}

s_list::s_list()
{
}

static void
skip_whitespace(const char *&src, char *&symbol_buffer)
{
   size_t n = strspn(src, " \v\t\r\n");
   src += n;
   symbol_buffer += n;
   /* Also skip Scheme-style comments: semi-colon 'til end of line */
   if (src[0] == ';') {
      n = strcspn(src, "\n");
      src += n;
      symbol_buffer += n;
      skip_whitespace(src, symbol_buffer);
   }
}

static s_expression *
read_atom(void *ctx, const char *&src, char *&symbol_buffer)
{
   s_expression *expr = NULL;

   skip_whitespace(src, symbol_buffer);

   size_t n = strcspn(src, "( \v\t\r\n);");
   if (n == 0)
      return NULL; // no atom

   // Check if the atom is a number.
   char *float_end = NULL;
   double f = glsl_strtod(src, &float_end);
   if (float_end != src) {
      char *int_end = NULL;
      int i = strtol(src, &int_end, 10);
      // If strtod matched more characters, it must have a decimal part
      if (float_end > int_end)
	 expr = new(ctx) s_float(f);
      else
	 expr = new(ctx) s_int(i);
   } else {
      // Not a number; return a symbol.
      symbol_buffer[n] = '\0';
      expr = new(ctx) s_symbol(symbol_buffer, n);
   }

   src += n;
   symbol_buffer += n;

   return expr;
}

static s_expression *
__read_expression(void *ctx, const char *&src, char *&symbol_buffer)
{
   s_expression *atom = read_atom(ctx, src, symbol_buffer);
   if (atom != NULL)
      return atom;

   skip_whitespace(src, symbol_buffer);
   if (src[0] == '(') {
      ++src;
      ++symbol_buffer;

      s_list *list = new(ctx) s_list;
      s_expression *expr;

      while ((expr = __read_expression(ctx, src, symbol_buffer)) != NULL) {
	 list->subexpressions.push_tail(expr);
      }
      skip_whitespace(src, symbol_buffer);
      if (src[0] != ')') {
	 printf("Unclosed expression (check your parenthesis).\n");
	 return NULL;
      }
      ++src;
      ++symbol_buffer;
      return list;
   }
   return NULL;
}

s_expression *
s_expression::read_expression(void *ctx, const char *&src)
{
   assert(src != NULL);

   /* When we encounter a Symbol, we need to save a nul-terminated copy of
    * the string.  However, ralloc_strndup'ing every individual Symbol is
    * extremely expensive.  We could avoid this by simply overwriting the
    * next character (guaranteed to be whitespace, parens, or semicolon) with
    * a nul-byte.  But overwriting non-whitespace would mess up parsing.
    *
    * So, just copy the whole buffer ahead of time.  Walk both, leaving the
    * original source string unmodified, and altering the copy to contain the
    * necessary nul-bytes whenever we encounter a symbol.
    */
   char *symbol_buffer = ralloc_strdup(ctx, src);
   return __read_expression(ctx, src, symbol_buffer);
}

void s_int::print()
{
   printf("%d", this->val);
}

void s_float::print()
{
   printf("%f", this->val);
}

void s_symbol::print()
{
   printf("%s", this->str);
}

void s_list::print()
{
   printf("(");
   foreach_iter(exec_list_iterator, it, this->subexpressions) {
      s_expression *expr = (s_expression*) it.get();
      expr->print();
      if (!expr->next->is_tail_sentinel())
	 printf(" ");
   }
   printf(")");
}

// --------------------------------------------------

bool
s_pattern::match(s_expression *expr)
{
   switch (type)
   {
   case EXPR:   *p_expr = expr; break;
   case LIST:   if (expr->is_list())   *p_list   = (s_list *)   expr; break;
   case SYMBOL: if (expr->is_symbol()) *p_symbol = (s_symbol *) expr; break;
   case NUMBER: if (expr->is_number()) *p_number = (s_number *) expr; break;
   case INT:    if (expr->is_int())    *p_int    = (s_int *)    expr; break;
   case STRING:
      s_symbol *sym = SX_AS_SYMBOL(expr);
      if (sym != NULL && strcmp(sym->value(), literal) == 0)
	 return true;
      return false;
   };

   return *p_expr == expr;
}

bool
s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
{
   s_list *list = SX_AS_LIST(top);
   if (list == NULL)
      return false;

   unsigned i = 0;
   foreach_iter(exec_list_iterator, it, list->subexpressions) {
      if (i >= n)
	 return partial; /* More actual items than the pattern expected */

      s_expression *expr = (s_expression *) it.get();
      if (expr == NULL || !pattern[i].match(expr))
	 return false;

      i++;
   }

   if (i < n)
      return false; /* Less actual items than the pattern expected */

   return true;
}
<commit_msg>glsl: Fix isinf() for non-C99-compliant compilers.<commit_after>/* -*- c++ -*- */
/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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 <assert.h>
#include <limits>
#include "s_expression.h"

s_symbol::s_symbol(const char *str, size_t n)
{
   /* Assume the given string is already nul-terminated and in memory that
    * will live as long as this node.
    */
   assert(str[n] == '\0');
   this->str = str;
}

s_list::s_list()
{
}

static void
skip_whitespace(const char *&src, char *&symbol_buffer)
{
   size_t n = strspn(src, " \v\t\r\n");
   src += n;
   symbol_buffer += n;
   /* Also skip Scheme-style comments: semi-colon 'til end of line */
   if (src[0] == ';') {
      n = strcspn(src, "\n");
      src += n;
      symbol_buffer += n;
      skip_whitespace(src, symbol_buffer);
   }
}

static s_expression *
read_atom(void *ctx, const char *&src, char *&symbol_buffer)
{
   s_expression *expr = NULL;

   skip_whitespace(src, symbol_buffer);

   size_t n = strcspn(src, "( \v\t\r\n);");
   if (n == 0)
      return NULL; // no atom

   // Check for the special symbol '+INF', which means +Infinity.  Note: C99
   // requires strtod to parse '+INF' as +Infinity, but we still support some
   // non-C99-compliant compilers (e.g. MSVC).
   if (n == 4 && strncmp(src, "+INF", 4) == 0) {
      expr = new(ctx) s_float(std::numeric_limits<float>::infinity());
   } else {
      // Check if the atom is a number.
      char *float_end = NULL;
      double f = glsl_strtod(src, &float_end);
      if (float_end != src) {
         char *int_end = NULL;
         int i = strtol(src, &int_end, 10);
         // If strtod matched more characters, it must have a decimal part
         if (float_end > int_end)
            expr = new(ctx) s_float(f);
         else
            expr = new(ctx) s_int(i);
      } else {
         // Not a number; return a symbol.
         symbol_buffer[n] = '\0';
         expr = new(ctx) s_symbol(symbol_buffer, n);
      }
   }

   src += n;
   symbol_buffer += n;

   return expr;
}

static s_expression *
__read_expression(void *ctx, const char *&src, char *&symbol_buffer)
{
   s_expression *atom = read_atom(ctx, src, symbol_buffer);
   if (atom != NULL)
      return atom;

   skip_whitespace(src, symbol_buffer);
   if (src[0] == '(') {
      ++src;
      ++symbol_buffer;

      s_list *list = new(ctx) s_list;
      s_expression *expr;

      while ((expr = __read_expression(ctx, src, symbol_buffer)) != NULL) {
	 list->subexpressions.push_tail(expr);
      }
      skip_whitespace(src, symbol_buffer);
      if (src[0] != ')') {
	 printf("Unclosed expression (check your parenthesis).\n");
	 return NULL;
      }
      ++src;
      ++symbol_buffer;
      return list;
   }
   return NULL;
}

s_expression *
s_expression::read_expression(void *ctx, const char *&src)
{
   assert(src != NULL);

   /* When we encounter a Symbol, we need to save a nul-terminated copy of
    * the string.  However, ralloc_strndup'ing every individual Symbol is
    * extremely expensive.  We could avoid this by simply overwriting the
    * next character (guaranteed to be whitespace, parens, or semicolon) with
    * a nul-byte.  But overwriting non-whitespace would mess up parsing.
    *
    * So, just copy the whole buffer ahead of time.  Walk both, leaving the
    * original source string unmodified, and altering the copy to contain the
    * necessary nul-bytes whenever we encounter a symbol.
    */
   char *symbol_buffer = ralloc_strdup(ctx, src);
   return __read_expression(ctx, src, symbol_buffer);
}

void s_int::print()
{
   printf("%d", this->val);
}

void s_float::print()
{
   printf("%f", this->val);
}

void s_symbol::print()
{
   printf("%s", this->str);
}

void s_list::print()
{
   printf("(");
   foreach_iter(exec_list_iterator, it, this->subexpressions) {
      s_expression *expr = (s_expression*) it.get();
      expr->print();
      if (!expr->next->is_tail_sentinel())
	 printf(" ");
   }
   printf(")");
}

// --------------------------------------------------

bool
s_pattern::match(s_expression *expr)
{
   switch (type)
   {
   case EXPR:   *p_expr = expr; break;
   case LIST:   if (expr->is_list())   *p_list   = (s_list *)   expr; break;
   case SYMBOL: if (expr->is_symbol()) *p_symbol = (s_symbol *) expr; break;
   case NUMBER: if (expr->is_number()) *p_number = (s_number *) expr; break;
   case INT:    if (expr->is_int())    *p_int    = (s_int *)    expr; break;
   case STRING:
      s_symbol *sym = SX_AS_SYMBOL(expr);
      if (sym != NULL && strcmp(sym->value(), literal) == 0)
	 return true;
      return false;
   };

   return *p_expr == expr;
}

bool
s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
{
   s_list *list = SX_AS_LIST(top);
   if (list == NULL)
      return false;

   unsigned i = 0;
   foreach_iter(exec_list_iterator, it, list->subexpressions) {
      if (i >= n)
	 return partial; /* More actual items than the pattern expected */

      s_expression *expr = (s_expression *) it.get();
      if (expr == NULL || !pattern[i].match(expr))
	 return false;

      i++;
   }

   if (i < n)
      return false; /* Less actual items than the pattern expected */

   return true;
}
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 <stdio.h>

#include "mnv2_cfu.h"
#include "mnv2_conv.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tf_util/print_params.h"

#ifdef DUMP_CONV
#include "b64_util.h"
#endif

namespace tflite {
namespace reference_integer_ops {

// Fixed-point per-channel-quantization convolution reference kernel.
void ConvPerChannel(const ConvParams& params, const int32_t* output_multiplier,
                    const int32_t* output_shift,
                    const RuntimeShape& input_shape, const int8_t* input_data,
                    const RuntimeShape& filter_shape, const int8_t* filter_data,
                    const RuntimeShape& bias_shape, const int32_t* bias_data,
                    const RuntimeShape& output_shape, int8_t* output_data) {
#ifdef SHOW_CONV_PARAMS
  print_conv_params(params, input_shape, filter_shape, output_shape);
#endif
  // Get parameters.
  const int32_t input_offset = params.input_offset;  // r = s(q - Z)
  const int stride_width = params.stride_width;
  const int stride_height = params.stride_height;
  const int dilation_width_factor = params.dilation_width_factor;
  const int dilation_height_factor = params.dilation_height_factor;
  const int pad_width = params.padding_values.width;
  const int pad_height = params.padding_values.height;
  const int32_t output_offset = params.output_offset;

  // Set min and max value of the output.
  const int32_t output_activation_min = params.quantized_activation_min;
  const int32_t output_activation_max = params.quantized_activation_max;

  // Consistency check.
  TFLITE_DCHECK_LE(output_activation_min, output_activation_max);
  TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4);
  const int batches = MatchingDim(input_shape, 0, output_shape, 0);
  const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3);
  const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3);
  if (bias_data) {
    TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth);
  }

  // Check dimensions of the tensors.
  const int input_height = input_shape.Dims(1);
  const int input_width = input_shape.Dims(2);
  const int filter_height = filter_shape.Dims(1);
  const int filter_width = filter_shape.Dims(2);
  const int output_height = output_shape.Dims(1);
  const int output_width = output_shape.Dims(2);

#ifdef ACCEL_CONV
  if (pad_width == 0 && pad_height == 0 && dilation_width_factor == 1 &&
      dilation_height_factor == 1 &&  // params.weights_offset == 0 &&
      output_activation_min == -128 && output_activation_max == 127 &&
      batches == 1) {
    if (params.stride_width == 1 && params.stride_height == 1 &&
        input_height == output_height && input_width == output_width &&
        filter_height == 1 && filter_width == 1 && bias_data &&
        input_depth < MAX_CONV_INPUT_BYTES && (input_depth % 8) == 0 &&
        (output_depth % 8) == 0) {
      Mnv2ConvPerChannel1x1(params, output_multiplier, output_shift,
                            input_shape, input_data, filter_shape, filter_data,
                            bias_shape, bias_data, output_shape, output_data);
      return;
    }
  }
#endif

#ifdef DUMP_CONV
  if (filter_shape.FlatSize() == 2304) {
    puts("\n\nDumping conv op");
    puts("-----\nparams");
    b64_dump((const int8_t*)(const void*)&params, sizeof(params));
    puts("-----\noutput_multiplier");
    b64_dump((const int8_t*)output_multiplier, output_depth * sizeof(uint32_t));
    puts("-----\noutput_shift");
    b64_dump((const int8_t*)output_shift, output_depth * sizeof(uint32_t));
    puts("-----\ninput_shape");
    b64_dump((const int8_t*)(const void*)&input_shape, sizeof(input_shape));
    puts("-----\ninput_data");
    b64_dump(input_data, input_shape.FlatSize());
    puts("-----\nfilter_shape");
    b64_dump((const int8_t*)(const void*)&filter_shape, sizeof(filter_shape));
    puts("-----\nfilter_data");
    b64_dump(filter_data, filter_shape.FlatSize());
    puts("-----\nbias_shape");
    b64_dump((const int8_t*)(const void*)&bias_shape, sizeof(bias_shape));
    puts("-----\nbias_data");
    b64_dump((const int8_t*)bias_data, output_depth * sizeof(uint32_t));
  }
#endif

  for (int batch = 0; batch < batches; ++batch) {
    for (int out_y = 0; out_y < output_height; ++out_y) {
      const int in_y_origin = (out_y * stride_height) - pad_height;
      for (int out_x = 0; out_x < output_width; ++out_x) {
        const int in_x_origin = (out_x * stride_width) - pad_width;
        for (int out_channel = 0; out_channel < output_depth; ++out_channel) {
          int32_t acc = 0;
          for (int filter_y = 0; filter_y < filter_height; ++filter_y) {
            const int in_y = in_y_origin + dilation_height_factor * filter_y;
            for (int filter_x = 0; filter_x < filter_width; ++filter_x) {
              const int in_x = in_x_origin + dilation_width_factor * filter_x;

              // Zero padding by omitting the areas outside the image.
              const bool is_point_inside_image =
                  (in_x >= 0) && (in_x < input_width) && (in_y >= 0) &&
                  (in_y < input_height);

              if (!is_point_inside_image) {
                continue;
              }

              for (int in_channel = 0; in_channel < input_depth; ++in_channel) {
                int32_t input_val = input_data[Offset(input_shape, batch, in_y,
                                                      in_x, in_channel)];
                int32_t filter_val = filter_data[Offset(
                    filter_shape, out_channel, filter_y, filter_x, in_channel)];
                // Accumulate with 32 bits accumulator.
                // In the nudging process during model quantization, we force
                // real value of 0.0 be represented by a quantized value. This
                // guarantees that the input_offset is a int8_t, even though
                // it is represented using int32_t. int32_t += int8_t *
                // (int8_t - int8_t) so the highest value we can get from each
                // accumulation is [-127, 127] * ([-128, 127] -
                // [-128, 127]), which is [-32512, 32512]. log2(32512)
                // = 14.98, which means we can accumulate at least 2^16
                // multiplications without overflow. The accumulator is
                // applied to a filter so the accumulation logic will hold as
                // long as the filter size (filter_y * filter_x * in_channel)
                // does not exceed 2^16, which is the case in all the models
                // we have seen so far.
                // TODO(jianlijianli): Add a check to make sure the
                // accumulator depth is smaller than 2^16.
                acc += filter_val * (input_val + input_offset);
              }
            }
          }
#if SHOW_SAMPLE_POST_PROCESSING
          static uint32_t count = 0;
          if ((count & (1024 * 128 - 1)) == 0) {
            printf("(%ld, %ld, %ld, %ld, %ld, %ld, %ld), ", acc,
                   bias_data[out_channel], output_multiplier[out_channel],
                   output_shift[out_channel], output_offset,
                   output_activation_min, output_activation_max);
          }
#endif

          if (bias_data) {
            acc += bias_data[out_channel];
          }
          acc = MultiplyByQuantizedMultiplier(
              acc, output_multiplier[out_channel], output_shift[out_channel]);
          acc += output_offset;
          acc = std::max(acc, output_activation_min);
          acc = std::min(acc, output_activation_max);
          output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] =
              static_cast<int8_t>(acc);

#if SHOW_SAMPLE_POST_PROCESSING
          if ((count & (1024 * 128 - 1)) == 0) {
            printf("%ld\n", acc);
          }
          count++;
#endif
        }
      }
    }
  }
#ifdef DUMP_CONV
  if (filter_shape.FlatSize() == 2304) {
    puts("-----\noutput_shape");
    b64_dump((const int8_t*)(const void*)&output_shape, sizeof(output_shape));
    puts("-----\noutput_data");
    b64_dump(output_data, output_shape.FlatSize());
    puts("-----\n");
  }
#endif
}

// Fixed-point per-channel-quantization convolution reference kernel.
// 16-bit data and 8-bit filter
void ConvPerChannel(const ConvParams& params, const int32_t* output_multiplier,
                    const int32_t* output_shift,
                    const RuntimeShape& input_shape, const int16_t* input_data,
                    const RuntimeShape& filter_shape, const int8_t* filter_data,
                    const RuntimeShape& bias_shape,
                    const std::int64_t* bias_data,
                    const RuntimeShape& output_shape, int16_t* output_data) {
  // Get parameters.
  const int stride_width = params.stride_width;
  const int stride_height = params.stride_height;
  const int dilation_width_factor = params.dilation_width_factor;
  const int dilation_height_factor = params.dilation_height_factor;
  const int pad_width = params.padding_values.width;
  const int pad_height = params.padding_values.height;

  // Set min and max value of the output.
  const int32_t output_activation_min = params.quantized_activation_min;
  const int32_t output_activation_max = params.quantized_activation_max;

  // Consistency check.
  TFLITE_DCHECK_LE(output_activation_min, output_activation_max);
  TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4);
  const int batches = MatchingDim(input_shape, 0, output_shape, 0);
  const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3);
  const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3);
  if (bias_data) {
    TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth);
  }

  // Check dimensions of the tensors.
  const int input_height = input_shape.Dims(1);
  const int input_width = input_shape.Dims(2);
  const int filter_height = filter_shape.Dims(1);
  const int filter_width = filter_shape.Dims(2);
  const int output_height = output_shape.Dims(1);
  const int output_width = output_shape.Dims(2);
  for (int batch = 0; batch < batches; ++batch) {
    for (int out_y = 0; out_y < output_height; ++out_y) {
      const int in_y_origin = (out_y * stride_height) - pad_height;
      for (int out_x = 0; out_x < output_width; ++out_x) {
        const int in_x_origin = (out_x * stride_width) - pad_width;
        for (int out_channel = 0; out_channel < output_depth; ++out_channel) {
          std::int64_t acc = 0;
          for (int filter_y = 0; filter_y < filter_height; ++filter_y) {
            const int in_y = in_y_origin + dilation_height_factor * filter_y;
            for (int filter_x = 0; filter_x < filter_width; ++filter_x) {
              const int in_x = in_x_origin + dilation_width_factor * filter_x;

              // Zero padding by omitting the areas outside the image.
              const bool is_point_inside_image =
                  (in_x >= 0) && (in_x < input_width) && (in_y >= 0) &&
                  (in_y < input_height);

              if (!is_point_inside_image) {
                continue;
              }

              for (int in_channel = 0; in_channel < input_depth; ++in_channel) {
                int32_t input_val = input_data[Offset(input_shape, batch, in_y,
                                                      in_x, in_channel)];
                int32_t filter_val = filter_data[Offset(
                    filter_shape, out_channel, filter_y, filter_x, in_channel)];
                // Accumulate with 64 bits accumulator.
                // int64_t += int8_t * int16_t so the highest value we can
                // get from each accumulation is [-127, 127] * ([-32768,
                // 32767] -
                // [-32768, 32767]), which is [-8322945, 8322945].
                // log2(8322945) = 22.99.
                acc += filter_val * input_val;
              }
            }
          }
          if (bias_data) {
            acc += bias_data[out_channel];
          }
          int32_t scaled_acc = MultiplyByQuantizedMultiplier(
              acc, output_multiplier[out_channel], output_shift[out_channel]);
          scaled_acc = std::max(scaled_acc, output_activation_min);
          scaled_acc = std::min(scaled_acc, output_activation_max);
          output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] =
              static_cast<int16_t>(scaled_acc);
        }
      }
    }
  }
}

}  // namespace reference_integer_ops
}  // namespace tflite
<commit_msg>mnv2_first/conv.cc: Add debugging code<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 <stdio.h>

#include "mnv2_cfu.h"
#include "mnv2_conv.h"
#include "tensorflow/lite/kernels/internal/common.h"
#include "tf_util/print_params.h"

#ifdef DUMP_CONV
#include "b64_util.h"
#endif

namespace tflite {
namespace reference_integer_ops {

// Fixed-point per-channel-quantization convolution reference kernel.
void ConvPerChannel(const ConvParams& params, const int32_t* output_multiplier,
                    const int32_t* output_shift,
                    const RuntimeShape& input_shape, const int8_t* input_data,
                    const RuntimeShape& filter_shape, const int8_t* filter_data,
                    const RuntimeShape& bias_shape, const int32_t* bias_data,
                    const RuntimeShape& output_shape, int8_t* output_data) {
#ifdef SHOW_CONV_PARAMS
  print_conv_params(params, input_shape, filter_shape, output_shape);
#endif
  // Get parameters.
  const int32_t input_offset = params.input_offset;  // r = s(q - Z)
  const int stride_width = params.stride_width;
  const int stride_height = params.stride_height;
  const int dilation_width_factor = params.dilation_width_factor;
  const int dilation_height_factor = params.dilation_height_factor;
  const int pad_width = params.padding_values.width;
  const int pad_height = params.padding_values.height;
  const int32_t output_offset = params.output_offset;

  // Set min and max value of the output.
  const int32_t output_activation_min = params.quantized_activation_min;
  const int32_t output_activation_max = params.quantized_activation_max;

  // Consistency check.
  TFLITE_DCHECK_LE(output_activation_min, output_activation_max);
  TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4);
  const int batches = MatchingDim(input_shape, 0, output_shape, 0);
  const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3);
  const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3);
  if (bias_data) {
    TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth);
  }

  // Check dimensions of the tensors.
  const int input_height = input_shape.Dims(1);
  const int input_width = input_shape.Dims(2);
  const int filter_height = filter_shape.Dims(1);
  const int filter_width = filter_shape.Dims(2);
  const int output_height = output_shape.Dims(1);
  const int output_width = output_shape.Dims(2);

#ifdef ACCEL_CONV
  if (pad_width == 0 && pad_height == 0 && dilation_width_factor == 1 &&
      dilation_height_factor == 1 &&  // params.weights_offset == 0 &&
      output_activation_min == -128 && output_activation_max == 127 &&
      batches == 1) {
    if (params.stride_width == 1 && params.stride_height == 1 &&
        input_height == output_height && input_width == output_width &&
        filter_height == 1 && filter_width == 1 && bias_data &&
        input_depth < MAX_CONV_INPUT_BYTES && (input_depth % 8) == 0 &&
        (output_depth % 8) == 0) {
      Mnv2ConvPerChannel1x1(params, output_multiplier, output_shift,
                            input_shape, input_data, filter_shape, filter_data,
                            bias_shape, bias_data, output_shape, output_data);
      return;
    }
  }
#endif

#ifdef DUMP_CONV
  if (filter_shape.FlatSize() == 2304) {
    puts("\n\nDumping conv op");
    puts("-----\nparams");
    b64_dump((const int8_t*)(const void*)&params, sizeof(params));
    puts("-----\noutput_multiplier");
    b64_dump((const int8_t*)output_multiplier, output_depth * sizeof(uint32_t));
    puts("-----\noutput_shift");
    b64_dump((const int8_t*)output_shift, output_depth * sizeof(uint32_t));
    puts("-----\ninput_shape");
    b64_dump((const int8_t*)(const void*)&input_shape, sizeof(input_shape));
    puts("-----\ninput_data");
    b64_dump(input_data, input_shape.FlatSize());
    puts("-----\nfilter_shape");
    b64_dump((const int8_t*)(const void*)&filter_shape, sizeof(filter_shape));
    puts("-----\nfilter_data");
    b64_dump(filter_data, filter_shape.FlatSize());
    puts("-----\nbias_shape");
    b64_dump((const int8_t*)(const void*)&bias_shape, sizeof(bias_shape));
    puts("-----\nbias_data");
    b64_dump((const int8_t*)bias_data, output_depth * sizeof(uint32_t));
  }
#endif

  for (int batch = 0; batch < batches; ++batch) {
    for (int out_y = 0; out_y < output_height; ++out_y) {
      const int in_y_origin = (out_y * stride_height) - pad_height;
      for (int out_x = 0; out_x < output_width; ++out_x) {
        const int in_x_origin = (out_x * stride_width) - pad_width;
        for (int out_channel = 0; out_channel < output_depth; ++out_channel) {
          int32_t acc = 0;
          for (int filter_y = 0; filter_y < filter_height; ++filter_y) {
            const int in_y = in_y_origin + dilation_height_factor * filter_y;
            for (int filter_x = 0; filter_x < filter_width; ++filter_x) {
              const int in_x = in_x_origin + dilation_width_factor * filter_x;

              // Zero padding by omitting the areas outside the image.
              const bool is_point_inside_image =
                  (in_x >= 0) && (in_x < input_width) && (in_y >= 0) &&
                  (in_y < input_height);

              if (!is_point_inside_image) {
                continue;
              }

              for (int in_channel = 0; in_channel < input_depth; ++in_channel) {
                int32_t input_val = input_data[Offset(input_shape, batch, in_y,
                                                      in_x, in_channel)];
                int32_t filter_val = filter_data[Offset(
                    filter_shape, out_channel, filter_y, filter_x, in_channel)];
                // Accumulate with 32 bits accumulator.
                // In the nudging process during model quantization, we force
                // real value of 0.0 be represented by a quantized value. This
                // guarantees that the input_offset is a int8_t, even though
                // it is represented using int32_t. int32_t += int8_t *
                // (int8_t - int8_t) so the highest value we can get from each
                // accumulation is [-127, 127] * ([-128, 127] -
                // [-128, 127]), which is [-32512, 32512]. log2(32512)
                // = 14.98, which means we can accumulate at least 2^16
                // multiplications without overflow. The accumulator is
                // applied to a filter so the accumulation logic will hold as
                // long as the filter size (filter_y * filter_x * in_channel)
                // does not exceed 2^16, which is the case in all the models
                // we have seen so far.
                // TODO(jianlijianli): Add a check to make sure the
                // accumulator depth is smaller than 2^16.
                int32_t sum = filter_val * (input_val + input_offset);
                acc += sum;
#if 0
                static int dbg_ctr = 0;
                if (dbg_ctr >= 96*24 && dbg_ctr < 96*24+96) {
                  printf("%6ld, %4ld, %6ld, %6ld\n", filter_val, input_val, input_offset, sum);
                }
                dbg_ctr++;

#endif
              }
            }
          }
#if SHOW_SAMPLE_POST_PROCESSING
          static uint32_t count = 0;
          if ((count & (1024 * 128 - 1)) == 0) {
            printf("(%ld, %ld, %ld, %ld, %ld, %ld, %ld), ", acc,
                   bias_data[out_channel], output_multiplier[out_channel],
                   output_shift[out_channel], output_offset,
                   output_activation_min, output_activation_max);
          }
#endif
          if (bias_data) {
            acc += bias_data[out_channel];
          }
          acc = MultiplyByQuantizedMultiplier(
              acc, output_multiplier[out_channel], output_shift[out_channel]);
          acc += output_offset;
          acc = std::max(acc, output_activation_min);
          acc = std::min(acc, output_activation_max);
          output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] =
              static_cast<int8_t>(acc);

#if 0
          // fixme int32_t acc_in = acc;
          static int dbg_ctr = 0;
          if (dbg_ctr == 0) {
            printf("%6ld, %6ld, %02lx\n", acc_in, acc, acc & 0xff);
          }
          dbg_ctr++;

#endif

#if SHOW_SAMPLE_POST_PROCESSING
          if ((count & (1024 * 128 - 1)) == 0) {
            printf("%ld\n", acc);
          }
          count++;
#endif
        }
      }
    }
  }
#ifdef DUMP_CONV
  if (filter_shape.FlatSize() == 2304) {
    puts("-----\noutput_shape");
    b64_dump((const int8_t*)(const void*)&output_shape, sizeof(output_shape));
    puts("-----\noutput_data");
    b64_dump(output_data, output_shape.FlatSize());
    puts("-----\n");
  }
#endif
}

// Fixed-point per-channel-quantization convolution reference kernel.
// 16-bit data and 8-bit filter
void ConvPerChannel(const ConvParams& params, const int32_t* output_multiplier,
                    const int32_t* output_shift,
                    const RuntimeShape& input_shape, const int16_t* input_data,
                    const RuntimeShape& filter_shape, const int8_t* filter_data,
                    const RuntimeShape& bias_shape,
                    const std::int64_t* bias_data,
                    const RuntimeShape& output_shape, int16_t* output_data) {
  // Get parameters.
  const int stride_width = params.stride_width;
  const int stride_height = params.stride_height;
  const int dilation_width_factor = params.dilation_width_factor;
  const int dilation_height_factor = params.dilation_height_factor;
  const int pad_width = params.padding_values.width;
  const int pad_height = params.padding_values.height;

  // Set min and max value of the output.
  const int32_t output_activation_min = params.quantized_activation_min;
  const int32_t output_activation_max = params.quantized_activation_max;

  // Consistency check.
  TFLITE_DCHECK_LE(output_activation_min, output_activation_max);
  TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4);
  TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4);
  const int batches = MatchingDim(input_shape, 0, output_shape, 0);
  const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3);
  const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3);
  if (bias_data) {
    TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth);
  }

  // Check dimensions of the tensors.
  const int input_height = input_shape.Dims(1);
  const int input_width = input_shape.Dims(2);
  const int filter_height = filter_shape.Dims(1);
  const int filter_width = filter_shape.Dims(2);
  const int output_height = output_shape.Dims(1);
  const int output_width = output_shape.Dims(2);
  for (int batch = 0; batch < batches; ++batch) {
    for (int out_y = 0; out_y < output_height; ++out_y) {
      const int in_y_origin = (out_y * stride_height) - pad_height;
      for (int out_x = 0; out_x < output_width; ++out_x) {
        const int in_x_origin = (out_x * stride_width) - pad_width;
        for (int out_channel = 0; out_channel < output_depth; ++out_channel) {
          std::int64_t acc = 0;
          for (int filter_y = 0; filter_y < filter_height; ++filter_y) {
            const int in_y = in_y_origin + dilation_height_factor * filter_y;
            for (int filter_x = 0; filter_x < filter_width; ++filter_x) {
              const int in_x = in_x_origin + dilation_width_factor * filter_x;

              // Zero padding by omitting the areas outside the image.
              const bool is_point_inside_image =
                  (in_x >= 0) && (in_x < input_width) && (in_y >= 0) &&
                  (in_y < input_height);

              if (!is_point_inside_image) {
                continue;
              }

              for (int in_channel = 0; in_channel < input_depth; ++in_channel) {
                int32_t input_val = input_data[Offset(input_shape, batch, in_y,
                                                      in_x, in_channel)];
                int32_t filter_val = filter_data[Offset(
                    filter_shape, out_channel, filter_y, filter_x, in_channel)];
                // Accumulate with 64 bits accumulator.
                // int64_t += int8_t * int16_t so the highest value we can
                // get from each accumulation is [-127, 127] * ([-32768,
                // 32767] -
                // [-32768, 32767]), which is [-8322945, 8322945].
                // log2(8322945) = 22.99.
                acc += filter_val * input_val;
              }
            }
          }
          if (bias_data) {
            acc += bias_data[out_channel];
          }
          int32_t scaled_acc = MultiplyByQuantizedMultiplier(
              acc, output_multiplier[out_channel], output_shift[out_channel]);
          scaled_acc = std::max(scaled_acc, output_activation_min);
          scaled_acc = std::min(scaled_acc, output_activation_max);
          output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] =
              static_cast<int16_t>(scaled_acc);
        }
      }
    }
  }
}

}  // namespace reference_integer_ops
}  // namespace tflite
<|endoftext|>


<commit_before>#include <debug.hpp>

#include <newDishWindow.hpp>
#include "ui_newDishWindow.h"

NewDishWindow::NewDishWindow(QWidget *parent) :
    QDialog {parent},
    ui {new Ui::NewDishWindow},
    foodStringList {new QStringList},
    itemListModel {new QStringListModel {*foodStringList, NULL}} {

    ui->setupUi(this);

    ui->listView_1->setModel(itemListModel);

    ui->tableWidget_1->setColumnCount(2);

    PRINT_OBJ("NewDishWindow created");
}

NewDishWindow::~NewDishWindow() {
    delete ui;

    PRINT_OBJ("NewDishWindow destroyed");
}

void NewDishWindow::on_buttonBox_1_accepted() {
    if ( dishFoodList.size() ) {
        emit itemObjectReady(createNewDish());
    }
    this->hide();

    PRINT_DEBUG("New dish accepted");
}

void NewDishWindow::on_buttonBox_1_rejected() {
    this->hide();

    PRINT_DEBUG("New dish rejected");
}

void NewDishWindow::fillItemList(std::list<Item *> *itemsList) {
    avaliableItemsList = itemsList;

    for ( auto& entry: *itemsList ) {
        if ( dynamic_cast<Food *>(entry) ) {
            foodStringList->append(QString::fromStdString(entry->getName()));
        } else {
            foodStringList->append(QString::fromStdString(entry->getName())+QString(" (item)"));
        }
    }

    itemListModel->setStringList(*foodStringList);
}

Dish* NewDishWindow::createNewDish(void) {
    std::list<Item *>::iterator item = dishFoodList.begin();
    uint64_t amountOfPeople = static_cast<uint64_t>(ui->lineEdit_2->text().toLong());
    int pos_y = 0;

    if ( amountOfPeople < 1 ) {
        amountOfPeople = 1;
    }

    newDish = new Dish(ui->lineEdit_1->text().toStdString(),
                       *dynamic_cast<Food *>(*item),
                       static_cast<uint64_t>(ui->tableWidget_1->item(pos_y, 1)->text().toLong()),
                       amountOfPeople);
    pos_y += 1;
    std::advance(item, 1);

    for ( ; item != dishFoodList.end(); item++ ) {
        newDish->addFood(*dynamic_cast<Food *>(*item),
                         static_cast<uint64_t>(ui->tableWidget_1->item(pos_y, 1)->text().toLong()));
        pos_y += 1;
    }

    return newDish;
}

void NewDishWindow::on_pushButton_1_clicked() {
    QModelIndexList selected = ui->listView_1->selectionModel()->selectedIndexes();

    if ( !selected.isEmpty() ) {
        std::list<Item *>::iterator item = avaliableItemsList->begin();

        std::advance(item, selected.first().row());

        if ( std::find(dishFoodList.begin(), dishFoodList.end(), *item) == dishFoodList.end() && dynamic_cast<Food *>(*item) ) {
            int rowCount = ui->tableWidget_1->rowCount();

            dishFoodList.push_back(*item);

            ui->tableWidget_1->setRowCount(rowCount+1);
            ui->tableWidget_1->setItem(rowCount, 0, new QTableWidgetItem(QString::fromStdString((*item)->getName())));
            ui->tableWidget_1->setItem(rowCount, 1, new QTableWidgetItem(QString("1")));
        }
   }
}

void NewDishWindow::on_pushButton_2_clicked() {
    if ( ui->tableWidget_1->currentRow() != -1 ) {
        std::list<Item *>::iterator item = dishFoodList.begin();
        int currentRow = ui->tableWidget_1->currentRow();

        std::advance(item, currentRow);
        dishFoodList.remove(*item);

        ui->tableWidget_1->removeRow(currentRow);
    }
}
<commit_msg>newDishWindow: Fix memory leaks<commit_after>#include <debug.hpp>

#include <newDishWindow.hpp>
#include "ui_newDishWindow.h"

NewDishWindow::NewDishWindow(QWidget *parent) :
    QDialog {parent},
    ui {new Ui::NewDishWindow},
    foodStringList {new QStringList},
    itemListModel {new QStringListModel {*foodStringList, NULL}} {

    ui->setupUi(this);

    ui->listView_1->setModel(itemListModel);

    ui->tableWidget_1->setColumnCount(2);

    PRINT_OBJ("NewDishWindow created");
}

NewDishWindow::~NewDishWindow() {
    delete ui;
    delete foodStringList;
    delete itemListModel;

    PRINT_OBJ("NewDishWindow destroyed");
}

void NewDishWindow::on_buttonBox_1_accepted() {
    if ( dishFoodList.size() ) {
        emit itemObjectReady(createNewDish());
    }
    this->hide();

    PRINT_DEBUG("New dish accepted");
}

void NewDishWindow::on_buttonBox_1_rejected() {
    this->hide();

    PRINT_DEBUG("New dish rejected");
}

void NewDishWindow::fillItemList(std::list<Item *> *itemsList) {
    avaliableItemsList = itemsList;

    for ( auto& entry: *itemsList ) {
        if ( dynamic_cast<Food *>(entry) ) {
            foodStringList->append(QString::fromStdString(entry->getName()));
        } else {
            foodStringList->append(QString::fromStdString(entry->getName())+QString(" (item)"));
        }
    }

    itemListModel->setStringList(*foodStringList);
}

Dish* NewDishWindow::createNewDish(void) {
    std::list<Item *>::iterator item = dishFoodList.begin();
    uint64_t amountOfPeople = static_cast<uint64_t>(ui->lineEdit_2->text().toLong());
    int pos_y = 0;

    if ( amountOfPeople < 1 ) {
        amountOfPeople = 1;
    }

    newDish = new Dish(ui->lineEdit_1->text().toStdString(),
                       *dynamic_cast<Food *>(*item),
                       static_cast<uint64_t>(ui->tableWidget_1->item(pos_y, 1)->text().toLong()),
                       amountOfPeople);
    pos_y += 1;
    std::advance(item, 1);

    for ( ; item != dishFoodList.end(); item++ ) {
        newDish->addFood(*dynamic_cast<Food *>(*item),
                         static_cast<uint64_t>(ui->tableWidget_1->item(pos_y, 1)->text().toLong()));
        pos_y += 1;
    }

    return newDish;
}

void NewDishWindow::on_pushButton_1_clicked() {
    QModelIndexList selected = ui->listView_1->selectionModel()->selectedIndexes();

    if ( !selected.isEmpty() ) {
        std::list<Item *>::iterator item = avaliableItemsList->begin();

        std::advance(item, selected.first().row());

        if ( std::find(dishFoodList.begin(), dishFoodList.end(), *item) == dishFoodList.end() && dynamic_cast<Food *>(*item) ) {
            int rowCount = ui->tableWidget_1->rowCount();

            dishFoodList.push_back(*item);

            ui->tableWidget_1->setRowCount(rowCount+1);
            ui->tableWidget_1->setItem(rowCount, 0, new QTableWidgetItem(QString::fromStdString((*item)->getName())));
            ui->tableWidget_1->setItem(rowCount, 1, new QTableWidgetItem(QString("1")));
        }
   }
}

void NewDishWindow::on_pushButton_2_clicked() {
    if ( ui->tableWidget_1->currentRow() != -1 ) {
        std::list<Item *>::iterator item = dishFoodList.begin();
        int currentRow = ui->tableWidget_1->currentRow();

        std::advance(item, currentRow);
        dishFoodList.remove(*item);

        ui->tableWidget_1->removeRow(currentRow);
    }
}
<|endoftext|>