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

  Program:   KWSys - Kitware System Library
  Module:    DynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)

#include KWSYS_HEADER(Configure.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "Configure.hxx.in"
#endif

// This file is actually 3 different implementations.
// 1. HP machines which uses shl_load
// 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
// 3. Windows which uses LoadLibrary
// 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen
// (default) Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::DynamicLoader()
{
}

//----------------------------------------------------------------------------
DynamicLoader::~DynamicLoader()
{
}

}

// ---------------------------------------------------------------
// 1. Implementation for HPUX  machines
#ifdef __hpux
#include <errno.h>
#include <dl.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  return !shl_unload(lib);
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer
DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym)
{
  void* addr;
  int status;

  /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
   * TYPE_DATA      Look for a symbol in the data segment (for example, variables).
   * TYPE_UNDEFINED Look for any symbol.
   */
  status = shl_findsym (&lib, sym, TYPE_UNDEFINED, &addr);
  void* result = (status < 0) ? (void*)0 : addr;

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".sl";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  // TODO: Need implementation with errno/strerror
  /* If successful, shl_findsym returns an integer (int) value zero. If
   * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
   * If any other errors occur, shl_findsym returns -1 and sets errno to one
   * of these values (defined in <errno.h>):
   * ENOEXEC
   * A format error was detected in the specified library.
   * ENOSYM
   * A symbol on which sym depends could not be found.
   * EINVAL
   * The specified handle is invalid.
   */

  if(  errno == ENOEXEC
    || errno == ENOSYM
    || errno == EINVAL )
    {
    return strerror(errno);
    }
  // else
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //__hpux

// ---------------------------------------------------------------
// 2. Implementation for Mac OS X 10.2.x and earlier
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
#include <string.h> // for strlen
#include <mach-o/dyld.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  NSObjectFileImageReturnCode rc;
  NSObjectFileImage image = 0;

  rc = NSCreateObjectFileImageFromFile(libname, &image);
  // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
  if( rc != NSObjectFileImageSuccess )
    {
    return 0;
    }
  NSModule handle = NSLinkModule(image, libname,
    NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
  NSDestroyObjectFileImage(image);
  return handle;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
{
  // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
  // With  this  option  the memory for the module is not deallocated
  // allowing pointers into the module to still be valid.
  // You should use this option instead if your code experience some problems
  // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up)
  bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  return success;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  void *result=0;
  // Need to prepend symbols with '_' on Apple-gcc compilers
  size_t len = strlen(sym);
  char *rsym = new char[len + 1 + 1];
  strcpy(rsym, "_");
  strcat(rsym+1, sym);

  NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
  if(symbol)
    {
    result = NSAddressOfSymbol(symbol);
    }

  delete[] rsym;
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  // NSCreateObjectFileImageFromFile fail when dealing with dylib image
  // it returns NSObjectFileImageInappropriateFile
  //return ".dylib";
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1030
#endif // __APPLE__

// ---------------------------------------------------------------
// 3. Implementation for Windows win32 code but not cygwin
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname)
{
  DynamicLoader::LibraryHandle lh;
#ifdef UNICODE
  wchar_t libn[MB_CUR_MAX];
  mbstowcs(libn, libname, MB_CUR_MAX);
  lh = LoadLibrary(libn);
#else
  lh = LoadLibrary(libname);
#endif
  return lh;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  return (int)FreeLibrary(lib);
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  void *result;
#ifdef __BORLANDC__
  // Need to prepend symbols with '_' on borland compilers
  size_t len = strlen(sym);
  char *rsym = new char[len + 1 + 1];
  strcpy(rsym, "_");
  strcat(rsym+1, sym);
#else
  const char *rsym = sym;
#endif
#ifdef UNICODE
  wchar_t wsym[MB_CUR_MAX];
  mbstowcs(wsym, rsym, MB_CUR_MAX);
  result = GetProcAddress(lib, wsym);
#else
  result = (void*)GetProcAddress(lib, rsym);
#endif
#ifdef __BORLANDC__
  delete[] rsym;
#endif
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
#ifdef __MINGW32__
  return "lib";
#else
  return "";
#endif
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dll";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  LPVOID lpMsgBuf;

  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );

  static char* str = 0;
  delete [] str;
  str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
  // Free the buffer.
  LocalFree( lpMsgBuf );
  return str;
}

} // namespace KWSYS_NAMESPACE

#endif //_WIN32

// ---------------------------------------------------------------
// 4. Implementation for BeOS
#ifdef __BEOS__
#include <string.h> // for strerror()
#include <be/kernel/image.h>
#include <be/support/Errors.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

static image_id last_dynamic_err = B_OK;

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  // image_id's are integers, errors are negative. Add one just in case we
  //  get a valid image_id of zero (is that even possible?).
  image_id rc = load_add_on(libname);
  if (rc < 0)
    {
    last_dynamic_err = rc;
    return 0;
    }

  return rc+1;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (!lib)
    {
      last_dynamic_err = B_BAD_VALUE;
      return 0;
    }
  else
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    status_t rc = unload_add_on(lib-1);
    if (rc != B_OK)
      {
      last_dynamic_err = rc;
      return 0;
      }
    }

  return 1;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;

  result.psym = NULL;

  if (!lib)
    {
      last_dynamic_err = B_BAD_VALUE;
    }
  else
    {
    // !!! FIXME: BeOS can do function-only lookups...does this ever
    // !!! FIXME:  actually _want_ a data symbol lookup, or was this union
    // !!! FIXME:  a leftover of dlsym()? (s/ANY/TEXT for functions only).
    status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
    if (rc != B_OK)
      {
      last_dynamic_err = rc;
      result.psym = NULL;
      }
    }
  return result.psym;
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  const char *retval = strerror(last_dynamic_err);
  last_dynamic_err = B_OK;
  return retval;
}

} // namespace KWSYS_NAMESPACE
#endif

// ---------------------------------------------------------------
// 5. Implementation for default UNIX machines.
// if nothing has been defined then use this
#ifndef DYNAMICLOADER_DEFINED
#define DYNAMICLOADER_DEFINED 1
// Setup for most unix machines
#include <dlfcn.h>

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return dlopen(libname, RTLD_LAZY);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (lib)
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    return !dlclose(lib);
    }
  // else
  return 0;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;
  result.pvoid = dlsym(lib, sym);
  return result.psym;
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
#ifdef __CYGWIN__
  return ".dll";
#else
  return ".so";
#endif
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return dlerror();
}

} // namespace KWSYS_NAMESPACE

#endif
<commit_msg>ENH: Added support for Watcom compiler.  Added TODO comment about calling conventions.<commit_after>/*=========================================================================

  Program:   KWSys - Kitware System Library
  Module:    DynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)

#include KWSYS_HEADER(Configure.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "Configure.hxx.in"
#endif

// This file is actually 3 different implementations.
// 1. HP machines which uses shl_load
// 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
// 3. Windows which uses LoadLibrary
// 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen
// (default) Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::DynamicLoader()
{
}

//----------------------------------------------------------------------------
DynamicLoader::~DynamicLoader()
{
}

}

// ---------------------------------------------------------------
// 1. Implementation for HPUX  machines
#ifdef __hpux
#include <errno.h>
#include <dl.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  return !shl_unload(lib);
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer
DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym)
{
  void* addr;
  int status;

  /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
   * TYPE_DATA      Look for a symbol in the data segment (for example, variables).
   * TYPE_UNDEFINED Look for any symbol.
   */
  status = shl_findsym (&lib, sym, TYPE_UNDEFINED, &addr);
  void* result = (status < 0) ? (void*)0 : addr;

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".sl";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  // TODO: Need implementation with errno/strerror
  /* If successful, shl_findsym returns an integer (int) value zero. If
   * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
   * If any other errors occur, shl_findsym returns -1 and sets errno to one
   * of these values (defined in <errno.h>):
   * ENOEXEC
   * A format error was detected in the specified library.
   * ENOSYM
   * A symbol on which sym depends could not be found.
   * EINVAL
   * The specified handle is invalid.
   */

  if(  errno == ENOEXEC
    || errno == ENOSYM
    || errno == EINVAL )
    {
    return strerror(errno);
    }
  // else
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //__hpux

// ---------------------------------------------------------------
// 2. Implementation for Mac OS X 10.2.x and earlier
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
#include <string.h> // for strlen
#include <mach-o/dyld.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  NSObjectFileImageReturnCode rc;
  NSObjectFileImage image = 0;

  rc = NSCreateObjectFileImageFromFile(libname, &image);
  // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
  if( rc != NSObjectFileImageSuccess )
    {
    return 0;
    }
  NSModule handle = NSLinkModule(image, libname,
    NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
  NSDestroyObjectFileImage(image);
  return handle;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
{
  // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
  // With  this  option  the memory for the module is not deallocated
  // allowing pointers into the module to still be valid.
  // You should use this option instead if your code experience some problems
  // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up)
  bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  return success;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  void *result=0;
  // Need to prepend symbols with '_' on Apple-gcc compilers
  size_t len = strlen(sym);
  char *rsym = new char[len + 1 + 1];
  strcpy(rsym, "_");
  strcat(rsym+1, sym);

  NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
  if(symbol)
    {
    result = NSAddressOfSymbol(symbol);
    }

  delete[] rsym;
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  // NSCreateObjectFileImageFromFile fail when dealing with dylib image
  // it returns NSObjectFileImageInappropriateFile
  //return ".dylib";
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1030
#endif // __APPLE__

// ---------------------------------------------------------------
// 3. Implementation for Windows win32 code but not cygwin
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname)
{
  DynamicLoader::LibraryHandle lh;
#ifdef UNICODE
  wchar_t libn[MB_CUR_MAX];
  mbstowcs(libn, libname, MB_CUR_MAX);
  lh = LoadLibrary(libn);
#else
  lh = LoadLibrary(libname);
#endif
  return lh;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  return (int)FreeLibrary(lib);
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  // TODO: The calling convention affects the name of the symbol.  We
  // should have a tool to help get the symbol with the desired
  // calling convention.  Currently we assume cdecl.
  //
  // Borland:
  //   __cdecl    = "_func" (default)
  //   __fastcall = "@_func"
  //   __stdcall  = "func"
  //
  // Watcom:
  //   __cdecl    = "_func"
  //   __fastcall = "@_func@X"
  //   __stdcall  = "_func@X"
  //   __watcall  = "func_" (default)
  //
  // MSVC:
  //   __cdecl    = "func" (default)
  //   __fastcall = "@_func@X"
  //   __stdcall  = "_func@X"
  //
  // Note that the "@X" part of the name above is the total size (in
  // bytes) of the arguments on the stack.
  void *result;
#if defined(__BORLANDC__) || defined(__WATCOMC__)
  // Need to prepend symbols with '_'
  size_t len = strlen(sym);
  char *rsym = new char[len + 1 + 1];
  strcpy(rsym, "_");
  strcat(rsym, sym);
#else
  const char *rsym = sym;
#endif
#ifdef UNICODE
  wchar_t wsym[MB_CUR_MAX];
  mbstowcs(wsym, rsym, MB_CUR_MAX);
  result = GetProcAddress(lib, wsym);
#else
  result = (void*)GetProcAddress(lib, rsym);
#endif
#if defined(__BORLANDC__) || defined(__WATCOMC__)
  delete[] rsym;
#endif
  // Hack to cast pointer-to-data to pointer-to-function.
#ifdef __WATCOMC__
  return *(DynamicLoader::SymbolPointer*)(&result);
#else
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
#endif
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
#ifdef __MINGW32__
  return "lib";
#else
  return "";
#endif
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dll";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  LPVOID lpMsgBuf;

  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );

  static char* str = 0;
  delete [] str;
  str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
  // Free the buffer.
  LocalFree( lpMsgBuf );
  return str;
}

} // namespace KWSYS_NAMESPACE

#endif //_WIN32

// ---------------------------------------------------------------
// 4. Implementation for BeOS
#ifdef __BEOS__
#include <string.h> // for strerror()
#include <be/kernel/image.h>
#include <be/support/Errors.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

static image_id last_dynamic_err = B_OK;

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  // image_id's are integers, errors are negative. Add one just in case we
  //  get a valid image_id of zero (is that even possible?).
  image_id rc = load_add_on(libname);
  if (rc < 0)
    {
    last_dynamic_err = rc;
    return 0;
    }

  return rc+1;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (!lib)
    {
      last_dynamic_err = B_BAD_VALUE;
      return 0;
    }
  else
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    status_t rc = unload_add_on(lib-1);
    if (rc != B_OK)
      {
      last_dynamic_err = rc;
      return 0;
      }
    }

  return 1;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;

  result.psym = NULL;

  if (!lib)
    {
      last_dynamic_err = B_BAD_VALUE;
    }
  else
    {
    // !!! FIXME: BeOS can do function-only lookups...does this ever
    // !!! FIXME:  actually _want_ a data symbol lookup, or was this union
    // !!! FIXME:  a leftover of dlsym()? (s/ANY/TEXT for functions only).
    status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
    if (rc != B_OK)
      {
      last_dynamic_err = rc;
      result.psym = NULL;
      }
    }
  return result.psym;
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  const char *retval = strerror(last_dynamic_err);
  last_dynamic_err = B_OK;
  return retval;
}

} // namespace KWSYS_NAMESPACE
#endif

// ---------------------------------------------------------------
// 5. Implementation for default UNIX machines.
// if nothing has been defined then use this
#ifndef DYNAMICLOADER_DEFINED
#define DYNAMICLOADER_DEFINED 1
// Setup for most unix machines
#include <dlfcn.h>

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return dlopen(libname, RTLD_LAZY);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (lib)
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    return !dlclose(lib);
    }
  // else
  return 0;
}

//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const char* sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;
  result.pvoid = dlsym(lib, sym);
  return result.psym;
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
#ifdef __CYGWIN__
  return ".dll";
#else
  return ".so";
#endif
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return dlerror();
}

} // namespace KWSYS_NAMESPACE

#endif
<|endoftext|>


<commit_before>#include <string>
#include <cstring>
#include <sstream>
#include <tr1/tuple>
using namespace std;

#include <gtest/gtest.h>
#include "../src/options.hpp"

namespace {

class CmdLineOptionsTest : public ::testing::Test {
protected:
CmdLineOptions opts;
};

TEST_F(CmdLineOptionsTest, DefaultConstructor) {
EXPECT_FALSE(opts.getHelp());
EXPECT_FALSE(opts.getTemplate());
EXPECT_FALSE(opts.getDebug());
EXPECT_FALSE(opts.getQuiet());
EXPECT_EQ("", opts.getInputPath());
}

TEST_F(CmdLineOptionsTest, ExplicitConstructor) {
CmdLineOptions helpSet(true,false,false,false,"");
EXPECT_TRUE(helpSet.getHelp());
EXPECT_FALSE(helpSet.getTemplate());
EXPECT_FALSE(helpSet.getDebug());
EXPECT_FALSE(helpSet.getQuiet());
EXPECT_EQ("", helpSet.getInputPath());

CmdLineOptions tempSet(false,true,false,false,"");
EXPECT_FALSE(tempSet.getHelp());
EXPECT_TRUE(tempSet.getTemplate());
EXPECT_FALSE(tempSet.getDebug());
EXPECT_FALSE(tempSet.getQuiet());
EXPECT_EQ("", tempSet.getInputPath());

CmdLineOptions debugSet(false,false,true,false,"");
EXPECT_FALSE(debugSet.getHelp());
EXPECT_FALSE(debugSet.getTemplate());
EXPECT_TRUE(debugSet.getDebug());
EXPECT_FALSE(debugSet.getQuiet());
EXPECT_EQ("", debugSet.getInputPath());

CmdLineOptions quietSet(false,false,false,true,"");
EXPECT_FALSE(quietSet.getHelp());
EXPECT_FALSE(quietSet.getTemplate());
EXPECT_FALSE(quietSet.getDebug());
EXPECT_TRUE(quietSet.getQuiet());
EXPECT_EQ("", quietSet.getInputPath());

CmdLineOptions pathSet(false,false,false,false,"ExplicitConstructorPath");
EXPECT_FALSE(pathSet.getHelp());
EXPECT_FALSE(pathSet.getTemplate());
EXPECT_FALSE(pathSet.getDebug());
EXPECT_FALSE(pathSet.getQuiet());
EXPECT_EQ("ExplicitConstructorPath", pathSet.getInputPath());
}

TEST_F(CmdLineOptionsTest, Print) {
stringstream testStream;
string expectedResponse="Help:    \t0;\tTemplate:\t0;\nDebug:   \t0;\tQuiet:   \t0;\nInput path:\tPrintedPath\n";

opts.setInputPath("PrintedPath");

opts.print(testStream);
EXPECT_EQ(expectedResponse, testStream.str());
}

#ifdef GTEST_HAS_COMBINE
// Setup the command line processing
// Do it with tuples so we get all possible combos easily

using ::testing::ValuesIn;

string helpStrings[3] = {"-h", "--help", ""};
string templateStrings[3] = {"-t", "--template", ""};
string debugStrings[3] = {"-d", "--debug", ""};
string quietStrings[3] = {"-q", "--quiet", ""};
string inputPathStrings[3] = {"-i", "--input-path", ""};
char dummyProg[] = "PretendProg";
string dummyPath = "PretendInputFile";

class ProcessCmdLineTest : public ::testing::TestWithParam< tr1::tuple<string, string, string, string, string> > {
protected:
CmdLineOptions processedOptions;
CmdLineOptions* expectedOptions;
int argc;
char * argv[8];
virtual void SetUp() {
  string helpIn, tempIn, debugIn, quietIn, inputIn;
  tr1::tie(helpIn,tempIn,debugIn,quietIn,inputIn) = GetParam();
  expectedOptions = new CmdLineOptions(!helpIn.empty(), !tempIn.empty(), !debugIn.empty(), !quietIn.empty(), inputIn.empty() ? "" : "PretendInputFile");
  // Int args
  argv[0] = dummyProg;
  argc=1;
  // Fill argv appropriately
  if (!helpIn.empty()) {
        argv[argc] = new char [helpIn.length()+1];
	strcpy(argv[argc], helpIn.c_str());
        argc++;
  }
  if (!tempIn.empty()) {
        argv[argc] = new char [tempIn.length()+1];
	strcpy(argv[argc], tempIn.c_str());
        argc++;
  }
  if (!debugIn.empty()) {
        argv[argc] = new char [debugIn.length()+1];
	strcpy(argv[argc], debugIn.c_str());
        argc++;
  }
  if (!quietIn.empty()) {
        argv[argc] = new char [quietIn.length()+1];
	strcpy(argv[argc], quietIn.c_str());
        argc++;
  }
  if (!inputIn.empty()) {
        argv[argc] = new char [inputIn.length()+1];
	strcpy(argv[argc], inputIn.c_str());
        argc++;
	argv[argc] = new char [dummyPath.length()+1];
	strcpy(argv[argc], dummyPath.c_str());
	argc++;
  }
  for (int i = argc; i<8; i++) argv[i]=NULL;
}

virtual void TearDown() {
cerr << "Before delete expectedOptions\n";
delete expectedOptions;
expectedOptions = NULL;
for(int i=1; i<argc; i++) {
cerr << "LoopLoc" << i << endl;
  if(NULL != argv[i]) {
	delete[] argv[i];
        argv[i]=NULL;
}
cerr << "ItFinished" << i << endl;
}
}

};

TEST_P(ProcessCmdLineTest, ProcessesCorrectly) {
ASSERT_EQ(0, processedOptions.processCmdLine(argc, argv));
EXPECT_EQ(*expectedOptions, processedOptions);
}

INSTANTIATE_TEST_CASE_P(AllValidCombinations, ProcessCmdLineTest, ::testing::Combine( ValuesIn(helpStrings), ValuesIn(templateStrings), ValuesIn(debugStrings), ValuesIn(quietStrings), ValuesIn(inputPathStrings) ) );
#else
TEST(DummyTest, CombineIsNoteSupportedOnThisPlatform) {ASSERT_TRUE(false);}
#endif // GTEST_HAS_COMBINE

} // end namespace

int main(int argc, char * argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
<commit_msg>Remove debugging lines from test<commit_after>#include <string>
#include <cstring>
#include <sstream>
#include <tr1/tuple>
using namespace std;

#include <gtest/gtest.h>
#include "../src/options.hpp"

namespace {

class CmdLineOptionsTest : public ::testing::Test {
protected:
CmdLineOptions opts;
};

TEST_F(CmdLineOptionsTest, DefaultConstructor) {
EXPECT_FALSE(opts.getHelp());
EXPECT_FALSE(opts.getTemplate());
EXPECT_FALSE(opts.getDebug());
EXPECT_FALSE(opts.getQuiet());
EXPECT_EQ("", opts.getInputPath());
}

TEST_F(CmdLineOptionsTest, ExplicitConstructor) {
CmdLineOptions helpSet(true,false,false,false,"");
EXPECT_TRUE(helpSet.getHelp());
EXPECT_FALSE(helpSet.getTemplate());
EXPECT_FALSE(helpSet.getDebug());
EXPECT_FALSE(helpSet.getQuiet());
EXPECT_EQ("", helpSet.getInputPath());

CmdLineOptions tempSet(false,true,false,false,"");
EXPECT_FALSE(tempSet.getHelp());
EXPECT_TRUE(tempSet.getTemplate());
EXPECT_FALSE(tempSet.getDebug());
EXPECT_FALSE(tempSet.getQuiet());
EXPECT_EQ("", tempSet.getInputPath());

CmdLineOptions debugSet(false,false,true,false,"");
EXPECT_FALSE(debugSet.getHelp());
EXPECT_FALSE(debugSet.getTemplate());
EXPECT_TRUE(debugSet.getDebug());
EXPECT_FALSE(debugSet.getQuiet());
EXPECT_EQ("", debugSet.getInputPath());

CmdLineOptions quietSet(false,false,false,true,"");
EXPECT_FALSE(quietSet.getHelp());
EXPECT_FALSE(quietSet.getTemplate());
EXPECT_FALSE(quietSet.getDebug());
EXPECT_TRUE(quietSet.getQuiet());
EXPECT_EQ("", quietSet.getInputPath());

CmdLineOptions pathSet(false,false,false,false,"ExplicitConstructorPath");
EXPECT_FALSE(pathSet.getHelp());
EXPECT_FALSE(pathSet.getTemplate());
EXPECT_FALSE(pathSet.getDebug());
EXPECT_FALSE(pathSet.getQuiet());
EXPECT_EQ("ExplicitConstructorPath", pathSet.getInputPath());
}

TEST_F(CmdLineOptionsTest, Print) {
stringstream testStream;
string expectedResponse="Help:    \t0;\tTemplate:\t0;\nDebug:   \t0;\tQuiet:   \t0;\nInput path:\tPrintedPath\n";

opts.setInputPath("PrintedPath");

opts.print(testStream);
EXPECT_EQ(expectedResponse, testStream.str());
}

#ifdef GTEST_HAS_COMBINE
// Setup the command line processing
// Do it with tuples so we get all possible combos easily

using ::testing::ValuesIn;

string helpStrings[3] = {"-h", "--help", ""};
string templateStrings[3] = {"-t", "--template", ""};
string debugStrings[3] = {"-d", "--debug", ""};
string quietStrings[3] = {"-q", "--quiet", ""};
string inputPathStrings[3] = {"-i", "--input-path", ""};
char dummyProg[] = "PretendProg";
string dummyPath = "PretendInputFile";

class ProcessCmdLineTest : public ::testing::TestWithParam< tr1::tuple<string, string, string, string, string> > {
protected:
CmdLineOptions processedOptions;
CmdLineOptions* expectedOptions;
int argc;
char * argv[8];
virtual void SetUp() {
  string helpIn, tempIn, debugIn, quietIn, inputIn;
  tr1::tie(helpIn,tempIn,debugIn,quietIn,inputIn) = GetParam();
  expectedOptions = new CmdLineOptions(!helpIn.empty(), !tempIn.empty(), !debugIn.empty(), !quietIn.empty(), inputIn.empty() ? "" : "PretendInputFile");
  // Int args
  argv[0] = dummyProg;
  argc=1;
  // Fill argv appropriately
  if (!helpIn.empty()) {
        argv[argc] = new char [helpIn.length()+1];
	strcpy(argv[argc], helpIn.c_str());
        argc++;
  }
  if (!tempIn.empty()) {
        argv[argc] = new char [tempIn.length()+1];
	strcpy(argv[argc], tempIn.c_str());
        argc++;
  }
  if (!debugIn.empty()) {
        argv[argc] = new char [debugIn.length()+1];
	strcpy(argv[argc], debugIn.c_str());
        argc++;
  }
  if (!quietIn.empty()) {
        argv[argc] = new char [quietIn.length()+1];
	strcpy(argv[argc], quietIn.c_str());
        argc++;
  }
  if (!inputIn.empty()) {
        argv[argc] = new char [inputIn.length()+1];
	strcpy(argv[argc], inputIn.c_str());
        argc++;
	argv[argc] = new char [dummyPath.length()+1];
	strcpy(argv[argc], dummyPath.c_str());
	argc++;
  }
  for (int i = argc; i<8; i++) argv[i]=NULL;
}

virtual void TearDown() {
delete expectedOptions;
expectedOptions = NULL;
for(int i=1; i<argc; i++) {
  if(NULL != argv[i]) {
	delete[] argv[i];
        argv[i]=NULL;
}
}
}

};

TEST_P(ProcessCmdLineTest, ProcessesCorrectly) {
ASSERT_EQ(0, processedOptions.processCmdLine(argc, argv));
EXPECT_EQ(*expectedOptions, processedOptions);
}

INSTANTIATE_TEST_CASE_P(AllValidCombinations, ProcessCmdLineTest, ::testing::Combine( ValuesIn(helpStrings), ValuesIn(templateStrings), ValuesIn(debugStrings), ValuesIn(quietStrings), ValuesIn(inputPathStrings) ) );
#else
TEST(DummyTest, CombineIsNoteSupportedOnThisPlatform) {ASSERT_TRUE(false);}
#endif // GTEST_HAS_COMBINE

} // end namespace

int main(int argc, char * argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <NIHeaders.hpp>
#include <iostream>
#include <iomanip>

int compare_codes(void)
{
    //typedef double RealType;
    typedef mpfr::mpreal RealType;
    //RealType::set_default_prec(128);
    RealType::set_default_prec(256);

    typedef Kronrod::LaurieGautschi<RealType> LaurieGautschiPolicy;
    typedef LaurieGautschiPolicy::IndexType IndexType;
    typedef LaurieGautschiPolicy::VectorType VectorType;

    const IndexType N=15;
    const int outputIntegers = 33;

    Eigen::Array<RealType,Dynamic,2> ans;
    ans = Kronrod::multiPrecisionKronrod<RealType>(N);

    std::cout<<std::fixed;
    std::cout<<std::endl<<"MS Laurie Gautschi"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers) << ans.col(0)(i)
          << "\t" << ans.col(1)(i) << std::endl;
    }

    VectorType x=VectorType::Zero(2*N+1);
    VectorType w=VectorType::Zero(2*N+1);
    LaurieGautschiPolicy::mpkonrad(N,x,w);

    std::cout<<"\nSTB Laurie Gautschi"<<std::endl;
    for(IndexType i=0;i<x.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers) << x(i)
          << "\t" << w(i) << std::endl;
    }

    x=VectorType::Zero(N);
    w=VectorType::Zero(N);
    LaurieGautschiPolicy::mpgauss(N,x,w);
    std::cout<<std::endl;
    for(IndexType i=0;i<x.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers) << x(i)
          << "\t" << w(i) << std::endl;
    }

    Eigen::Array<RealType, Dynamic, 1> xGKPosAndNeg
    = Eigen::Array<RealType, Dynamic, 1>::Zero(x.rows());
    Eigen::Array<RealType, Dynamic, 1> wGKPosAndNeg
    = Eigen::Array<RealType, Dynamic, 1>::Zero(x.rows());

    Eigen::Array<RealType, Dynamic, 1> xGK;
    Eigen::Array<RealType, Dynamic, 1> wGK;
    Eigen::Array<RealType, Dynamic, 1> wG;

    Kronrod::kronrod(N, xGK,  wGK, wG);

    for(IndexType i=0; i<xGK.rows(); ++i)
    {
        xGKPosAndNeg(i) = -xGK(i);
        wGKPosAndNeg(i) = wGK(i);
    }

    for(IndexType i=0; i<xGK.rows(); ++i)
    {
        xGKPosAndNeg(xGKPosAndNeg.rows()-1-i) = xGK(i);
        wGKPosAndNeg(wGKPosAndNeg.rows()-1-i) = wGK(i);
    }

    std::cout << "\nMS Piessens" << std::endl;
    for(IndexType i=0;i<xGKPosAndNeg.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers) << xGKPosAndNeg(i)
          << "\t"<<wGKPosAndNeg(i) << std::endl;
    }

    std::cout << std::endl;

    for(IndexType i=0;i<wG.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers) << wG(i) << std::endl;
    }

    std::cout<<std::endl;

/*------------------------Output of Differences Between Approaches-------------------------------//

    std::cout<<"\nSolution Differences: MS - STB Laurie Gautschi"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(15) << ans(i,0) - x(i)
          << "\t" << ans(i,1) - w(i) << std::endl;
    }

    std::cout<<"\nSolution Differences: MS Laurie Gautschi - MS Piessens"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(15) << ans(i,0) - xGKPosAndNeg(i)
          << "\t" << ans(i,1) - wGKPosAndNeg(i) << std::endl;
    }

    std::cout<<"\nSolution Differences: STB Laurie Gautschi - MS Piessens"<<std::endl;
    for(int i=0;i<x.rows();++i)
    {
        std::cout  << std::setprecision(15) << x(i) - xGKPosAndNeg(i)
           << "\t" << w(i) - wGKPosAndNeg(i) << std::endl;
    }

//-----------------------End Output of Differences Between Approaches----------------------------*/

    return EXIT_SUCCESS;
}

int main(void)
{
    int ret = 0;
    ret += compare_codes();

    return ret;
}
<commit_msg>Repair indices in testLaurieGautschi.cpp.<commit_after>#include <NIHeaders.hpp>
#include <iostream>
#include <iomanip>

int compare_codes(void)
{
    //typedef double RealType;
    typedef mpfr::mpreal RealType;
    //RealType::set_default_prec(128);
    RealType::set_default_prec(256);

    typedef Kronrod::LaurieGautschi<RealType> LaurieGautschiPolicy;
    typedef LaurieGautschiPolicy::IndexType IndexType;
    typedef LaurieGautschiPolicy::VectorType VectorType;

    const IndexType N = 15;
    const int outputIntegers = 33;

    Eigen::Array<RealType,Dynamic,2> ans;
    ans = Kronrod::multiPrecisionKronrod<RealType>(N);

    std::cout<<std::fixed;
    std::cout<<std::endl<<"MS Laurie Gautschi"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(outputIntegers);
        std::cout << ans.col(0)(i) << "\t" << ans.col(1)(i) << std::endl;
    }

    VectorType xGK =VectorType::Zero(2*N+1);
    VectorType wGK =VectorType::Zero(2*N+1);
    LaurieGautschiPolicy::mpkonrad(N,xGK,wGK);

    std::cout<<"\nSTB Laurie Gautschi"<<std::endl;
    for(IndexType i = 0; i < xGK.rows(); ++i)
    {
        std::cout << std::setprecision(outputIntegers);
        std::cout << xGK(i) << "\t" << wGK(i) << std::endl;
    }

    VectorType xG = VectorType::Zero(N);
    VectorType wG = VectorType::Zero(N);

    LaurieGautschiPolicy::mpgauss(N,xG,wG);

    std::cout<<std::endl;
    for(IndexType i = 0; i < xG.rows(); ++i)
    {
        std::cout << std::setprecision(outputIntegers);
        std::cout << xG(i) << "\t" << wG(i) << std::endl;
    }

    Eigen::Array<RealType, Dynamic, 1> xGKPiessens;
    Eigen::Array<RealType, Dynamic, 1> wGKPiessens;
    Eigen::Array<RealType, Dynamic, 1> wGPiessens;

    Kronrod::kronrod(N, xGKPiessens,  wGKPiessens, wGPiessens);

    for(IndexType i = 0; i < xGKPiessens.rows(); ++i)
    {
        xGK(i) = -xGKPiessens(i);
        wGK(i) = wGKPiessens(i);
    }

    for(IndexType i=0; i<xGKPiessens.rows(); ++i)
    {
        xGK(xGK.rows()-1-i) = xGKPiessens(i);
        wGK(wGK.rows()-1-i) = wGKPiessens(i);
    }

    std::cout << "\nMS Piessens" << std::endl;
    for(IndexType i = 0; i < xGK.rows(); ++i)
    {
        std::cout << std::setprecision(outputIntegers);
        std::cout << xGK(i) << "\t" << wGK(i) << std::endl;
    }

    std::cout << std::endl;

    for(IndexType i = 0; i < wGPiessens.rows(); ++i)
    {
        std::cout << std::setprecision(outputIntegers);
        std::cout << wGPiessens(i) << std::endl;
    }

    std::cout<<std::endl;

/*------------------------Output of Differences Between Approaches-------------------------------//

    std::cout<<"\nSolution Differences: MS - STB Laurie Gautschi"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(15) << ans(i,0) - x(i)
          << "\t" << ans(i,1) - w(i) << std::endl;
    }

    std::cout<<"\nSolution Differences: MS Laurie Gautschi - MS Piessens"<<std::endl;
    for(int i=0;i<ans.rows();++i)
    {
        std::cout << std::setprecision(15) << ans(i,0) - xGKPosAndNeg(i)
          << "\t" << ans(i,1) - wGKPosAndNeg(i) << std::endl;
    }

    std::cout<<"\nSolution Differences: STB Laurie Gautschi - MS Piessens"<<std::endl;
    for(int i=0;i<x.rows();++i)
    {
        std::cout  << std::setprecision(15) << x(i) - xGKPosAndNeg(i)
           << "\t" << w(i) - wGKPosAndNeg(i) << std::endl;
    }

//-----------------------End Output of Differences Between Approaches----------------------------*/

    return EXIT_SUCCESS;
}

int main(void)
{
    int ret = 0;
    ret += compare_codes();

    return ret;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#include <akonadi/private/xdgbasedirs_p.h>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "serveradaptor.h"

#include "cachecleaner.h"
#include "intervalcheck.h"
#include "storage/datastore.h"
#include "notificationmanager.h"
#include "resourcemanager.h"
#include "tracer.h"
#include "xesammanager.h"
#include "nepomukmanager.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QProcess>
#include <QtCore/QSettings>
#include <QtCore/QTimer>

#include <unistd.h>
#include <stdlib.h>

using namespace Akonadi;

static AkonadiServer *s_instance = 0;

AkonadiServer::AkonadiServer( QObject* parent )
    : QLocalServer( parent )
    , mCacheCleaner( 0 )
    , mIntervalChecker( 0 )
    , mDatabaseProcess( 0 )
    , mAlreadyShutdown( false )
{
    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    if ( settings.value( QLatin1String("General/Driver"), QLatin1String( "QMYSQL" ) ).toString() == QLatin1String( "QMYSQL" )
         && settings.value( QLatin1String( "QMYSQL/StartServer" ), true ).toBool() )
      startDatabaseProcess();

    s_instance = this;

    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile(
    XdgBaseDirs::WriteOnly );

    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );

#ifdef Q_OS_WIN
    QString namedPipe = settings.value( QLatin1String( "Connection/NamedPipe" ), QLatin1String( "Akonadi" ) ).toString();
    if ( !listen( namedPipe ) )
      qFatal( "Unable to listen on Named Pipe %s", namedPipe.toLocal8Bit().data() );

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "NamedPipe" ) );
    connectionSettings.setValue( QLatin1String( "Data/NamedPipe" ), namedPipe );
#else
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();
    if ( socketDir[0] != QLatin1Char( '/' ) ) {
      QDir::home().mkdir( socketDir );
      socketDir = QDir::homePath() + QLatin1Char( '/' ) + socketDir;
    }

    const QString socketFile = socketDir + QLatin1String( "/akonadiserver.socket" );
    unlink( socketFile.toUtf8().constData() );
    if ( !listen( socketFile ) )
      qFatal("Unable to listen on Unix socket '%s'", socketFile.toLocal8Bit().data() );

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "UnixPath" ) );
    connectionSettings.setValue( QLatin1String( "Data/UnixPath" ), socketFile );
#endif

    // initialize the database
    DataStore *db = DataStore::self();
    if ( !db->database().isOpen() )
      qFatal("Unable to open database.");
    if ( !db->init() )
      qFatal("Unable to initialize database.");

    NotificationManager::self();
    Tracer::self();
    ResourceManager::self();
    if ( settings.value( QLatin1String( "Cache/EnableCleaner" ), true ).toBool() ) {
      mCacheCleaner = new CacheCleaner( this );
      mCacheCleaner->start( QThread::IdlePriority );
    }

    mIntervalChecker = new IntervalCheck( this );
    mIntervalChecker->start( QThread::IdlePriority );

    mSearchManager = new DummySearchManager;

    new ServerAdaptor( this );
    QDBusConnection::sessionBus().registerObject( QLatin1String( "/Server" ), this );

    char* dbusAddress = getenv( "DBUS_SESSION_BUS_ADDRESS" );
    if ( dbusAddress != 0 ) {
      connectionSettings.setValue( QLatin1String( "DBUS/Address" ), QLatin1String( dbusAddress ) );
    }
}

AkonadiServer::~AkonadiServer()
{
}

void AkonadiServer::quit()
{
    if ( mAlreadyShutdown )
      return;

    mAlreadyShutdown = true;

    if ( mCacheCleaner )
      QMetaObject::invokeMethod( mCacheCleaner, "quit", Qt::QueuedConnection );
    if ( mIntervalChecker )
      QMetaObject::invokeMethod( mIntervalChecker, "quit", Qt::QueuedConnection );
    QCoreApplication::instance()->processEvents();

    if ( mCacheCleaner )
      mCacheCleaner->wait();
    if ( mIntervalChecker )
      mIntervalChecker->wait();

    delete mSearchManager;
    mSearchManager = 0;

    for ( int i = 0; i < mConnections.count(); ++i ) {
      if ( mConnections[ i ] ) {
        mConnections[ i ]->quit();
        mConnections[ i ]->wait();
      }
    }

    DataStore::self()->close();

    // execute the deleteLater() calls for the threads so they free their db connections
    // and the following db termination will work
    QCoreApplication::instance()->processEvents();

    if ( mDatabaseProcess )
      stopDatabaseProcess();

    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );

#ifndef Q_OS_WIN
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    const QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();

    if ( !QDir::home().remove( socketDir + QLatin1String( "/akonadiserver.socket" ) ) )
        qWarning("Failed to remove Unix socket");
#endif
    if ( !QDir::home().remove( connectionSettingsFile ) )
        qWarning("Failed to remove runtime connection config file");

    QTimer::singleShot( 0, this, SLOT( doQuit() ) );
}

void AkonadiServer::doQuit()
{
    QCoreApplication::exit();
}

void AkonadiServer::incomingConnection( quintptr socketDescriptor )
{
    QPointer<AkonadiConnection> thread = new AkonadiConnection( socketDescriptor, this );
    connect( thread, SIGNAL( finished() ), thread, SLOT( deleteLater() ) );
    mConnections.append( thread );
    thread->start();
}

AkonadiServer * AkonadiServer::instance()
{
    if ( !s_instance )
        s_instance = new AkonadiServer();
    return s_instance;
}

void AkonadiServer::startDatabaseProcess()
{
#ifdef MYSQLD_EXECUTABLE
  const QString mysqldPath = QLatin1String( MYSQLD_EXECUTABLE );
#else
  const QString mysqldPath;
  Q_ASSERT_X( false, "AkonadiServer::startDatabaseProcess()",
              "mysqld was not found during compile time, you need to start a MySQL server yourself first and configure Akonadi accordingly" );
#endif

  // create the database directories if they don't exists
  const QString dataDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/db_data" ) );
  const QString akDir   = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/" ) );
  const QString miscDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/db_misc" ) );

  // generate config file
  const QString globalConfig = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-global.conf" ) );
  const QString localConfig  = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-local.conf" ) );
  const QString actualConfig = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) ) + QLatin1String("/mysql.conf");
  if ( globalConfig.isEmpty() )
    qFatal("Where is my MySQL config file??");
  QFile globalFile( globalConfig );
  QFile actualFile( actualConfig );
  if ( globalFile.open( QFile::ReadOnly ) && actualFile.open( QFile::WriteOnly ) ) {
    actualFile.write( globalFile.readAll() );
    if ( !localConfig.isEmpty() ) {
      QFile localFile( localConfig );
      if ( localFile.open( QFile::ReadOnly ) ) {
        actualFile.write( localFile.readAll() );
        localFile.close();
      }
    }
    actualFile.close();
    globalFile.close();
  } else {
    qFatal("What did you do to my MySQL config file??");
  }

  if ( dataDir.isEmpty() )
    qFatal("Akonadi server was not able not create database data directory");

  if ( akDir.isEmpty() )
    qFatal("Akonadi server was not able not create database log directory");

  if ( miscDir.isEmpty() )
    qFatal("Akonadi server was not able not create database misc directory");

  // synthesize the mysqld command
  QStringList arguments;
  arguments << QString::fromLatin1( "--defaults-file=%1/mysql.conf" ).arg( akDir );
  arguments << QString::fromLatin1( "--datadir=%1/" ).arg( dataDir );
  arguments << QString::fromLatin1( "--socket=%1/mysql.socket" ).arg( miscDir );

  mDatabaseProcess = new QProcess( this );
  mDatabaseProcess->start( mysqldPath, arguments );
  if ( !mDatabaseProcess->waitForStarted() )
    qFatal( "Could not start database server '%s'", qPrintable( mysqldPath ) );

  {
    QSqlDatabase db = QSqlDatabase::addDatabase( QLatin1String( "QMYSQL" ), QLatin1String( "initConnection" ) );
    db.setConnectOptions( QString::fromLatin1( "UNIX_SOCKET=%1/mysql.socket" ).arg( miscDir ) );

    bool opened = false;
    for ( int i = 0; i < 60; ++i ) {
      opened = db.open();
      if ( opened )
        break;

      sleep( 1 );
    }

    if ( opened ) {
      QSqlQuery query( db );
      if ( !query.exec( QLatin1String( "USE DATABASE akonadi" ) ) )
        query.exec( QLatin1String( "CREATE DATABASE akonadi" ) );

      db.close();
    }
  }

  QSqlDatabase::removeDatabase( QLatin1String( "initConnection" ) );
}

void AkonadiServer::stopDatabaseProcess()
{
  mDatabaseProcess->terminate();
  mDatabaseProcess->waitForFinished();
}

#include "akonadi.moc"
<commit_msg>Patch by Dmitry Ivanov <vonami@gmail.com> to detect mysqld start failures earlier.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#include <akonadi/private/xdgbasedirs_p.h>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "serveradaptor.h"

#include "cachecleaner.h"
#include "intervalcheck.h"
#include "storage/datastore.h"
#include "notificationmanager.h"
#include "resourcemanager.h"
#include "tracer.h"
#include "xesammanager.h"
#include "nepomukmanager.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QProcess>
#include <QtCore/QSettings>
#include <QtCore/QTimer>

#include <unistd.h>
#include <stdlib.h>

using namespace Akonadi;

static AkonadiServer *s_instance = 0;

AkonadiServer::AkonadiServer( QObject* parent )
    : QLocalServer( parent )
    , mCacheCleaner( 0 )
    , mIntervalChecker( 0 )
    , mDatabaseProcess( 0 )
    , mAlreadyShutdown( false )
{
    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    if ( settings.value( QLatin1String("General/Driver"), QLatin1String( "QMYSQL" ) ).toString() == QLatin1String( "QMYSQL" )
         && settings.value( QLatin1String( "QMYSQL/StartServer" ), true ).toBool() )
      startDatabaseProcess();

    s_instance = this;

    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile(
    XdgBaseDirs::WriteOnly );

    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );

#ifdef Q_OS_WIN
    QString namedPipe = settings.value( QLatin1String( "Connection/NamedPipe" ), QLatin1String( "Akonadi" ) ).toString();
    if ( !listen( namedPipe ) )
      qFatal( "Unable to listen on Named Pipe %s", namedPipe.toLocal8Bit().data() );

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "NamedPipe" ) );
    connectionSettings.setValue( QLatin1String( "Data/NamedPipe" ), namedPipe );
#else
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();
    if ( socketDir[0] != QLatin1Char( '/' ) ) {
      QDir::home().mkdir( socketDir );
      socketDir = QDir::homePath() + QLatin1Char( '/' ) + socketDir;
    }

    const QString socketFile = socketDir + QLatin1String( "/akonadiserver.socket" );
    unlink( socketFile.toUtf8().constData() );
    if ( !listen( socketFile ) )
      qFatal("Unable to listen on Unix socket '%s'", socketFile.toLocal8Bit().data() );

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "UnixPath" ) );
    connectionSettings.setValue( QLatin1String( "Data/UnixPath" ), socketFile );
#endif

    // initialize the database
    DataStore *db = DataStore::self();
    if ( !db->database().isOpen() )
      qFatal("Unable to open database.");
    if ( !db->init() )
      qFatal("Unable to initialize database.");

    NotificationManager::self();
    Tracer::self();
    ResourceManager::self();
    if ( settings.value( QLatin1String( "Cache/EnableCleaner" ), true ).toBool() ) {
      mCacheCleaner = new CacheCleaner( this );
      mCacheCleaner->start( QThread::IdlePriority );
    }

    mIntervalChecker = new IntervalCheck( this );
    mIntervalChecker->start( QThread::IdlePriority );

    mSearchManager = new DummySearchManager;

    new ServerAdaptor( this );
    QDBusConnection::sessionBus().registerObject( QLatin1String( "/Server" ), this );

    char* dbusAddress = getenv( "DBUS_SESSION_BUS_ADDRESS" );
    if ( dbusAddress != 0 ) {
      connectionSettings.setValue( QLatin1String( "DBUS/Address" ), QLatin1String( dbusAddress ) );
    }
}

AkonadiServer::~AkonadiServer()
{
}

void AkonadiServer::quit()
{
    if ( mAlreadyShutdown )
      return;

    mAlreadyShutdown = true;

    if ( mCacheCleaner )
      QMetaObject::invokeMethod( mCacheCleaner, "quit", Qt::QueuedConnection );
    if ( mIntervalChecker )
      QMetaObject::invokeMethod( mIntervalChecker, "quit", Qt::QueuedConnection );
    QCoreApplication::instance()->processEvents();

    if ( mCacheCleaner )
      mCacheCleaner->wait();
    if ( mIntervalChecker )
      mIntervalChecker->wait();

    delete mSearchManager;
    mSearchManager = 0;

    for ( int i = 0; i < mConnections.count(); ++i ) {
      if ( mConnections[ i ] ) {
        mConnections[ i ]->quit();
        mConnections[ i ]->wait();
      }
    }

    DataStore::self()->close();

    // execute the deleteLater() calls for the threads so they free their db connections
    // and the following db termination will work
    QCoreApplication::instance()->processEvents();

    if ( mDatabaseProcess )
      stopDatabaseProcess();

    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );

#ifndef Q_OS_WIN
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    const QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();

    if ( !QDir::home().remove( socketDir + QLatin1String( "/akonadiserver.socket" ) ) )
        qWarning("Failed to remove Unix socket");
#endif
    if ( !QDir::home().remove( connectionSettingsFile ) )
        qWarning("Failed to remove runtime connection config file");

    QTimer::singleShot( 0, this, SLOT( doQuit() ) );
}

void AkonadiServer::doQuit()
{
    QCoreApplication::exit();
}

void AkonadiServer::incomingConnection( quintptr socketDescriptor )
{
    QPointer<AkonadiConnection> thread = new AkonadiConnection( socketDescriptor, this );
    connect( thread, SIGNAL( finished() ), thread, SLOT( deleteLater() ) );
    mConnections.append( thread );
    thread->start();
}

AkonadiServer * AkonadiServer::instance()
{
    if ( !s_instance )
        s_instance = new AkonadiServer();
    return s_instance;
}

void AkonadiServer::startDatabaseProcess()
{
#ifdef MYSQLD_EXECUTABLE
  const QString mysqldPath = QLatin1String( MYSQLD_EXECUTABLE );
#else
  const QString mysqldPath;
  Q_ASSERT_X( false, "AkonadiServer::startDatabaseProcess()",
              "mysqld was not found during compile time, you need to start a MySQL server yourself first and configure Akonadi accordingly" );
#endif

  // create the database directories if they don't exists
  const QString dataDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/db_data" ) );
  const QString akDir   = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/" ) );
  const QString miscDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/db_misc" ) );

  // generate config file
  const QString globalConfig = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-global.conf" ) );
  const QString localConfig  = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-local.conf" ) );
  const QString actualConfig = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) ) + QLatin1String("/mysql.conf");
  if ( globalConfig.isEmpty() )
    qFatal("Where is my MySQL config file??");
  QFile globalFile( globalConfig );
  QFile actualFile( actualConfig );
  if ( globalFile.open( QFile::ReadOnly ) && actualFile.open( QFile::WriteOnly ) ) {
    actualFile.write( globalFile.readAll() );
    if ( !localConfig.isEmpty() ) {
      QFile localFile( localConfig );
      if ( localFile.open( QFile::ReadOnly ) ) {
        actualFile.write( localFile.readAll() );
        localFile.close();
      }
    }
    actualFile.close();
    globalFile.close();
  } else {
    qFatal("What did you do to my MySQL config file??");
  }

  if ( dataDir.isEmpty() )
    qFatal("Akonadi server was not able not create database data directory");

  if ( akDir.isEmpty() )
    qFatal("Akonadi server was not able not create database log directory");

  if ( miscDir.isEmpty() )
    qFatal("Akonadi server was not able not create database misc directory");

  // synthesize the mysqld command
  QStringList arguments;
  arguments << QString::fromLatin1( "--defaults-file=%1/mysql.conf" ).arg( akDir );
  arguments << QString::fromLatin1( "--datadir=%1/" ).arg( dataDir );
  arguments << QString::fromLatin1( "--socket=%1/mysql.socket" ).arg( miscDir );

  mDatabaseProcess = new QProcess( this );
  mDatabaseProcess->start( mysqldPath, arguments );
  if ( !mDatabaseProcess->waitForStarted() )
    qFatal( "Could not start database server '%s'", qPrintable( mysqldPath ) );

  {
    QSqlDatabase db = QSqlDatabase::addDatabase( QLatin1String( "QMYSQL" ), QLatin1String( "initConnection" ) );
    db.setConnectOptions( QString::fromLatin1( "UNIX_SOCKET=%1/mysql.socket" ).arg( miscDir ) );

    bool opened = false;
    for ( int i = 0; i < 120; ++i ) {
      opened = db.open();
      if ( opened )
        break;
      if ( mDatabaseProcess->waitForFinished( 500 ) )
        qFatal( "Database server exited unexpectedly, exit code %d", mDatabaseProcess->exitCode() );
    }

    if ( opened ) {
      QSqlQuery query( db );
      if ( !query.exec( QLatin1String( "USE DATABASE akonadi" ) ) )
        query.exec( QLatin1String( "CREATE DATABASE akonadi" ) );

      db.close();
    }
  }

  QSqlDatabase::removeDatabase( QLatin1String( "initConnection" ) );
}

void AkonadiServer::stopDatabaseProcess()
{
  mDatabaseProcess->terminate();
  mDatabaseProcess->waitForFinished();
}

#include "akonadi.moc"
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/download_throttling_resource_handler.h"

#include "base/logging.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"

DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler(
    ResourceDispatcherHost* host,
    URLRequest* request,
    const GURL& url,
    int render_process_host_id,
    int render_view_id,
    int request_id,
    bool in_complete)
    : host_(host),
      request_(request),
      url_(url),
      render_process_host_id_(render_process_host_id),
      render_view_id_(render_view_id),
      request_id_(request_id),
      tmp_buffer_length_(0),
      ignore_on_read_complete_(in_complete) {
  // Pause the request.
  host_->PauseRequest(render_process_host_id_, request_id_, true);
  host_->download_request_manager()->CanDownloadOnIOThread(
      render_process_host_id_, render_view_id, this);
 }

DownloadThrottlingResourceHandler::~DownloadThrottlingResourceHandler() {
}

bool DownloadThrottlingResourceHandler::OnUploadProgress(int request_id,
                                                         uint64 position,
                                                         uint64 size) {
  if (download_handler_.get())
    return download_handler_->OnUploadProgress(request_id, position, size);
  return true;
}

bool DownloadThrottlingResourceHandler::OnRequestRedirected(
    int request_id,
    const GURL& url,
    ResourceResponse* response,
    bool* defer) {
  if (download_handler_.get()) {
    return download_handler_->OnRequestRedirected(
        request_id, url, response, defer);
  }
  url_ = url;
  return true;
}

bool DownloadThrottlingResourceHandler::OnResponseStarted(
    int request_id,
    ResourceResponse* response) {
  if (download_handler_.get())
    return download_handler_->OnResponseStarted(request_id, response);
  response_ = response;
  return true;
}

bool DownloadThrottlingResourceHandler::OnWillStart(int request_id,
                                                    const GURL& url,
                                                    bool* defer) {
  if (download_handler_.get())
    return download_handler_->OnWillStart(request_id, url, defer);
  return true;
}

bool DownloadThrottlingResourceHandler::OnWillRead(int request_id,
                                                   net::IOBuffer** buf,
                                                   int* buf_size,
                                                   int min_size) {
  if (download_handler_.get())
    return download_handler_->OnWillRead(request_id, buf, buf_size, min_size);

  // We should only have this invoked once, as such we only deal with one
  // tmp buffer.
  DCHECK(!tmp_buffer_.get());
  if (min_size < 0)
    min_size = 1024;
  tmp_buffer_ = new net::IOBuffer(min_size);
  *buf = tmp_buffer_.get();
  // TODO(willchan): Remove after debugging bug 16371.
  CHECK((*buf)->data());
  *buf_size = min_size;
  return true;
}

bool DownloadThrottlingResourceHandler::OnReadCompleted(int request_id,
                                                        int* bytes_read) {
  if (ignore_on_read_complete_) {
    // See comments above definition for details on this.
    ignore_on_read_complete_ = false;
    return true;
  }
  if (!*bytes_read)
    return true;

  if (tmp_buffer_.get()) {
    DCHECK(!tmp_buffer_length_);
    tmp_buffer_length_ = *bytes_read;
    if (download_handler_.get())
      CopyTmpBufferToDownloadHandler();
    return true;
  }
  if (download_handler_.get())
    return download_handler_->OnReadCompleted(request_id, bytes_read);
  return true;
}

bool DownloadThrottlingResourceHandler::OnResponseCompleted(
    int request_id,
    const URLRequestStatus& status,
    const std::string& security_info) {
  if (download_handler_.get())
    return download_handler_->OnResponseCompleted(request_id, status,
                                                  security_info);

  // For a download, if ResourceDispatcher::Read() fails,
  // ResourceDispatcher::OnresponseStarted() will call
  // OnResponseCompleted(), and we will end up here with an error
  // status.
  if (!status.is_success())
    return false;
  NOTREACHED();
  return true;
}

void DownloadThrottlingResourceHandler::OnRequestClosed() {
  if (download_handler_.get())
    download_handler_->OnRequestClosed();
}

void DownloadThrottlingResourceHandler::CancelDownload() {
  host_->CancelRequest(render_process_host_id_, request_id_, false);
}

void DownloadThrottlingResourceHandler::ContinueDownload() {
  DCHECK(!download_handler_.get());
  download_handler_ =
      new DownloadResourceHandler(host_,
                                  render_process_host_id_,
                                  render_view_id_,
                                  request_id_,
                                  url_,
                                  host_->download_file_manager(),
                                  request_,
                                  false,
                                  DownloadSaveInfo());
  if (response_.get())
    download_handler_->OnResponseStarted(request_id_, response_.get());

  if (tmp_buffer_length_)
    CopyTmpBufferToDownloadHandler();

  // And let the request continue.
  host_->PauseRequest(render_process_host_id_, request_id_, false);
}

int DownloadThrottlingResourceHandler::GetRequestId() {
  return request_id_;
}

void DownloadThrottlingResourceHandler::CopyTmpBufferToDownloadHandler() {
  // Copy over the tmp buffer.
  net::IOBuffer* buffer;
  int buf_size;
  if (download_handler_->OnWillRead(request_id_, &buffer, &buf_size,
                                    tmp_buffer_length_)) {
    CHECK(buf_size >= tmp_buffer_length_);
    memcpy(buffer->data(), tmp_buffer_->data(), tmp_buffer_length_);
    download_handler_->OnReadCompleted(request_id_, &tmp_buffer_length_);
  }
  tmp_buffer_length_ = 0;
  tmp_buffer_ = NULL;
}
<commit_msg>Fixing a constant which was the hardcoded value of 2*kNumBytesToSniff. When I  changed kNumBytesToSniff in 41687, it was left behind. <commit_after>// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/download_throttling_resource_handler.h"

#include "base/logging.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"

DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler(
    ResourceDispatcherHost* host,
    URLRequest* request,
    const GURL& url,
    int render_process_host_id,
    int render_view_id,
    int request_id,
    bool in_complete)
    : host_(host),
      request_(request),
      url_(url),
      render_process_host_id_(render_process_host_id),
      render_view_id_(render_view_id),
      request_id_(request_id),
      tmp_buffer_length_(0),
      ignore_on_read_complete_(in_complete) {
  // Pause the request.
  host_->PauseRequest(render_process_host_id_, request_id_, true);
  host_->download_request_manager()->CanDownloadOnIOThread(
      render_process_host_id_, render_view_id, this);
 }

DownloadThrottlingResourceHandler::~DownloadThrottlingResourceHandler() {
}

bool DownloadThrottlingResourceHandler::OnUploadProgress(int request_id,
                                                         uint64 position,
                                                         uint64 size) {
  if (download_handler_.get())
    return download_handler_->OnUploadProgress(request_id, position, size);
  return true;
}

bool DownloadThrottlingResourceHandler::OnRequestRedirected(
    int request_id,
    const GURL& url,
    ResourceResponse* response,
    bool* defer) {
  if (download_handler_.get()) {
    return download_handler_->OnRequestRedirected(
        request_id, url, response, defer);
  }
  url_ = url;
  return true;
}

bool DownloadThrottlingResourceHandler::OnResponseStarted(
    int request_id,
    ResourceResponse* response) {
  if (download_handler_.get())
    return download_handler_->OnResponseStarted(request_id, response);
  response_ = response;
  return true;
}

bool DownloadThrottlingResourceHandler::OnWillStart(int request_id,
                                                    const GURL& url,
                                                    bool* defer) {
  if (download_handler_.get())
    return download_handler_->OnWillStart(request_id, url, defer);
  return true;
}

bool DownloadThrottlingResourceHandler::OnWillRead(int request_id,
                                                   net::IOBuffer** buf,
                                                   int* buf_size,
                                                   int min_size) {
  if (download_handler_.get())
    return download_handler_->OnWillRead(request_id, buf, buf_size, min_size);

  // We should only have this invoked once, as such we only deal with one
  // tmp buffer.
  DCHECK(!tmp_buffer_.get());
  // If the caller passed a negative |min_size| then chose an appropriate
  // default. The BufferedResourceHandler requires this to be at least 2 times
  // the size required for mime detection.
  if (min_size < 0)
    min_size = 2 * net::kMaxBytesToSniff;
  tmp_buffer_ = new net::IOBuffer(min_size);
  *buf = tmp_buffer_.get();
  // TODO(willchan): Remove after debugging bug 16371.
  CHECK((*buf)->data());
  *buf_size = min_size;
  return true;
}

bool DownloadThrottlingResourceHandler::OnReadCompleted(int request_id,
                                                        int* bytes_read) {
  if (ignore_on_read_complete_) {
    // See comments above definition for details on this.
    ignore_on_read_complete_ = false;
    return true;
  }
  if (!*bytes_read)
    return true;

  if (tmp_buffer_.get()) {
    DCHECK(!tmp_buffer_length_);
    tmp_buffer_length_ = *bytes_read;
    if (download_handler_.get())
      CopyTmpBufferToDownloadHandler();
    return true;
  }
  if (download_handler_.get())
    return download_handler_->OnReadCompleted(request_id, bytes_read);
  return true;
}

bool DownloadThrottlingResourceHandler::OnResponseCompleted(
    int request_id,
    const URLRequestStatus& status,
    const std::string& security_info) {
  if (download_handler_.get())
    return download_handler_->OnResponseCompleted(request_id, status,
                                                  security_info);

  // For a download, if ResourceDispatcher::Read() fails,
  // ResourceDispatcher::OnresponseStarted() will call
  // OnResponseCompleted(), and we will end up here with an error
  // status.
  if (!status.is_success())
    return false;
  NOTREACHED();
  return true;
}

void DownloadThrottlingResourceHandler::OnRequestClosed() {
  if (download_handler_.get())
    download_handler_->OnRequestClosed();
}

void DownloadThrottlingResourceHandler::CancelDownload() {
  host_->CancelRequest(render_process_host_id_, request_id_, false);
}

void DownloadThrottlingResourceHandler::ContinueDownload() {
  DCHECK(!download_handler_.get());
  download_handler_ =
      new DownloadResourceHandler(host_,
                                  render_process_host_id_,
                                  render_view_id_,
                                  request_id_,
                                  url_,
                                  host_->download_file_manager(),
                                  request_,
                                  false,
                                  DownloadSaveInfo());
  if (response_.get())
    download_handler_->OnResponseStarted(request_id_, response_.get());

  if (tmp_buffer_length_)
    CopyTmpBufferToDownloadHandler();

  // And let the request continue.
  host_->PauseRequest(render_process_host_id_, request_id_, false);
}

int DownloadThrottlingResourceHandler::GetRequestId() {
  return request_id_;
}

void DownloadThrottlingResourceHandler::CopyTmpBufferToDownloadHandler() {
  // Copy over the tmp buffer.
  net::IOBuffer* buffer;
  int buf_size;
  if (download_handler_->OnWillRead(request_id_, &buffer, &buf_size,
                                    tmp_buffer_length_)) {
    CHECK(buf_size >= tmp_buffer_length_);
    memcpy(buffer->data(), tmp_buffer_->data(), tmp_buffer_length_);
    download_handler_->OnReadCompleted(request_id_, &tmp_buffer_length_);
  }
  tmp_buffer_length_ = 0;
  tmp_buffer_ = NULL;
}
<|endoftext|>


<commit_before>/*
 * filter_lightshow.cpp -- animate color to the audio
 * Copyright (C) 2015 Meltytech, LLC
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "common.h"
#include <framework/mlt.h>
#include <stdlib.h> // calloc(), free()
#include <math.h>   // sin()
#include <string.h> // strchr()
#include <QPainter>
#include <QTransform>
#include <QImage>

/** Get the image.
*/
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	int error = 0;
	// Get the filter
	mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );

	// Get the properties
	mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
	bool hasAlpha = false;

	// Only process if we have no error and a valid colour space
	mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
	mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );

	mlt_position position = mlt_filter_get_position( filter, frame );
	mlt_position length = mlt_filter_get_length2( filter, frame );
	mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
	double output_ar = mlt_profile_sar( profile );
	// Special case - aspect_ratio = 0
	if ( mlt_frame_get_aspect_ratio( frame ) == 0 )
		mlt_frame_set_aspect_ratio( frame, output_ar );

	// Check transform
	QTransform transform;
	int normalised_width = profile->width;
	int normalised_height = profile->height;
	double consumer_ar = mlt_profile_sar( profile );

	// Destination rect
	mlt_rect rect;
	rect.w = normalised_width * mlt_profile_scale_width(profile, *width);
	rect.h = normalised_height * mlt_profile_scale_height(profile, *height);
	int b_width = mlt_properties_get_int( frame_properties, "meta.media.width" );
	int b_height = mlt_properties_get_int( frame_properties, "meta.media.height" );
	if ( b_height == 0 )
	{
		b_width = normalised_width;
		b_height = normalised_height;
	}
	double b_ar = mlt_frame_get_aspect_ratio( frame );
	double b_dar = b_ar * b_width / b_height;
	double opacity = 1.0;
	bool consumerScaling = false;

	if ( mlt_properties_get( properties, "rect" ) )
	{
		rect = mlt_properties_anim_get_rect( properties, "rect", position, length );
		if (mlt_properties_get(properties, "rect") && ::strchr(mlt_properties_get(properties, "rect"), '%')) {
			rect.x *= normalised_width;
			rect.y *= normalised_height;
			rect.w *= normalised_width;
			rect.h *= normalised_height;
		}
		double scale = mlt_profile_scale_width(profile, *width);
		if ( scale != 1.0 ) {
			consumerScaling = true;
		}
		rect.x *= scale;
		rect.w *= scale;
		scale = mlt_profile_scale_height(profile, *height);
		if ( !consumerScaling && scale != 1.0 ) {
			consumerScaling = true;
		}
		rect.y *= scale;
		rect.h *= scale;
		transform.translate(rect.x, rect.y);
		opacity = rect.o;
		hasAlpha = true;
	}

	if ( mlt_properties_get( properties, "rotation" ) )
	{
		double angle = mlt_properties_anim_get_double( properties, "rotation", position, length );
		if (angle != 0.0) {
			if ( mlt_properties_get_int( properties, "rotate_center" ) )
			{
				transform.translate( rect.w / 2.0, rect.h / 2.0 );
				transform.rotate( angle );
				transform.translate( -rect.w / 2.0, -rect.h / 2.0 );
			}
			else
			{
				// old style rotation (from top left corner) to keep compatibility
				transform.rotate( angle );
			}
			hasAlpha = true;
		}
	}

	if ( !hasAlpha && ( mlt_properties_get_int( properties, "compositing" ) != 0 || b_width < *width || b_height < *height || b_width < normalised_width || b_height  < normalised_height ) )
	{
		hasAlpha = true;
	}

	if ( !hasAlpha ) {
		uint8_t *src_image = NULL;
		error = mlt_frame_get_image( frame, &src_image, format, &b_width, &b_height, 0 );
		if ( *format == mlt_image_rgb24a || mlt_frame_get_alpha( frame ) ) {
			hasAlpha = true;
		} else {
			// Prepare output image
			*image = src_image;
			*width = b_width;
			*height = b_height;
			return 0;
		}
	}

	// fetch image
	*format = mlt_image_rgb24a;
	uint8_t *src_image = NULL;

	// Adjust if consumer is scaling
	if ( consumerScaling )
	{
		// Scale request of b frame image to consumer scale maintaining its aspect ratio.
		b_height = *height;
		b_width = b_height * b_dar / b_ar;
	}

	error = mlt_frame_get_image( frame, &src_image, format, &b_width, &b_height, 0 );

	// Put source buffer into QImage
	QImage sourceImage;
	convert_mlt_to_qimage_rgba( src_image, &sourceImage, b_width, b_height );

	int image_size = mlt_image_format_size( *format, *width, *height, NULL );

	// resize to rect
	if ( mlt_properties_get_int( properties, "distort" ) )
	{
		transform.scale( rect.w / b_width, rect.h / b_height );
	}
	else
	{
		// Take the smaller scale between horizontal and vertical
		float scale_x = MIN( rect.w / b_width, rect.h / b_height );
		float scale_y = scale_x;

		// Determine scale with respect to aspect ratio.
		double geometry_dar = rect.w * consumer_ar / rect.h;
		double scale;
		if ( b_dar > geometry_dar )
		{
			scale = rect.w / b_width;
		}
		else
		{
			scale = rect.h / b_height * b_ar;
		}
		// Center image in rect
		transform.translate( ( rect.w - ( b_width * scale ) ) / 2.0, ( rect.h - ( b_height * scale ) ) / 2.0 );
		transform.scale( scale, scale );
	}

	uint8_t *dest_image = NULL;
	dest_image = (uint8_t *) mlt_pool_alloc( image_size );

	QImage destImage;
	convert_mlt_to_qimage_rgba( dest_image, &destImage, *width, *height );
	destImage.fill( mlt_properties_get_int( properties, "background_color" ) );

	QPainter painter( &destImage );
	painter.setCompositionMode( ( QPainter::CompositionMode ) mlt_properties_get_int( properties, "compositing" ) );
	painter.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
	painter.setTransform(transform);
	painter.setOpacity(opacity);
	// Composite top frame
	painter.drawImage(0, 0, sourceImage);
	// finish Qt drawing
	painter.end();
	convert_qimage_to_mlt_rgba( &destImage, dest_image, *width, *height );
	*image = dest_image;
	mlt_frame_set_image( frame, *image, *width * *height * 4, mlt_pool_release );
	return error;
}

/** Filter processing.
*/
static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
	mlt_frame_push_service( frame, filter );
	mlt_frame_push_get_image( frame, filter_get_image );

	return frame;
}

/** Constructor for the filter.
*/

extern "C" {

mlt_filter filter_qtblend_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
	mlt_filter filter = mlt_filter_new();

	if ( filter && createQApplicationIfNeeded( MLT_FILTER_SERVICE(filter) ) )
	{
		filter->process = filter_process;
		mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
		mlt_properties_set_int( properties, "rotate_center", 0 );
	}
	else
	{
		mlt_log_error( MLT_FILTER_SERVICE(filter), "Filter qtblend failed\n" );

		if( filter )
		{
			mlt_filter_close( filter );
		}

		filter = NULL;
	}
	return filter;
}

}

<commit_msg>Fix compile warnings<commit_after>/*
 * filter_lightshow.cpp -- animate color to the audio
 * Copyright (C) 2015 Meltytech, LLC
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "common.h"
#include <framework/mlt.h>
#include <stdlib.h> // calloc(), free()
#include <math.h>   // sin()
#include <string.h> // strchr()
#include <QPainter>
#include <QTransform>
#include <QImage>

/** Get the image.
*/
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	int error = 0;
	// Get the filter
	mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );

	// Get the properties
	mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
	bool hasAlpha = false;

	// Only process if we have no error and a valid colour space
	mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
	mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );

	mlt_position position = mlt_filter_get_position( filter, frame );
	mlt_position length = mlt_filter_get_length2( filter, frame );
	mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
	double output_ar = mlt_profile_sar( profile );
	// Special case - aspect_ratio = 0
	if ( mlt_frame_get_aspect_ratio( frame ) == 0 )
		mlt_frame_set_aspect_ratio( frame, output_ar );

	// Check transform
	QTransform transform;
	int normalised_width = profile->width;
	int normalised_height = profile->height;
	double consumer_ar = mlt_profile_sar( profile );

	// Destination rect
	mlt_rect rect = {0, 0, normalised_width * mlt_profile_scale_width(profile, *width), normalised_height * mlt_profile_scale_height(profile, *height), 1.0};
	int b_width = mlt_properties_get_int( frame_properties, "meta.media.width" );
	int b_height = mlt_properties_get_int( frame_properties, "meta.media.height" );
	if ( b_height == 0 )
	{
		b_width = normalised_width;
		b_height = normalised_height;
	}
	double b_ar = mlt_frame_get_aspect_ratio( frame );
	double b_dar = b_ar * b_width / b_height;
	double opacity = 1.0;
	bool consumerScaling = false;

	if ( mlt_properties_get( properties, "rect" ) )
	{
		rect = mlt_properties_anim_get_rect( properties, "rect", position, length );
		if (mlt_properties_get(properties, "rect") && ::strchr(mlt_properties_get(properties, "rect"), '%')) {
			rect.x *= normalised_width;
			rect.y *= normalised_height;
			rect.w *= normalised_width;
			rect.h *= normalised_height;
		}
		double scale = mlt_profile_scale_width(profile, *width);
		if ( scale != 1.0 ) {
			consumerScaling = true;
		}
		rect.x *= scale;
		rect.w *= scale;
		scale = mlt_profile_scale_height(profile, *height);
		if ( !consumerScaling && scale != 1.0 ) {
			consumerScaling = true;
		}
		rect.y *= scale;
		rect.h *= scale;
		transform.translate(rect.x, rect.y);
		opacity = rect.o;
		hasAlpha = true;
	}

	if ( mlt_properties_get( properties, "rotation" ) )
	{
		double angle = mlt_properties_anim_get_double( properties, "rotation", position, length );
		if (angle != 0.0) {
			if ( mlt_properties_get_int( properties, "rotate_center" ) )
			{
				transform.translate( rect.w / 2.0, rect.h / 2.0 );
				transform.rotate( angle );
				transform.translate( -rect.w / 2.0, -rect.h / 2.0 );
			}
			else
			{
				// old style rotation (from top left corner) to keep compatibility
				transform.rotate( angle );
			}
			hasAlpha = true;
		}
	}

	if ( !hasAlpha && ( mlt_properties_get_int( properties, "compositing" ) != 0 || b_width < *width || b_height < *height || b_width < normalised_width || b_height  < normalised_height ) )
	{
		hasAlpha = true;
	}

	if ( !hasAlpha ) {
		uint8_t *src_image = NULL;
		error = mlt_frame_get_image( frame, &src_image, format, &b_width, &b_height, 0 );
		if ( *format == mlt_image_rgb24a || mlt_frame_get_alpha( frame ) ) {
			hasAlpha = true;
		} else {
			// Prepare output image
			*image = src_image;
			*width = b_width;
			*height = b_height;
			return 0;
		}
	}

	// fetch image
	*format = mlt_image_rgb24a;
	uint8_t *src_image = NULL;

	// Adjust if consumer is scaling
	if ( consumerScaling )
	{
		// Scale request of b frame image to consumer scale maintaining its aspect ratio.
		b_height = *height;
		b_width = b_height * b_dar / b_ar;
	}

	error = mlt_frame_get_image( frame, &src_image, format, &b_width, &b_height, 0 );

	// Put source buffer into QImage
	QImage sourceImage;
	convert_mlt_to_qimage_rgba( src_image, &sourceImage, b_width, b_height );

	int image_size = mlt_image_format_size( *format, *width, *height, NULL );

	// resize to rect
	if ( mlt_properties_get_int( properties, "distort" ) )
	{
		transform.scale( rect.w / b_width, rect.h / b_height );
	}
	else
	{
		// Determine scale with respect to aspect ratio.
		double geometry_dar = rect.w * consumer_ar / rect.h;
		double scale;
		if ( b_dar > geometry_dar )
		{
			scale = rect.w / b_width;
		}
		else
		{
			scale = rect.h / b_height * b_ar;
		}
		// Center image in rect
		transform.translate( ( rect.w - ( b_width * scale ) ) / 2.0, ( rect.h - ( b_height * scale ) ) / 2.0 );
		transform.scale( scale, scale );
	}

	uint8_t *dest_image = NULL;
	dest_image = (uint8_t *) mlt_pool_alloc( image_size );

	QImage destImage;
	convert_mlt_to_qimage_rgba( dest_image, &destImage, *width, *height );
	destImage.fill( mlt_properties_get_int( properties, "background_color" ) );

	QPainter painter( &destImage );
	painter.setCompositionMode( ( QPainter::CompositionMode ) mlt_properties_get_int( properties, "compositing" ) );
	painter.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
	painter.setTransform(transform);
	painter.setOpacity(opacity);
	// Composite top frame
	painter.drawImage(0, 0, sourceImage);
	// finish Qt drawing
	painter.end();
	convert_qimage_to_mlt_rgba( &destImage, dest_image, *width, *height );
	*image = dest_image;
	mlt_frame_set_image( frame, *image, *width * *height * 4, mlt_pool_release );
	return error;
}

/** Filter processing.
*/
static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
{
	mlt_frame_push_service( frame, filter );
	mlt_frame_push_get_image( frame, filter_get_image );

	return frame;
}

/** Constructor for the filter.
*/

extern "C" {

mlt_filter filter_qtblend_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
	mlt_filter filter = mlt_filter_new();

	if ( filter && createQApplicationIfNeeded( MLT_FILTER_SERVICE(filter) ) )
	{
		filter->process = filter_process;
		mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
		mlt_properties_set_int( properties, "rotate_center", 0 );
	}
	else
	{
		mlt_log_error( MLT_FILTER_SERVICE(filter), "Filter qtblend failed\n" );

		if( filter )
		{
			mlt_filter_close( filter );
		}

		filter = NULL;
	}
	return filter;
}

}

<|endoftext|>


<commit_before>#include "catch.hpp"

#include <iostream>
#include <iomanip>

#include "glm/glm.hpp"
#include "util/mapProjection.h"

#include <stdio.h>

using namespace Tangram;

TEST_CASE( "Testing some functionality for mercator projection", "[MERCATOR][PROJECTION]" ) {
    MercatorProjection mercProjection = MercatorProjection();
    glm::dvec2 lonLat = glm::dvec2(0.0,0.0);
    glm::dvec2 worldCoord = glm::dvec2(0.0, 0.0);
    //glm::ivec3 tileCoord = glm::ivec3(2, 2, 3);
    double epsilon = 0.000000000000000001;
    //check if all the test tileCoordinates are loaded
    /*REQUIRE(dataSource.JsonRootSize() == 3);
    //check if all the test tiles have data in the jsonRoots data structure
    REQUIRE(dataSource.CheckDataExists("14_19293_24641") == true);
    REQUIRE(dataSource.CheckDataExists("16_19293_24641") == true);
    REQUIRE(dataSource.CheckDataExists("0_0_0") == true);
    REQUIRE(dataSource.CheckDataExists("0_1_0") == false);*/
    glm::dvec2 testMeters = mercProjection.LonLatToMeters(lonLat);
    glm::dvec2 testLonLat = mercProjection.MetersToLonLat(worldCoord);
    REQUIRE( (testMeters.x - worldCoord.x) < epsilon);
    REQUIRE( (testMeters.y - worldCoord.y) < epsilon);
    REQUIRE( (testLonLat.x - lonLat.x) < epsilon);
    REQUIRE( (testLonLat.y - lonLat.y) < epsilon);
}
<commit_msg>Adapted epsilon's accuracy to pass 32bit tests (#1762)<commit_after>#include "catch.hpp"

#include <iostream>
#include <iomanip>

#include "glm/glm.hpp"
#include "util/mapProjection.h"

#include <stdio.h>

using namespace Tangram;

TEST_CASE( "Testing some functionality for mercator projection", "[MERCATOR][PROJECTION]" ) {
    MercatorProjection mercProjection = MercatorProjection();
    glm::dvec2 lonLat = glm::dvec2(0.0,0.0);
    glm::dvec2 worldCoord = glm::dvec2(0.0, 0.0);
    //glm::ivec3 tileCoord = glm::ivec3(2, 2, 3);
    double epsilon = 0.000000000001;
    //check if all the test tileCoordinates are loaded
    /*REQUIRE(dataSource.JsonRootSize() == 3);
    //check if all the test tiles have data in the jsonRoots data structure
    REQUIRE(dataSource.CheckDataExists("14_19293_24641") == true);
    REQUIRE(dataSource.CheckDataExists("16_19293_24641") == true);
    REQUIRE(dataSource.CheckDataExists("0_0_0") == true);
    REQUIRE(dataSource.CheckDataExists("0_1_0") == false);*/
    glm::dvec2 testMeters = mercProjection.LonLatToMeters(lonLat);
    glm::dvec2 testLonLat = mercProjection.MetersToLonLat(worldCoord);
    REQUIRE( (testMeters.x - worldCoord.x) < epsilon);
    REQUIRE( (testMeters.y - worldCoord.y) < epsilon);
    REQUIRE( (testLonLat.x - lonLat.x) < epsilon);
    REQUIRE( (testLonLat.y - lonLat.y) < epsilon);
}
<|endoftext|>