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

// in this file we define the shell extension that renderdoc sets up to be able to
// display thumbnails of captures in windows explorer. We register as a thumbnail
// provider and either the installer or the UI installs the appropriate registry keys.

#include <thumbcache.h>
#include <windows.h>
#include "common/common.h"
#include "core/core.h"
#include "jpeg-compressor/jpgd.h"
#include "serialise/serialiser.h"

// {5D6BF029-A6BA-417A-8523-120492B1DCE3}
static const GUID CLSID_RDCThumbnailProvider = {0x5d6bf029,
                                                0xa6ba,
                                                0x417a,
                                                {0x85, 0x23, 0x12, 0x4, 0x92, 0xb1, 0xdc, 0xe3}};

unsigned int numProviders = 0;

struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream
{
  unsigned int m_iRefcount;
  bool m_Inited;
  Serialiser *m_Ser;

  RDCThumbnailProvider() : m_iRefcount(1), m_Inited(false), m_Ser(NULL)
  {
    InterlockedIncrement(&numProviders);
  }

  virtual ~RDCThumbnailProvider()
  {
    InterlockedDecrement(&numProviders);
    SAFE_DELETE(m_Ser);
  }

  ULONG STDMETHODCALLTYPE AddRef()
  {
    InterlockedIncrement(&m_iRefcount);
    return m_iRefcount;
  }
  ULONG STDMETHODCALLTYPE Release()
  {
    unsigned int ret = InterlockedDecrement(&m_iRefcount);
    if(ret == 0)
      delete this;
    return ret;
  }

  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
  {
    if(riid == CLSID_RDCThumbnailProvider)
    {
      *ppvObject = (void *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IThumbnailProvider))
    {
      *ppvObject = (void *)(IThumbnailProvider *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IInitializeWithStream))
    {
      *ppvObject = (void *)(IInitializeWithStream *)this;
      AddRef();
      return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE Initialize(IStream *pstream, DWORD grfMode)
  {
    if(m_Inited)
      return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);

    byte *buf = new byte[2 * 1024 * 1024 + 1];
    ULONG numRead = 0;
    HRESULT hr = pstream->Read(buf, 2 * 1024 * 1024, &numRead);

    if(hr != S_OK && hr != S_FALSE)
    {
      delete[] buf;
      return E_INVALIDARG;
    }

    RDCLOG("RDCThumbnailProvider Initialize read %d bytes from file", numRead);

    m_Ser = new Serialiser(numRead, buf, true);

    delete[] buf;

    m_Inited = true;

    return S_OK;
  }

  virtual HRESULT STDMETHODCALLTYPE GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha)
  {
    RDCLOG("RDCThumbnailProvider GetThumbnail %d", cx);

    if(!m_Inited || !m_Ser)
    {
      RDCERR("Not initialized");
      return E_NOTIMPL;
    }

    if(m_Ser->HasError())
    {
      RDCERR("Problem serialising file");
      return E_NOTIMPL;
    }

    int ctx = m_Ser->PushContext(NULL, NULL, 1, false);

    if(ctx != THUMBNAIL_DATA)
    {
      return E_NOTIMPL;
    }

    bool HasThumbnail = false;
    m_Ser->Serialise(NULL, HasThumbnail);

    if(!HasThumbnail)
    {
      return E_NOTIMPL;
    }

    byte *jpgbuf = NULL;
    size_t thumblen = 0;
    uint32_t thumbwidth = 0, thumbheight = 0;
    {
      m_Ser->Serialise("ThumbWidth", thumbwidth);
      m_Ser->Serialise("ThumbHeight", thumbheight);
      m_Ser->SerialiseBuffer("ThumbnailPixels", jpgbuf, thumblen);
    }

    if(jpgbuf == NULL)
    {
      return E_NOTIMPL;
    }

    int w = thumbwidth;
    int h = thumbheight;
    int comp = 3;
    byte *thumbpixels =
        jpgd::decompress_jpeg_image_from_memory(jpgbuf, (int)thumblen, &w, &h, &comp, 3);

    delete[] jpgbuf;

    float aspect = float(thumbwidth) / float(thumbheight);

    BITMAPV5HEADER bi;
    RDCEraseEl(bi);
    bi.bV5Size = sizeof(BITMAPV5HEADER);
    bi.bV5Width = RDCMIN((LONG)cx, (LONG)thumbwidth);
    bi.bV5Height = (LONG)(bi.bV5Width / aspect);
    bi.bV5Planes = 1;
    bi.bV5BitCount = 32;
    bi.bV5Compression = BI_BITFIELDS;
    bi.bV5RedMask = 0x00FF0000;
    bi.bV5GreenMask = 0x0000FF00;
    bi.bV5BlueMask = 0x000000FF;
    bi.bV5AlphaMask = 0xFF000000;

    HDC dc = ::CreateCompatibleDC(0);

    RGBQUAD *pArgb;
    *phbmp = ::CreateDIBSection(dc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&pArgb, NULL, 0);

    float widthf = float(thumbwidth);
    float heightf = float(thumbheight);

    if(*phbmp)
    {
      DWORD *pBits = (DWORD *)pArgb;
      for(int y = 0; y < bi.bV5Height; y++)
      {
        for(int x = 0; x < bi.bV5Width; x++)
        {
          *pBits = 0xff000000;

          byte *srcPixel = NULL;

          float xf = float(x) / float(bi.bV5Width);
          float yf = float(bi.bV5Height - y - 1) / float(bi.bV5Height);

          srcPixel = &thumbpixels[3 * (uint32_t(xf * widthf) + thumbwidth * uint32_t(yf * heightf))];

          *pBits |= (srcPixel[0] << 16);
          *pBits |= (srcPixel[1] << 8);
          *pBits |= (srcPixel[2] << 0);

          pBits++;
        }
      }
    }

    free(thumbpixels);

    DeleteObject(dc);

    *pdwAlpha = WTSAT_ARGB;

    return S_OK;
  }
};

struct RDCThumbnailProviderFactory : public IClassFactory
{
  unsigned int m_iRefcount;

  RDCThumbnailProviderFactory() : m_iRefcount(1), locked(false) {}
  virtual ~RDCThumbnailProviderFactory() {}
  ULONG STDMETHODCALLTYPE AddRef()
  {
    InterlockedIncrement(&m_iRefcount);
    return m_iRefcount;
  }
  ULONG STDMETHODCALLTYPE Release()
  {
    unsigned int ret = InterlockedDecrement(&m_iRefcount);
    if(ret == 0)
      delete this;
    return ret;
  }

  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
  {
    if(riid == __uuidof(IClassFactory))
    {
      *ppvObject = (void *)(IClassFactory *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)this;
      AddRef();
      return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
  {
    if(pUnkOuter != NULL)
    {
      return CLASS_E_NOAGGREGATION;
    }

    if(riid == CLSID_RDCThumbnailProvider)
    {
      *ppvObject = (void *)(new RDCThumbnailProvider());
      return S_OK;
    }
    else if(riid == __uuidof(IThumbnailProvider))
    {
      *ppvObject = (void *)(new RDCThumbnailProvider());
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)(new RDCThumbnailProvider());
      return S_OK;
    }

    *ppvObject = NULL;

    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock)
  {
    locked = (fLock == TRUE);
    return S_OK;
  }

  bool locked;
};

_Check_return_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, LPVOID *ppv)
{
  if(rclsid == CLSID_RDCThumbnailProvider)
  {
    if(ppv)
      *ppv = (LPVOID)(new RDCThumbnailProviderFactory);
    return S_OK;
  }

  if(ppv)
    *ppv = NULL;

  return CLASS_E_CLASSNOTAVAILABLE;
}

STDAPI DllCanUnloadNow()
{
  if(numProviders > 0)
    return S_FALSE;

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

// in this file we define the shell extension that renderdoc sets up to be able to
// display thumbnails of captures in windows explorer. We register as a thumbnail
// provider and either the installer or the UI installs the appropriate registry keys.

#include <thumbcache.h>
#include <windows.h>
#include "3rdparty/stb/stb_image_resize.h"
#include "common/common.h"
#include "core/core.h"
#include "jpeg-compressor/jpgd.h"
#include "serialise/rdcfile.h"

// {5D6BF029-A6BA-417A-8523-120492B1DCE3}
static const GUID CLSID_RDCThumbnailProvider = {0x5d6bf029,
                                                0xa6ba,
                                                0x417a,
                                                {0x85, 0x23, 0x12, 0x4, 0x92, 0xb1, 0xdc, 0xe3}};

unsigned int numProviders = 0;

struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream
{
  unsigned int m_iRefcount;
  bool m_Inited;
  RDCFile m_RDC;

  RDCThumbnailProvider() : m_iRefcount(1), m_Inited(false) { InterlockedIncrement(&numProviders); }
  virtual ~RDCThumbnailProvider() { InterlockedDecrement(&numProviders); }
  ULONG STDMETHODCALLTYPE AddRef()
  {
    InterlockedIncrement(&m_iRefcount);
    return m_iRefcount;
  }
  ULONG STDMETHODCALLTYPE Release()
  {
    unsigned int ret = InterlockedDecrement(&m_iRefcount);
    if(ret == 0)
      delete this;
    return ret;
  }

  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
  {
    if(riid == CLSID_RDCThumbnailProvider)
    {
      *ppvObject = (void *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IThumbnailProvider))
    {
      *ppvObject = (void *)(IThumbnailProvider *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IInitializeWithStream))
    {
      *ppvObject = (void *)(IInitializeWithStream *)this;
      AddRef();
      return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE Initialize(IStream *pstream, DWORD grfMode)
  {
    if(m_Inited)
      return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);

    byte *buf = new byte[2 * 1024 * 1024 + 1];
    ULONG numRead = 0;
    HRESULT hr = pstream->Read(buf, 2 * 1024 * 1024, &numRead);

    if(hr != S_OK && hr != S_FALSE)
    {
      delete[] buf;
      return E_INVALIDARG;
    }

    RDCDEBUG("RDCThumbnailProvider Initialize read %d bytes from file", numRead);

    m_RDC.Open(std::vector<byte>(buf, buf + numRead));

    delete[] buf;

    m_Inited = true;

    return S_OK;
  }

  virtual HRESULT STDMETHODCALLTYPE GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha)
  {
    RDCDEBUG("RDCThumbnailProvider GetThumbnail %d", cx);

    if(!m_Inited)
    {
      RDCERR("Not initialized");
      return E_NOTIMPL;
    }

    if(m_RDC.ErrorCode() != ContainerError::NoError)
    {
      RDCERR("Problem opening file");
      return E_NOTIMPL;
    }

    const RDCThumb &thumb = m_RDC.GetThumbnail();

    const byte *jpgbuf = thumb.pixels;
    size_t thumblen = thumb.len;
    uint32_t thumbwidth = thumb.width, thumbheight = thumb.height;

    if(jpgbuf == NULL)
      return E_NOTIMPL;

    int w = thumbwidth;
    int h = thumbheight;
    int comp = 3;
    byte *thumbpixels =
        jpgd::decompress_jpeg_image_from_memory(jpgbuf, (int)thumblen, &w, &h, &comp, 3);

    float aspect = float(thumbwidth) / float(thumbheight);

    BITMAPV5HEADER bi;
    RDCEraseEl(bi);
    bi.bV5Size = sizeof(BITMAPV5HEADER);
    bi.bV5Width = RDCMIN((LONG)cx, (LONG)thumbwidth);
    bi.bV5Height = (LONG)(bi.bV5Width / aspect);
    bi.bV5Planes = 1;
    bi.bV5BitCount = 32;
    bi.bV5Compression = BI_BITFIELDS;
    bi.bV5RedMask = 0x00FF0000;
    bi.bV5GreenMask = 0x0000FF00;
    bi.bV5BlueMask = 0x000000FF;
    bi.bV5AlphaMask = 0xFF000000;

    if(cx != thumbwidth)
    {
      byte *resizedpixels = (byte *)malloc(3 * bi.bV5Width * bi.bV5Height);

      stbir_resize_uint8_srgb(thumbpixels, thumbwidth, thumbheight, 0, resizedpixels, bi.bV5Width,
                              bi.bV5Height, 0, 3, -1, 0);

      free(thumbpixels);

      thumbpixels = resizedpixels;
    }

    HDC dc = ::CreateCompatibleDC(0);

    RGBQUAD *pArgb;
    *phbmp = ::CreateDIBSection(dc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&pArgb, NULL, 0);

    if(*phbmp)
    {
      DWORD *pBits = (DWORD *)pArgb;
      for(int y = bi.bV5Height - 1; y >= 0; y--)
      {
        for(int x = 0; x < bi.bV5Width; x++)
        {
          byte *srcPixel = &thumbpixels[3 * (x + bi.bV5Width * y)];

          *pBits = 0xff << 24 | (srcPixel[0] << 16) | (srcPixel[1] << 8) | (srcPixel[2] << 0);

          pBits++;
        }
      }
    }

    free(thumbpixels);

    DeleteObject(dc);

    *pdwAlpha = WTSAT_ARGB;

    return S_OK;
  }
};

struct RDCThumbnailProviderFactory : public IClassFactory
{
  unsigned int m_iRefcount;

  RDCThumbnailProviderFactory() : m_iRefcount(1), locked(false) {}
  virtual ~RDCThumbnailProviderFactory() {}
  ULONG STDMETHODCALLTYPE AddRef()
  {
    InterlockedIncrement(&m_iRefcount);
    return m_iRefcount;
  }
  ULONG STDMETHODCALLTYPE Release()
  {
    unsigned int ret = InterlockedDecrement(&m_iRefcount);
    if(ret == 0)
      delete this;
    return ret;
  }

  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
  {
    if(riid == __uuidof(IClassFactory))
    {
      *ppvObject = (void *)(IClassFactory *)this;
      AddRef();
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)this;
      AddRef();
      return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
  {
    if(pUnkOuter != NULL)
    {
      return CLASS_E_NOAGGREGATION;
    }

    if(riid == CLSID_RDCThumbnailProvider)
    {
      *ppvObject = (void *)(new RDCThumbnailProvider());
      return S_OK;
    }
    else if(riid == __uuidof(IThumbnailProvider))
    {
      *ppvObject = (void *)(new RDCThumbnailProvider());
      return S_OK;
    }
    else if(riid == __uuidof(IUnknown))
    {
      *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)(new RDCThumbnailProvider());
      return S_OK;
    }

    *ppvObject = NULL;

    return E_NOINTERFACE;
  }

  virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock)
  {
    locked = (fLock == TRUE);
    return S_OK;
  }

  bool locked;
};

_Check_return_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, LPVOID *ppv)
{
  if(rclsid == CLSID_RDCThumbnailProvider)
  {
    if(ppv)
      *ppv = (LPVOID)(new RDCThumbnailProviderFactory);
    return S_OK;
  }

  if(ppv)
    *ppv = NULL;

  return CLASS_E_CLASSNOTAVAILABLE;
}

STDAPI DllCanUnloadNow()
{
  if(numProviders > 0)
    return S_FALSE;

  return S_OK;
}
<|endoftext|>


<commit_before>// This file is part of the dune-pymor project:
//   https://github.com/pyMor/dune-pymor
// Copyright Holders: Felix Albrecht, Stephan Rave
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH
#define DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH

#include <utility>
#include <vector>
#include <string>

#include <dune/common/float_cmp.hh>

namespace Dune {
namespace Pymor {
namespace LA {

class VectorInterface
{
public:

  virtual ~VectorInterface() {}

  /**
   * \brief   A unique (per class, not per instance) identifier.
   * \return
   */
  virtual std::string type() const = 0;

  /**
   * \brief   A list of types which are compatible.
   * \return  A list of types which are compatible.
   */
  virtual std::vector< std::string > compatibleTypes() const = 0;

  /**
   * \brief   The dimension of the vector.
   * \return  The dimension of the vector.
   */
  virtual int dim() const = 0;

  /**
   * \brief   Check vectors for equality.
   *          Equality of two vectors is defined as in Dune::FloatCmp componentwise.
   * \param   other   A vector of same dimension to compare with.
   * \param   epsilon See Dune::FloatCmp.
   * \return          Truth value of the comparison.
   */
  virtual bool almost_equal(const VectorInterface* other,
                            const double epsilon = Dune::FloatCmp::DefaultEpsilon< double >::value()) const = 0;

  /**
   * \brief BLAS SCAL operation (in-place sclar multiplication).
   * \param alpha The scalar coefficient with which the vector is multiplied.
   */
  virtual void scal(const double alpha) = 0;

  /**
   * \brief BLAS AXPY operation.
   * \param alpha The scalar coefficient with which the vector is multiplied
   * \param x     Vector that is to be added.
   */
  virtual void axpy(const double alpha, const VectorInterface* x) = 0;

  /**
   * \brief   Computes the scalar products between two vectors.
   * \param   other The second factor.
   * \return        The scalar product.
   */
  virtual double dot(const VectorInterface* other) const = 0;

  /**
   * \brief   The l1-norm of the vector.
   * \return  The l1-norm of the vector.
   */
  virtual double l1_norm() const = 0;

  /**
   * \brief   The l2-norm of the vector.
   * \return  The l2-norm of the vector.
   */
  virtual double l2_norm() const = 0;

  /**
   * \brief   The l-infintiy-norm of the vector.
   * \return  The l-infintiy-norm of the vector.
   */
  virtual double sup_norm() const = 0;

  /**
   * \brief Extract components of the vector.
   * \param component_indices Indices of the vector components that are to be returned.
   * \return                  A Dune::DynamicVector `result` such that `result[i]` is the `component_indices[i]`-th
                              component of the vector.
   */
  virtual std::vector< double > components(const std::vector< int >& component_indices) const = 0;

  /**
   * \brief   The maximum absolute value of the vector.
   * \return  A pair< max_ind, max_val >, where max_ind is the index at which the maximum is attained and max_val is the
   *          absolute value.
   */
  virtual std::vector< double > amax() const = 0;

  /**
   * \brief   Adds two vectors.
   * \param   other The right summand.
   * \return        The sum of this and other.
   */
  virtual VectorInterface* add(const VectorInterface* other) const = 0;

  /**
   * \brief Inplace variant of add().
   * \param other The right summand.
   */
  virtual void iadd(const VectorInterface* other) = 0;

  /**
   * \brief   Subtracts two vectors.
   * \param   other The subtrahend.
   * \return        The difference between this and other.
   */
  virtual VectorInterface* sub(const VectorInterface* other) const = 0;

  /**
   * \brief Inplace variant of sub().
   * \param other The subtrahend.
   */
  virtual void isub(const VectorInterface* other) = 0;
}; // class VectorInterface

} // namespace LA
} // namespace Pymor
} // namespace Dune

#endif // DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH
<commit_msg>[la.container.interfaces] add proper exceptions<commit_after>// This file is part of the dune-pymor project:
//   https://github.com/pyMor/dune-pymor
// Copyright Holders: Felix Albrecht, Stephan Rave
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH
#define DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH

#include <utility>
#include <vector>
#include <string>

#include <dune/common/float_cmp.hh>

#include <dune/pymor/common/exceptions.hh>

namespace Dune {
namespace Pymor {
namespace LA {

class VectorInterface
{
public:

  virtual ~VectorInterface() {}

  /**
   * \brief   A unique (per class, not per instance) identifier.
   * \return  A unique (per class, not per instance) identifier.
   */
  virtual std::string type() const = 0;

  /**
   * \brief   A list of types which are compatible.
   * \return  A list of types which are compatible.
   */
  virtual std::vector< std::string > compatibleTypes() const = 0;

  /**
   * \brief   The dimension of the vector.
   * \return  The dimension of the vector.
   */
  virtual int dim() const = 0;

  /**
   * \brief   Check vectors for equality.
   *          Equality of two vectors is defined as in Dune::FloatCmp componentwise.
   * \param   other   A vector of same dimension to compare with.
   * \param   epsilon See Dune::FloatCmp.
   * \return          Truth value of the comparison.
   */
  virtual bool almost_equal(const VectorInterface* other,
                            const double epsilon = Dune::FloatCmp::DefaultEpsilon< double >::value()) const
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief BLAS SCAL operation (in-place sclar multiplication).
   * \param alpha The scalar coefficient with which the vector is multiplied.
   */
  virtual void scal(const double alpha) = 0;

  /**
   * \brief BLAS AXPY operation.
   * \param alpha The scalar coefficient with which the vector is multiplied
   * \param x     Vector that is to be added.
   */
  virtual void axpy(const double alpha, const VectorInterface* x)
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief   Computes the scalar products between two vectors.
   * \param   other The second factor.
   * \return        The scalar product.
   */
  virtual double dot(const VectorInterface* other) const
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief   The l1-norm of the vector.
   * \return  The l1-norm of the vector.
   */
  virtual double l1_norm() const = 0;

  /**
   * \brief   The l2-norm of the vector.
   * \return  The l2-norm of the vector.
   */
  virtual double l2_norm() const = 0;

  /**
   * \brief   The l-infintiy-norm of the vector.
   * \return  The l-infintiy-norm of the vector.
   */
  virtual double sup_norm() const = 0;

  /**
   * \brief Extract components of the vector.
   * \param component_indices Indices of the vector components that are to be returned.
   * \return                  A Dune::DynamicVector `result` such that `result[i]` is the `component_indices[i]`-th
                              component of the vector.
   */
  virtual std::vector< double > components(const std::vector< int >& component_indices) const
    throw (Exception::sizes_do_not_match, Exception::index_out_of_range) = 0;

  /**
   * \brief   The maximum absolute value of the vector.
   * \return  A pair< max_ind, max_val >, where max_ind is the index at which the maximum is attained and max_val is the
   *          absolute value.
   */
  virtual std::vector< double > amax() const = 0;

  /**
   * \brief   Adds two vectors.
   * \param   other The right summand.
   * \return        The sum of this and other.
   */
  virtual VectorInterface* add(const VectorInterface* other) const
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief Inplace variant of add().
   * \param other The right summand.
   */
  virtual void iadd(const VectorInterface* other)
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief   Subtracts two vectors.
   * \param   other The subtrahend.
   * \return        The difference between this and other.
   */
  virtual VectorInterface* sub(const VectorInterface* other) const
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;

  /**
   * \brief Inplace variant of sub().
   * \param other The subtrahend.
   */
  virtual void isub(const VectorInterface* other)
    throw (Exception::not_implemented_for_this_combination, Exception::sizes_do_not_match) = 0;
}; // class VectorInterface

} // namespace LA
} // namespace Pymor
} // namespace Dune

#endif // DUNE_PYMOR_LA_CONTAINER_INTERFACES_HH
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

#include <botan/botan.h>
#include <botan/look_pk.h>
#include <botan/dsa.h>
#include <botan/numthry.h>
using namespace Botan;

bool check(std::map<std::string, std::string>);

int main()
   {
   try {
      LibraryInitializer init("use_engines");

      std::ifstream in("PQGGen.rsp");
      if(!in)
         throw Exception("Can't open response file");

      std::map<std::string, std::string> inputs;

      while(in.good())
         {
         std::string line;
         std::getline(in, line);

         if(line == "" || line[0] == '[' || line[0] == '#')
            continue;

         std::vector<std::string> name_and_val = split_on(line, '=');

         if(name_and_val.size() != 2)
            throw Decoding_Error("Unexpected input: " + line);

         name_and_val[0].erase(name_and_val[0].size()-1);
         name_and_val[1].erase(0, 1);

         std::string name = name_and_val[0], value = name_and_val[1];

         inputs[name] = value;

         if(name == "H")
            {
            bool result = check(inputs);
            std::cout << "." << std::flush;
            if(result == false)
               {
               std::cout << "   Check failed\n";

               std::map<std::string, std::string>::const_iterator i;

               for(i = inputs.begin(); i != inputs.end(); i++)
                  std::cout << i->first << " = " << i->second << "\n";

               std::cout << "\n";
               }

            inputs.clear();
            }
         }
   }
   catch(std::exception& e)
      {
      std::cout << e.what() << std::endl;
      return 1;
      }
   return 0;
   }

bool check(std::map<std::string, std::string> inputs)
   {
   BigInt p("0x"+inputs["P"]),
          q("0x"+inputs["Q"]),
          g("0x"+inputs["G"]),
          h("0x"+inputs["H"]);

   if(h < 1 || h >= p-1) return false;

   u32bit c = to_u32bit(inputs["c"]);

   Pipe pipe(new Hex_Decoder);
   pipe.process_msg(inputs["Seed"]);
   SecureVector<byte> seed = pipe.read_all();

   BigInt our_p, our_q;

   bool found = generate_dsa_primes(our_p, our_q, seed, seed.size(),
                                    p.bits(), 0);

   if(!found) /* bad seed */
      return false;

   if(our_p != p) return false;
   if(our_q != q) return false;

   BigInt our_g = power_mod(h, (p-1)/q, p);

   if(our_g != g) return false;

   return true;
   }
<commit_msg>Create a RNG object, update for new interface for DSA paramater generation<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <memory>

#include <botan/botan.h>
#include <botan/look_pk.h>
#include <botan/dsa.h>
#include <botan/numthry.h>
#include <botan/dl_group.h>
using namespace Botan;

bool check(RandomNumberGenerator& rng,
           std::map<std::string, std::string>);

int main()
   {
   try {
      LibraryInitializer init("use_engines");

      std::auto_ptr<RandomNumberGenerator> rng(
         RandomNumberGenerator::make_rng());

      std::ifstream in("PQGGen.rsp");
      if(!in)
         throw Exception("Can't open response file");

      std::map<std::string, std::string> inputs;

      while(in.good())
         {
         std::string line;
         std::getline(in, line);

         if(line == "" || line[0] == '[' || line[0] == '#')
            continue;

         std::vector<std::string> name_and_val = split_on(line, '=');

         if(name_and_val.size() != 2)
            throw Decoding_Error("Unexpected input: " + line);

         name_and_val[0].erase(name_and_val[0].size()-1);
         name_and_val[1].erase(0, 1);

         std::string name = name_and_val[0], value = name_and_val[1];

         inputs[name] = value;

         if(name == "H")
            {
            bool result = check(*rng, inputs);
            std::cout << "." << std::flush;
            if(result == false)
               {
               std::cout << "   Check failed\n";

               std::map<std::string, std::string>::const_iterator i;

               for(i = inputs.begin(); i != inputs.end(); i++)
                  std::cout << i->first << " = " << i->second << "\n";

               std::cout << "\n";
               }

            inputs.clear();
            }
         }
   }
   catch(std::exception& e)
      {
      std::cout << e.what() << std::endl;
      return 1;
      }
   return 0;
   }

bool check(RandomNumberGenerator& rng,
           std::map<std::string, std::string> inputs)
   {
   BigInt p("0x"+inputs["P"]),
          q("0x"+inputs["Q"]),
          g("0x"+inputs["G"]),
          h("0x"+inputs["H"]);

   if(h < 1 || h >= p-1) return false;

   //u32bit c = to_u32bit(inputs["c"]);

   Pipe pipe(new Hex_Decoder);
   pipe.process_msg(inputs["Seed"]);
   SecureVector<byte> seed = pipe.read_all();

   BigInt our_p, our_q;

   u32bit qbits = (p.bits() <= 1024) ? 160 : 256;

   bool found = DL_Group::generate_dsa_primes(rng, our_p, our_q,
                                              p.bits(), qbits, seed);

   if(!found) /* bad seed */
      return false;

   if(our_p != p) return false;
   if(our_q != q) return false;

   BigInt our_g = power_mod(h, (p-1)/q, p);

   if(our_g != g) return false;

   return true;
   }
<|endoftext|>


<commit_before>#include <GLFW/glfw3.h>

#define LOGURU_IMPLEMENTATION 1
#include "app/EmberApp.h"

int get_log_level();
void test_loguru( int argc, char **argv );

int main( int argc, char **argv )
{
	using namespace ember::app;

	EmberApp *app = new EmberApp();
	app->Initialize();

	test_loguru( argc, argv );

	app->Run();

	delete app;
	app = nullptr;

	return 0;
}

int get_log_level()
{
	return loguru::Verbosity_4;
}

void test_loguru( int argc, char **argv )
{
	bool badness = false;
	int length = 10;
	int a = 5;
	int b = 5;

	LOG_SCOPE_F( INFO, "Will indent all log messages within this scope." );
	LOG_F( INFO, "I'm hungry for some %.3f!", 3.14159 );
	LOG_F( 2, "Will only show if verbosity is 2 or higher" );
	VLOG_F( get_log_level(), "Use vlog for dynamic log level (integer in the range 0-9, inclusive)" );
	LOG_IF_F( ERROR, badness, "Will only show if badness happens" );
	CHECK_GT_F( length, 0 ); // Will print the value of `length` on failure.
	CHECK_EQ_F( a, b, "You can also supply a custom message, like to print something: %d", a + b );
}
<commit_msg>trying out creating & destroying lua.<commit_after>#include <GLFW/glfw3.h>

#define LOGURU_IMPLEMENTATION 1
#include "app/EmberApp.h"

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

int get_log_level();
void test_loguru( int argc, char **argv );

int main( int argc, char **argv )
{
	using namespace ember::app;

	EmberApp *app = new EmberApp();
	app->Initialize();

	test_loguru( argc, argv );

	app->Run();

	delete app;
	app = nullptr;

	lua_State *L = luaL_newstate();
	luaL_openlibs( L );

	int error = 0;
	std::string luaScript( "p = 5\nprint(p)" );

	error = luaL_loadbuffer( L, luaScript.c_str(), luaScript.size(), "line" );
	lua_pcall( L, 0, 0, 0 );

	lua_close( L );

	return 0;
}

int get_log_level()
{
	return loguru::Verbosity_4;
}

void test_loguru( int argc, char **argv )
{
	bool badness = false;
	int length = 10;
	int a = 5;
	int b = 5;

	LOG_SCOPE_F( INFO, "Will indent all log messages within this scope." );
	LOG_F( INFO, "I'm hungry for some %.3f!", 3.14159 );
	LOG_F( 2, "Will only show if verbosity is 2 or higher" );
	VLOG_F( get_log_level(), "Use vlog for dynamic log level (integer in the range 0-9, inclusive)" );
	LOG_IF_F( ERROR, badness, "Will only show if badness happens" );
	CHECK_GT_F( length, 0 ); // Will print the value of `length` on failure.
	CHECK_EQ_F( a, b, "You can also supply a custom message, like to print something: %d", a + b );
}
<|endoftext|>


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

#if HAVE_LLVM < 0x0303
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/Function.h>
#include <llvm/DataLayout.h>
#else
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/DataLayout.h>
#endif

#include <llvm/PassManager.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Threading.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm-c/Target.h>

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace llvm;

namespace {

class LLVMEnsureMultithreaded {
public:
   LLVMEnsureMultithreaded()
   {
      llvm_start_multithreaded();
   }
};

static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;

}

/**
 * Set the shader type we want to compile
 *
 * @param type shader type to set
 */
extern "C" void
radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
{
  Function *Func = unwrap<Function>(F);
  int Idx = AttributeSet::FunctionIndex;
  AttrBuilder B;
  char Str[2];

  sprintf(Str, "%1d", type);
  B.addAttribute("ShaderType", Str);

  AttributeSet Set = AttributeSet::get(Func->getContext(), Idx, B);
  Func->addAttributes(Idx, Set);
}

/**
 * Compile an LLVM module to machine code.
 *
 * @param bytes This function allocates memory for the byte stream, it is the
 * caller's responsibility to free it.
 */
extern "C" unsigned
radeon_llvm_compile(LLVMModuleRef M, unsigned char ** bytes,
                 unsigned * byte_count, const char * gpu_family,
                 unsigned dump) {

   Triple AMDGPUTriple(sys::getDefaultTargetTriple());

   LLVMInitializeR600TargetInfo();
   LLVMInitializeR600Target();
   LLVMInitializeR600TargetMC();
   LLVMInitializeR600AsmPrinter();

   std::string err;
   const Target * AMDGPUTarget = TargetRegistry::lookupTarget("r600", err);
   if(!AMDGPUTarget) {
      fprintf(stderr, "Can't find target: %s\n", err.c_str());
      return 1;
   }

   Triple::ArchType Arch = Triple::getArchTypeForLLVMName("r600");
   if (Arch == Triple::UnknownArch) {
      fprintf(stderr, "Unknown Arch\n");
   }
   AMDGPUTriple.setArch(Arch);

   Module * mod = unwrap(M);
   std::string FS;
   TargetOptions TO;

   if (dump) {
      mod->dump();
      FS += "+DumpCode";
   }

   std::auto_ptr<TargetMachine> tm(AMDGPUTarget->createTargetMachine(
                     AMDGPUTriple.getTriple(), gpu_family, FS,
                     TO, Reloc::Default, CodeModel::Default,
                     CodeGenOpt::Default
                     ));
   TargetMachine &AMDGPUTargetMachine = *tm.get();
   PassManager PM;
   PM.add(new DataLayout(*AMDGPUTargetMachine.getDataLayout()));
   PM.add(createPromoteMemoryToRegisterPass());
   AMDGPUTargetMachine.setAsmVerbosityDefault(true);

   std::string CodeString;
   raw_string_ostream oStream(CodeString);
   formatted_raw_ostream out(oStream);

   /* Optional extra paramater true / false to disable verify */
   if (AMDGPUTargetMachine.addPassesToEmitFile(PM, out, TargetMachine::CGFT_ObjectFile,
                                               true)){
      fprintf(stderr, "AddingPasses failed.\n");
      return 1;
   }
   PM.run(*mod);

   out.flush();
   std::string &data = oStream.str();

   *bytes = (unsigned char*)malloc(data.length() * sizeof(unsigned char));
   memcpy(*bytes, data.c_str(), data.length() * sizeof(unsigned char));
   *byte_count = data.length();

   return 0;
}
<commit_msg>radeon/llvm: remove uneeded inclusion<commit_after>/*
 * Copyright 2011 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Authors: Tom Stellard <thomas.stellard@amd.com>
 *
 */
#include "radeon_llvm_emit.h"

#if HAVE_LLVM < 0x0303
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/Function.h>
#include <llvm/DataLayout.h>
#else
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/DataLayout.h>
#endif

#include <llvm/PassManager.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Threading.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm-c/Target.h>

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace llvm;

namespace {

class LLVMEnsureMultithreaded {
public:
   LLVMEnsureMultithreaded()
   {
      llvm_start_multithreaded();
   }
};

static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;

}

/**
 * Set the shader type we want to compile
 *
 * @param type shader type to set
 */
extern "C" void
radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
{
  Function *Func = unwrap<Function>(F);
  int Idx = AttributeSet::FunctionIndex;
  AttrBuilder B;
  char Str[2];

  sprintf(Str, "%1d", type);
  B.addAttribute("ShaderType", Str);

  AttributeSet Set = AttributeSet::get(Func->getContext(), Idx, B);
  Func->addAttributes(Idx, Set);
}

/**
 * Compile an LLVM module to machine code.
 *
 * @param bytes This function allocates memory for the byte stream, it is the
 * caller's responsibility to free it.
 */
extern "C" unsigned
radeon_llvm_compile(LLVMModuleRef M, unsigned char ** bytes,
                 unsigned * byte_count, const char * gpu_family,
                 unsigned dump) {

   Triple AMDGPUTriple(sys::getDefaultTargetTriple());

   LLVMInitializeR600TargetInfo();
   LLVMInitializeR600Target();
   LLVMInitializeR600TargetMC();
   LLVMInitializeR600AsmPrinter();

   std::string err;
   const Target * AMDGPUTarget = TargetRegistry::lookupTarget("r600", err);
   if(!AMDGPUTarget) {
      fprintf(stderr, "Can't find target: %s\n", err.c_str());
      return 1;
   }

   Triple::ArchType Arch = Triple::getArchTypeForLLVMName("r600");
   if (Arch == Triple::UnknownArch) {
      fprintf(stderr, "Unknown Arch\n");
   }
   AMDGPUTriple.setArch(Arch);

   Module * mod = unwrap(M);
   std::string FS;
   TargetOptions TO;

   if (dump) {
      mod->dump();
      FS += "+DumpCode";
   }

   std::auto_ptr<TargetMachine> tm(AMDGPUTarget->createTargetMachine(
                     AMDGPUTriple.getTriple(), gpu_family, FS,
                     TO, Reloc::Default, CodeModel::Default,
                     CodeGenOpt::Default
                     ));
   TargetMachine &AMDGPUTargetMachine = *tm.get();
   PassManager PM;
   PM.add(new DataLayout(*AMDGPUTargetMachine.getDataLayout()));
   PM.add(createPromoteMemoryToRegisterPass());
   AMDGPUTargetMachine.setAsmVerbosityDefault(true);

   std::string CodeString;
   raw_string_ostream oStream(CodeString);
   formatted_raw_ostream out(oStream);

   /* Optional extra paramater true / false to disable verify */
   if (AMDGPUTargetMachine.addPassesToEmitFile(PM, out, TargetMachine::CGFT_ObjectFile,
                                               true)){
      fprintf(stderr, "AddingPasses failed.\n");
      return 1;
   }
   PM.run(*mod);

   out.flush();
   std::string &data = oStream.str();

   *bytes = (unsigned char*)malloc(data.length() * sizeof(unsigned char));
   memcpy(*bytes, data.c_str(), data.length() * sizeof(unsigned char));
   *byte_count = data.length();

   return 0;
}
<|endoftext|>


<commit_before>#include "ClusterTransport.h"

void ClusterTransport::Init(Endpoint& endpoint_)
{
    endpoint = endpoint_;
    server.Init(endpoint.GetPort());
    server.SetTransport(this);
    awaitingNodeID = true;
}

void ClusterTransport::SetSelfNodeID(uint64_t nodeID_)
{
    nodeID = nodeID_;
    awaitingNodeID = false;
    ReconnectAll(); // so we establish "regular" connections with the nodeID
}

bool ClusterTransport::IsAwaitingNodeID()
{
    return awaitingNodeID;
}

uint64_t ClusterTransport::GetSelfNodeID()
{
    return nodeID;
}

Endpoint& ClusterTransport::GetSelfEndpoint()
{
    return endpoint;
}

void ClusterTransport::AddNode(uint64_t nodeID, Endpoint& endpoint)
{
    ClusterConnection* conn;

    if (nodeID < this->nodeID)
        return;

    conn = GetConnection(nodeID);
    if (conn != NULL)
        return;

    if (nodeID == this->nodeID)
        Log_Trace("connecting to self");

    conn = new ClusterConnection;
    conn->SetTransport(this);
    conn->SetNodeID(nodeID);
    conn->SetEndpoint(endpoint);
    conn->Connect();
}

bool ClusterTransport::SetConnectionNodeID(Endpoint& endpoint, uint64_t nodeID)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetEndpoint() == endpoint)
        {
            assert(it->GetProgress() == ClusterConnection::AWAITING_NODEID);
            it->SetNodeID(nodeID);
            it->SetProgress(ClusterConnection::READY);
            return true;
        }
    }

    return false;
}

void ClusterTransport::SendMessage(uint64_t nodeID, Buffer& prefix, Message& msg)
{
    ClusterConnection*  conn;

    conn = GetConnection(nodeID);

    if (!conn)
    {
        Log_Trace("no connection to nodeID %" PRIu64, nodeID);
        return;
    }

    if (conn->GetProgress() != ClusterConnection::READY)
    {
        Log_Trace("connection to %" PRIu64 " has progress: %d", nodeID, conn->GetProgress());
        return;
    }

    msg.Write(msgBuffer);
    conn->Write(prefix, msgBuffer);
}

void ClusterTransport::SendPriorityMessage(uint64_t nodeID, Buffer& prefix, Message& msg)
{
    ClusterConnection*  conn;

    conn = GetConnection(nodeID);

    if (!conn)
    {
        Log_Trace("no connection to nodeID %" PRIu64, nodeID);
        return;
    }

    if (conn->GetProgress() != ClusterConnection::READY)
    {
        Log_Trace("connection to %" PRIu64 " has progress: %d", nodeID, conn->GetProgress());
        return;
    }

    msg.Write(msgBuffer);
    conn->WritePriority(prefix, msgBuffer);
}

void ClusterTransport::DropConnection(uint64_t nodeID)
{
    ClusterConnection* conn;

    conn = GetConnection(nodeID);

    if (!conn)
        return;

    DeleteConnection(conn);
}

void ClusterTransport::DropConnection(Endpoint endpoint)
{
    ClusterConnection* conn;

    conn = GetConnection(endpoint);

    if (!conn)
        return;

    DeleteConnection(conn);
}

bool ClusterTransport::GetNextWaiting(Endpoint& endpoint)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetProgress() == ClusterConnection::AWAITING_NODEID)
        {
            endpoint = it->GetEndpoint();
            return true;
        }
    }

    return false;
}

void ClusterTransport::AddConnection(ClusterConnection* conn)
{
    conns.Append(conn);
}

ClusterConnection* ClusterTransport::GetConnection(uint64_t nodeID)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetNodeID() == nodeID && it->GetProgress() != ClusterConnection::AWAITING_NODEID)
            return it;
    }

    return NULL;
}

ClusterConnection* ClusterTransport::GetConnection(Endpoint& endpoint)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetEndpoint() == endpoint)
            return it;
    }

    return NULL;
}

void ClusterTransport::DeleteConnection(ClusterConnection* conn)
{
    conn->Close();

    if (conn->next != conn)
        conns.Remove(conn);

    delete conn;
}

void ClusterTransport::ReconnectAll()
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        it->Close();
        it->Connect();
    }
}
<commit_msg>Fixed nodeID issue.<commit_after>#include "ClusterTransport.h"

void ClusterTransport::Init(Endpoint& endpoint_)
{
    endpoint = endpoint_;
    server.Init(endpoint.GetPort());
    server.SetTransport(this);
    awaitingNodeID = true;
}

void ClusterTransport::SetSelfNodeID(uint64_t nodeID_)
{
    nodeID = nodeID_;
    awaitingNodeID = false;
    ReconnectAll(); // so we establish "regular" connections with the nodeID
}

bool ClusterTransport::IsAwaitingNodeID()
{
    return awaitingNodeID;
}

uint64_t ClusterTransport::GetSelfNodeID()
{
    return nodeID;
}

Endpoint& ClusterTransport::GetSelfEndpoint()
{
    return endpoint;
}

void ClusterTransport::AddNode(uint64_t nodeID, Endpoint& endpoint)
{
    ClusterConnection* conn;

    if (nodeID > this->nodeID)
        return;

    conn = GetConnection(nodeID);
    if (conn != NULL)
        return;

    if (nodeID == this->nodeID)
        Log_Trace("connecting to self");

    conn = new ClusterConnection;
    conn->SetTransport(this);
    conn->SetNodeID(nodeID);
    conn->SetEndpoint(endpoint);
    conn->Connect();
}

bool ClusterTransport::SetConnectionNodeID(Endpoint& endpoint, uint64_t nodeID)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetEndpoint() == endpoint)
        {
            assert(it->GetProgress() == ClusterConnection::AWAITING_NODEID);
            it->SetNodeID(nodeID);
            it->SetProgress(ClusterConnection::READY);
            return true;
        }
    }

    return false;
}

void ClusterTransport::SendMessage(uint64_t nodeID, Buffer& prefix, Message& msg)
{
    ClusterConnection*  conn;

    conn = GetConnection(nodeID);

    if (!conn)
    {
        Log_Trace("no connection to nodeID %" PRIu64, nodeID);
        return;
    }

    if (conn->GetProgress() != ClusterConnection::READY)
    {
        Log_Trace("connection to %" PRIu64 " has progress: %d", nodeID, conn->GetProgress());
        return;
    }

    msg.Write(msgBuffer);
    conn->Write(prefix, msgBuffer);
}

void ClusterTransport::SendPriorityMessage(uint64_t nodeID, Buffer& prefix, Message& msg)
{
    ClusterConnection*  conn;

    conn = GetConnection(nodeID);

    if (!conn)
    {
        Log_Trace("no connection to nodeID %" PRIu64, nodeID);
        return;
    }

    if (conn->GetProgress() != ClusterConnection::READY)
    {
        Log_Trace("connection to %" PRIu64 " has progress: %d", nodeID, conn->GetProgress());
        return;
    }

    msg.Write(msgBuffer);
    conn->WritePriority(prefix, msgBuffer);
}

void ClusterTransport::DropConnection(uint64_t nodeID)
{
    ClusterConnection* conn;

    conn = GetConnection(nodeID);

    if (!conn)
        return;

    DeleteConnection(conn);
}

void ClusterTransport::DropConnection(Endpoint endpoint)
{
    ClusterConnection* conn;

    conn = GetConnection(endpoint);

    if (!conn)
        return;

    DeleteConnection(conn);
}

bool ClusterTransport::GetNextWaiting(Endpoint& endpoint)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetProgress() == ClusterConnection::AWAITING_NODEID)
        {
            endpoint = it->GetEndpoint();
            return true;
        }
    }

    return false;
}

void ClusterTransport::AddConnection(ClusterConnection* conn)
{
    conns.Append(conn);
}

ClusterConnection* ClusterTransport::GetConnection(uint64_t nodeID)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetNodeID() == nodeID && it->GetProgress() != ClusterConnection::AWAITING_NODEID)
            return it;
    }

    return NULL;
}

ClusterConnection* ClusterTransport::GetConnection(Endpoint& endpoint)
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        if (it->GetEndpoint() == endpoint)
            return it;
    }

    return NULL;
}

void ClusterTransport::DeleteConnection(ClusterConnection* conn)
{
    conn->Close();

    if (conn->next != conn)
        conns.Remove(conn);

    delete conn;
}

void ClusterTransport::ReconnectAll()
{
    ClusterConnection* it;

    for (it = conns.First(); it != NULL; it = conns.Next(it))
    {
        it->Close();
        it->Connect();
    }
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2013 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/elem_cutter.h"
#include "libmesh/elem.h"
#include "libmesh/serial_mesh.h"
#include "libmesh/mesh_triangle_interface.h"
#include "libmesh/mesh_tetgen_interface.h"

// C++ includes

namespace
{
  unsigned int cut_cntr;
}
namespace libMesh
{

  // ------------------------------------------------------------
  // ElemCutter implementation
  ElemCutter::ElemCutter()
  {
    _inside_mesh_2D.reset  (new SerialMesh); /**/ _triangle_inside.reset  (new TriangleInterface (*_inside_mesh_2D));
    _outside_mesh_2D.reset (new SerialMesh); /**/ _triangle_outside.reset (new TriangleInterface (*_outside_mesh_2D));

    _inside_mesh_3D.reset  (new SerialMesh); /**/ _tetgen_inside.reset  (new TetGenMeshInterface (*_inside_mesh_3D));
    _outside_mesh_3D.reset (new SerialMesh); /**/ _tetgen_outside.reset (new TetGenMeshInterface (*_outside_mesh_3D));

    cut_cntr = 0;
  }

  ElemCutter::~ElemCutter()
  {}

  void ElemCutter::operator()(const Elem &elem,
			      const std::vector<Real> &vertex_distance_func)

  {
    libmesh_assert_equal_to (vertex_distance_func.size(), elem.n_vertices());

    _inside_elem.clear();
    _outside_elem.clear();

    // check for quick return?
    {
      Real
	nmin = vertex_distance_func.front(),
	nmax = nmin;

      for (std::vector<Real>::const_iterator it=vertex_distance_func.begin();
	   it!=vertex_distance_func.end(); ++it)
	{
	  nmin = std::min (nmin, *it);
	  nmax = std::max (nmax, *it);
	}

      // completely outside?
      if (nmin >= 0.)
	{
	  //std::cout << "element completely outside\n";
	  _outside_elem.push_back(&elem);
	  return;
	}

      // completely inside?
      else if (nmax <= 0.)
	{
	  //std::cout << "element completely inside\n";
	  _inside_elem.push_back(&elem);
	  return;
	}

      libmesh_assert_greater (nmax, 0.);
      libmesh_assert_less    (nmin, 0.);
    }

    // we now know we are in a cut element, find the intersecting points.
    this->find_intersection_points (elem, vertex_distance_func);

    // and then dispatch the proper method
    switch (elem.dim())
      {
      case 1: this->cut_1D(); break;
      case 2: this->cut_2D(elem, vertex_distance_func); break;
      case 3: this->cut_3D(); break;
      default: libmesh_error();
      }
  }

  void ElemCutter::find_intersection_points(const Elem &elem,
					    const std::vector<Real> &vertex_distance_func)
  {
    _intersection_pts.clear();

    for (unsigned int e=0; e<elem.n_edges(); e++)
      {
	AutoPtr<Elem> edge (elem.build_edge(e));

	// find the element nodes el0, el1 that map
	unsigned int
	  el0 = elem.get_node_index(edge->get_node(0)),
	  el1 = elem.get_node_index(edge->get_node(1));

	libmesh_assert (elem.is_vertex(el0));
	libmesh_assert (elem.is_vertex(el1));
	libmesh_assert_less (el0, vertex_distance_func.size());
	libmesh_assert_less (el1, vertex_distance_func.size());

	const Real
	  d0 = vertex_distance_func[el0],
	  d1 = vertex_distance_func[el1];

	// if this egde has a 0 crossing
	if (d0*d1 < 0.)
	  {
	    libmesh_assert_not_equal_to (d0, d1);

	    // then find d_star in [0,1], the
	    // distance from el0 to el1 where the 0 lives.
	    const Real d_star = d0 / (d0 - d1);

	    // Prevent adding nodes trivially close to existing
	    // nodes.
	    const Real endpoint_tol = 0.01;

	    if ( (d_star > endpoint_tol) &&
		 (d_star < (1.-endpoint_tol)) )
	      {
		const Point x_star = (edge->point(0)*(1.-d_star) +
				      edge->point(1)*d_star);

		std::cout << "adding cut point (d_star, x_star) = "
			  << d_star << " , " << x_star << std::endl;

		_intersection_pts.push_back (x_star);
	      }
	  }
      }
  }

  void ElemCutter::cut_1D ()
  {
    libmesh_not_implemented();
  }

  void ElemCutter::cut_2D (const Elem &elem,
			   const std::vector<Real> &vertex_distance_func)
  {
    //libmesh_not_implemented();
    std::cout << "Inside cut element!\n";

#ifdef LIBMESH_HAVE_TRIANGLE

    libmesh_assert (_inside_mesh_2D.get() != NULL);

    _inside_mesh_2D->clear();
    _outside_mesh_2D->clear();

    for (unsigned int v=0; v<elem.n_vertices(); v++)
      {
	if (vertex_distance_func[v] >= 0.)
	  _outside_mesh_2D->add_point (elem.point(v));

	if (vertex_distance_func[v] <= 0.)
	  _inside_mesh_2D->add_point (elem.point(v));
      }

    for (std::vector<Point>::const_iterator it=_intersection_pts.begin();
	 it != _intersection_pts.end(); ++it)
      {
	_inside_mesh_2D->add_point(*it);
	_outside_mesh_2D->add_point(*it);
      }

    // Customize the variables for the triangulation
    _triangle_inside->desired_area()  = 100.;
    _triangle_outside->desired_area() = 100.;

    // Turn on/off Laplacian mesh smoothing after generation.
    // By default this is on.
    _triangle_inside->smooth_after_generating()  = false;
    _triangle_outside->smooth_after_generating() = false;

    // Triangulate!
    _triangle_inside->triangulate();
    _triangle_outside->triangulate();

    std::ostringstream name;

    name << "cut_face_"
	 << cut_cntr++
	 << ".dat";
    _inside_mesh_2D->write  ("in_"  + name.str());
    _outside_mesh_2D->write ("out_" + name.str());
#endif
  }

  void ElemCutter::cut_3D ()
  {
    libmesh_not_implemented();
  }

} // namespace libMesh
<commit_msg>5 degree minimum angle, vs. default of 20 - results in fewer triangles.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2013 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/elem_cutter.h"
#include "libmesh/elem.h"
#include "libmesh/serial_mesh.h"
#include "libmesh/mesh_triangle_interface.h"
#include "libmesh/mesh_tetgen_interface.h"

// C++ includes

namespace
{
  unsigned int cut_cntr;
}
namespace libMesh
{

  // ------------------------------------------------------------
  // ElemCutter implementation
  ElemCutter::ElemCutter()
  {
    _inside_mesh_2D.reset  (new SerialMesh); /**/ _triangle_inside.reset  (new TriangleInterface (*_inside_mesh_2D));
    _outside_mesh_2D.reset (new SerialMesh); /**/ _triangle_outside.reset (new TriangleInterface (*_outside_mesh_2D));

    _inside_mesh_3D.reset  (new SerialMesh); /**/ _tetgen_inside.reset  (new TetGenMeshInterface (*_inside_mesh_3D));
    _outside_mesh_3D.reset (new SerialMesh); /**/ _tetgen_outside.reset (new TetGenMeshInterface (*_outside_mesh_3D));

    cut_cntr = 0;
  }

  ElemCutter::~ElemCutter()
  {}

  void ElemCutter::operator()(const Elem &elem,
			      const std::vector<Real> &vertex_distance_func)

  {
    libmesh_assert_equal_to (vertex_distance_func.size(), elem.n_vertices());

    _inside_elem.clear();
    _outside_elem.clear();

    // check for quick return?
    {
      Real
	nmin = vertex_distance_func.front(),
	nmax = nmin;

      for (std::vector<Real>::const_iterator it=vertex_distance_func.begin();
	   it!=vertex_distance_func.end(); ++it)
	{
	  nmin = std::min (nmin, *it);
	  nmax = std::max (nmax, *it);
	}

      // completely outside?
      if (nmin >= 0.)
	{
	  //std::cout << "element completely outside\n";
	  _outside_elem.push_back(&elem);
	  return;
	}

      // completely inside?
      else if (nmax <= 0.)
	{
	  //std::cout << "element completely inside\n";
	  _inside_elem.push_back(&elem);
	  return;
	}

      libmesh_assert_greater (nmax, 0.);
      libmesh_assert_less    (nmin, 0.);
    }

    // we now know we are in a cut element, find the intersecting points.
    this->find_intersection_points (elem, vertex_distance_func);

    // and then dispatch the proper method
    switch (elem.dim())
      {
      case 1: this->cut_1D(); break;
      case 2: this->cut_2D(elem, vertex_distance_func); break;
      case 3: this->cut_3D(); break;
      default: libmesh_error();
      }
  }

  void ElemCutter::find_intersection_points(const Elem &elem,
					    const std::vector<Real> &vertex_distance_func)
  {
    _intersection_pts.clear();

    for (unsigned int e=0; e<elem.n_edges(); e++)
      {
	AutoPtr<Elem> edge (elem.build_edge(e));

	// find the element nodes el0, el1 that map
	unsigned int
	  el0 = elem.get_node_index(edge->get_node(0)),
	  el1 = elem.get_node_index(edge->get_node(1));

	libmesh_assert (elem.is_vertex(el0));
	libmesh_assert (elem.is_vertex(el1));
	libmesh_assert_less (el0, vertex_distance_func.size());
	libmesh_assert_less (el1, vertex_distance_func.size());

	const Real
	  d0 = vertex_distance_func[el0],
	  d1 = vertex_distance_func[el1];

	// if this egde has a 0 crossing
	if (d0*d1 < 0.)
	  {
	    libmesh_assert_not_equal_to (d0, d1);

	    // then find d_star in [0,1], the
	    // distance from el0 to el1 where the 0 lives.
	    const Real d_star = d0 / (d0 - d1);

	    // Prevent adding nodes trivially close to existing
	    // nodes.
	    const Real endpoint_tol = 0.01;

	    if ( (d_star > endpoint_tol) &&
		 (d_star < (1.-endpoint_tol)) )
	      {
		const Point x_star = (edge->point(0)*(1.-d_star) +
				      edge->point(1)*d_star);

		std::cout << "adding cut point (d_star, x_star) = "
			  << d_star << " , " << x_star << std::endl;

		_intersection_pts.push_back (x_star);
	      }
	  }
      }
  }

  void ElemCutter::cut_1D ()
  {
    libmesh_not_implemented();
  }

  void ElemCutter::cut_2D (const Elem &elem,
			   const std::vector<Real> &vertex_distance_func)
  {
    //libmesh_not_implemented();
    std::cout << "Inside cut element!\n";

#ifdef LIBMESH_HAVE_TRIANGLE

    libmesh_assert (_inside_mesh_2D.get() != NULL);

    _inside_mesh_2D->clear();
    _outside_mesh_2D->clear();

    for (unsigned int v=0; v<elem.n_vertices(); v++)
      {
	if (vertex_distance_func[v] >= 0.)
	  _outside_mesh_2D->add_point (elem.point(v));

	if (vertex_distance_func[v] <= 0.)
	  _inside_mesh_2D->add_point (elem.point(v));
      }

    for (std::vector<Point>::const_iterator it=_intersection_pts.begin();
	 it != _intersection_pts.end(); ++it)
      {
	_inside_mesh_2D->add_point(*it);
	_outside_mesh_2D->add_point(*it);
      }

    // Customize the variables for the triangulation
    // we will be cutting reference cell, and want as few triangles
    // as possible, so jack this up larger than the area we will be
    // triangulating so we are governed only by accurately defining
    // the boundaries.
    _triangle_inside->desired_area()  = 100.;
    _triangle_outside->desired_area() = 100.;

    // allow for small angles
    _triangle_inside->minimum_angle()  = 5.;
    _triangle_outside->minimum_angle() = 5.;

    // Turn off Laplacian mesh smoothing after generation.
    _triangle_inside->smooth_after_generating()  = false;
    _triangle_outside->smooth_after_generating() = false;

    // Triangulate!
    _triangle_inside->triangulate();
    _triangle_outside->triangulate();

    std::ostringstream name;

    name << "cut_face_"
	 << cut_cntr++
	 << ".dat";
    _inside_mesh_2D->write  ("in_"  + name.str());
    _outside_mesh_2D->write ("out_" + name.str());
#endif
  }

  void ElemCutter::cut_3D ()
  {
    libmesh_not_implemented();
  }

} // namespace libMesh
<|endoftext|>


<commit_before>/*
* Copyright 2008 Free Software Foundation, Inc.
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "Sockets.h"
#include "Threads.h"
#include <stdio.h>
#include <stdlib.h>

static const int gNumToSend = 10;

void *testReaderIP(void *)
{
	UDPSocket readSocket("127.0.0.1", 5934, "localhost", 5061);
	readSocket.nonblocking();
	int rc = 0;
	while (rc<gNumToSend) {
		char buf[MAX_UDP_LENGTH];
		int count = readSocket.read(buf, MAX_UDP_LENGTH);
		if (count>0) {
			COUT("read: " << buf);
			rc++;
		} else {
			sleep(2);
		}
	}
	return NULL;
}

void *testReaderUnix(void *)
{
	UDDSocket readSocket("testDestination");
	readSocket.nonblocking();
	int rc = 0;
	while (rc<gNumToSend) {
		char buf[MAX_UDP_LENGTH];
		int count = readSocket.read(buf, MAX_UDP_LENGTH);
		if (count>0) {
			COUT("read: " << buf);
			rc++;
		} else {
			sleep(2);
		}
	}
	return NULL;
}

int main(int argc, char * argv[] )
{

  Thread readerThreadIP;
  readerThreadIP.start(testReaderIP,NULL);
  Thread readerThreadUnix;
  readerThreadUnix.start(testReaderUnix,NULL);

  UDPSocket socket1("127.0.0.1", 5061, "127.0.0.1", 5934);
  UDDSocket socket1U("testSource","testDestination");

  COUT("socket1: " << socket1.port());

  // give the readers time to open
  sleep(1);

  for (int i=0; i<gNumToSend; i++) {
    socket1.write("Hello IP land");
	socket1U.write("Hello Unix domain");
	sleep(1);
  }

  readerThreadIP.join();
  readerThreadUnix.join();
}

// vim: ts=4 sw=4
<commit_msg>SocketsTest: Fix printing of non-nul-terminated string<commit_after>/*
* Copyright 2008 Free Software Foundation, Inc.
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "Sockets.h"
#include "Threads.h"
#include <stdio.h>
#include <stdlib.h>

static const int gNumToSend = 10;

void *testReaderIP(void *)
{
	UDPSocket readSocket("127.0.0.1", 5934, "localhost", 5061);
	readSocket.nonblocking();
	int rc = 0;
	while (rc<gNumToSend) {
		char buf[MAX_UDP_LENGTH];
		int count = readSocket.read(buf, MAX_UDP_LENGTH);
		if (count>0) {
			COUT("read: " << buf);
			rc++;
		} else {
			sleep(2);
		}
	}
	return NULL;
}

void *testReaderUnix(void *)
{
	UDDSocket readSocket("testDestination");
	readSocket.nonblocking();
	int rc = 0;
	while (rc<gNumToSend) {
		char buf[MAX_UDP_LENGTH+1];
		buf[MAX_UDP_LENGTH] =  '\0';
		int count = readSocket.read(buf, MAX_UDP_LENGTH);
		if (count>0) {
			COUT("read: " << buf);
			rc++;
		} else {
			sleep(2);
		}
	}
	return NULL;
}

int main(int argc, char * argv[] )
{

  Thread readerThreadIP;
  readerThreadIP.start(testReaderIP,NULL);
  Thread readerThreadUnix;
  readerThreadUnix.start(testReaderUnix,NULL);

  UDPSocket socket1("127.0.0.1", 5061, "127.0.0.1", 5934);
  UDDSocket socket1U("testSource","testDestination");

  COUT("socket1: " << socket1.port());

  // give the readers time to open
  sleep(1);

  for (int i=0; i<gNumToSend; i++) {
    socket1.write("Hello IP land");
	socket1U.write("Hello Unix domain");
	sleep(1);
  }

  readerThreadIP.join();
  readerThreadUnix.join();
}

// vim: ts=4 sw=4
<|endoftext|>


<commit_before><commit_msg>Working on frustum stuff<commit_after><|endoftext|>


<commit_before>/**
 * \file
 * \brief forceContextSwitch() definition
 *
 * \author Copyright (C) 2014-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/internal/scheduler/forceContextSwitch.hpp"

#include "distortos/architecture/requestContextSwitch.hpp"

#include "distortos/internal/synchronization/InterruptUnmaskingLock.hpp"

namespace distortos
{

namespace internal
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

void forceContextSwitch()
{
	architecture::requestContextSwitch();
	InterruptUnmaskingLock interruptUnmaskingLock;
}

}	// namespace internal

}	// namespace distortos
<commit_msg>Constify all InterruptUnmaskingLock objects<commit_after>/**
 * \file
 * \brief forceContextSwitch() definition
 *
 * \author Copyright (C) 2014-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/internal/scheduler/forceContextSwitch.hpp"

#include "distortos/architecture/requestContextSwitch.hpp"

#include "distortos/internal/synchronization/InterruptUnmaskingLock.hpp"

namespace distortos
{

namespace internal
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

void forceContextSwitch()
{
	architecture::requestContextSwitch();
	const InterruptUnmaskingLock interruptUnmaskingLock;
}

}	// namespace internal

}	// namespace distortos
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/

#include "customdraganddrop.h"

#include <QMimeData>
#include <QPoint>
#include <QLabel>

#include <QMouseEvent>
#include <QApplication>
#include <QDebug>
#include <QPainter>

#ifdef Q_OS_WIN
#include <private/qwidget_p.h>
#endif

namespace QmlDesigner {

namespace QmlDesignerItemLibraryDragAndDrop {

void CustomDragAndDropIcon::startDrag()
{
    m_size = m_icon.size();
    m_iconAlpha = 1;
    m_previewAlpha = 0;

    QPoint pos = QCursor::pos();
    QWidget *widget = QApplication::topLevelAt(pos);
    setParent(widget);
    raise();
    show();

    grabMouseSafely();
}

void CustomDragAndDropIcon::grabMouseSafely()
{
#ifdef Q_OS_WIN
    // grabMouse calls SetWindowsHookEx() - this function causes a system-wide
    // freeze if any other app on the system installs a hook and fails to
    // process events.
    QWidgetPrivate *p = qt_widget_private(this);
    p->grabMouseWhileInWindow();
#else
    grabMouse();
#endif
}

void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event)
{
     QPoint globalPos = event->globalPos();
     releaseMouse();
     move(-1000, -1000); //-1000, -1000 is used to hide because hiding causes propblems with the mouse grabber
     QWidget* target = QApplication::widgetAt(globalPos - QPoint(2,2)); //-(2, 2) because:
                                                                        // otherwise we just get this widget

     if (CustomDragAndDrop::isAccepted()) // if the target widget accepted the enter event,
                                          // then create a drop event
         CustomDragAndDrop::drop(target, globalPos);
     CustomDragAndDrop::endCustomDrag();
}

void CustomDragAndDropIcon::mouseMoveEvent(QMouseEvent *event)
{
    QPoint globalPos = event->globalPos();
    QWidget * widget = QApplication::topLevelAt(globalPos); // grap the "current" top level widget
    if (widget) {
        setParent(widget); // set the current top level widget as parent
        QPoint pos = parentWidget()->mapFromGlobal(globalPos);
        if ((pos.y() > 30 && CustomDragAndDrop::isVisible())) // do not allow dragging over the menubar
            move(pos);
        else
            move(-1000, -1000); // no hiding because of mouse grabbing
        resize(m_size);
        show();
        update();
    }
    else {
       move(-1000, -1000); // if no top level widget is found we are out of the main window
    }
    QWidget* target = QApplication::widgetAt(globalPos - QPoint(2,2)); //-(2, 2) because:
                                                                       // otherwise we just get this widget
    if (target != m_oldTarget) {
      if (CustomDragAndDrop::isAccepted())
        CustomDragAndDrop::leave(m_oldTarget, globalPos);  // create DragLeave event if drag enter
                                                           // event was accepted
      bool wasAccepted = CustomDragAndDrop::isAccepted();
      CustomDragAndDrop::enter(target, globalPos);         // create and handle the create enter event
      releaseMouse(); // to set the cursor we have to disable the mouse grabber
      if (CustomDragAndDrop::isAccepted()) { // setting the right cursor and trigger animation
          setCursor(Qt::CrossCursor);
          if (!wasAccepted)
              enter();                      // trigger animation if enter event was accepted
      } else {
          setCursor(Qt::ForbiddenCursor);
          if (wasAccepted)
              leave();                     // trigger animation if we leave a widget that accepted
                                           // the drag enter event
      }
      // enable the mouse grabber again - after the curser is set
      grabMouseSafely();
    } else {
        if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget
                                             // accepted the DragEnter event
            CustomDragAndDrop::move(target, globalPos);
    }
    m_oldTarget = target;
}

void CustomDragAndDropIcon::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    QPainter p(this);
    if  (CustomDragAndDrop::isAccepted()) {
        p.setOpacity(m_previewAlpha);
        p.drawPixmap(0 ,0 , m_size.width(), m_size.height(), m_preview);
        p.setOpacity(m_iconAlpha);
        p.drawPixmap(0, 0, m_size.width(), m_size.height(), m_icon);
    } else {
        p.setOpacity(m_iconAlpha);
        p.drawPixmap(0, 0, m_size.width(), m_size.height(), m_icon);
        p.setOpacity(m_previewAlpha);
        p.drawPixmap(0 ,0 , m_size.width(), m_size.height(), m_preview);
    }
}

void CustomDragAndDropIcon::enter()
{
    connect(&m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(animateDrag(int)));
    m_timeLine.setFrameRange(0, 10);
    m_timeLine.setDuration(10);
    m_timeLine.setLoopCount(1);
    m_timeLine.setCurveShape(QTimeLine::EaseInCurve);
    m_timeLine.start();
    m_size  = m_icon.size();
    m_iconAlpha = 1;
    m_previewAlpha = 0;
}

void CustomDragAndDropIcon::leave()
{
    connect(&m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(animateDrag(int)));
    m_timeLine.setFrameRange(0, 10);
    m_timeLine.setDuration(250);
    m_timeLine.setLoopCount(1);
    m_timeLine.setCurveShape(QTimeLine::EaseInCurve);
    m_timeLine.start();
    m_size  = m_preview.size();
    m_iconAlpha = 0;
    m_previewAlpha = 1;
}

void CustomDragAndDropIcon::animateDrag(int frame)
{
    // interpolation of m_size and alpha values
    if (CustomDragAndDrop::isAccepted()) {
        // small -> big
        m_iconAlpha = 1.0 - qreal(frame) / 10.0;
        m_previewAlpha = qreal(frame) / 10.0;
        int width = qreal(m_preview.width()) * (qreal(frame) / 10.0) + qreal(m_icon.width()) * (1.0 - qreal(frame) / 10.0);
        int height = qreal(m_preview.height()) * (qreal(frame) / 10.0) + qreal(m_icon.height()) * (1 - qreal(frame) / 10.0);
        m_size = QSize(width, height);
    } else {
        // big -> small
        m_previewAlpha = 1.0 - qreal(frame) / 10.0;
        m_iconAlpha = qreal(frame) / 10.0;
        int width = qreal(m_icon.width()) * (qreal(frame) / 10.0) + qreal(m_preview.width()) * (1.0 - qreal(frame) / 10.0);
        int height = qreal(m_icon.height()) * (qreal(frame) / 10.0) + qreal(m_preview.height()) * (1 - qreal(frame) / 10.0);
        m_size = QSize(width, height);
    }
    QPoint p = pos();
    resize(m_size);
    move(p);
    update(); // redrawing needed
}

class CustomDragAndDropGuard { // This guard destroys the singleton in its destructor
public:                   // This should avoid that a memory leak is reported
    ~CustomDragAndDropGuard() {
        if (CustomDragAndDrop::m_instance)
            delete CustomDragAndDrop::m_instance;
    }
};

CustomDragAndDrop* CustomDragAndDrop::m_instance = 0;

CustomDragAndDrop::CustomDragAndDrop() : m_customDragActive(0), m_mimeData(0), m_accepted(false)
{
    m_widget = new CustomDragAndDropIcon(QApplication::topLevelWidgets().first());
    m_widget->move(-1000, 1000);
    m_widget->resize(32, 32);
    m_widget->show();
}

CustomDragAndDrop* CustomDragAndDrop::instance()
{
    static CustomDragAndDropGuard guard; // The destructor destroys the singleton. See above
    if (m_instance == 0)
        m_instance = new CustomDragAndDrop();
    return m_instance;
}

void CustomDragAndDrop::endCustomDrag()
{
    instance()->m_customDragActive = false;
}

void CustomDragAndDrop::startCustomDrag(const QPixmap icon, const QPixmap preview, QMimeData * mimeData)
{
    if (instance()->m_customDragActive) {
        qWarning("CustomDragAndDrop::startCustomDrag drag is active");
        return ;
    }
    instance()->m_customDragActive = true;
    instance()-> m_accepted = false;
    show();
    instance()->m_mimeData = mimeData;
    instance()->m_widget->setIcon(icon);
    instance()->m_widget->setPreview(preview);
    instance()->m_widget->startDrag();
}

bool CustomDragAndDrop::customDragActive()
{
    return instance()->m_customDragActive;
}

bool CustomDragAndDrop::isAccepted()
{
    return instance()->m_accepted;
}

void CustomDragAndDrop::enter(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDragEnterEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
        instance()-> m_accepted = event.isAccepted(); // if the event is accepted we enter the "accepted" state
    } else {
        instance()-> m_accepted = false;
    }
}

void CustomDragAndDrop::leave(QWidget *target, QPoint globalPos)
{
    Q_UNUSED(globalPos)
    if (target) {
        QDragLeaveEvent event;
        QApplication::sendEvent(target, &event);
    } else {
       qWarning() <<  "CustomDragAndDrop::leave leaving invalid target";
    }
}

void CustomDragAndDrop::move(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDragMoveEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
    } else {
        qWarning() <<  "CustomDragAndDrop::move move in invalid target";
    }
}

void CustomDragAndDrop::drop(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDropEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
    } else {
        qWarning() <<  "CustomDragAndDrop::drop dropping in invalid target";
    }
}

bool CustomDragAndDrop::isAnimated()
{
    if (instance()->m_widget)
        return instance()->m_widget->isAnimated();
    return false;
}

} // namespace QmlDesignerItemLibraryDragAndDrop
} // namespave QmlDesigner
<commit_msg>QmlDesigner: fixing compile for Qt 5<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/

#include "customdraganddrop.h"

#include <QMimeData>
#include <QPoint>
#include <QLabel>

#include <QMouseEvent>
#include <QApplication>
#include <QDebug>
#include <QPainter>

#if defined(Q_OS_WIN) && QT_VERSION < 0x050000
#include <private/qwidget_p.h>
#endif

namespace QmlDesigner {

namespace QmlDesignerItemLibraryDragAndDrop {

void CustomDragAndDropIcon::startDrag()
{
    m_size = m_icon.size();
    m_iconAlpha = 1;
    m_previewAlpha = 0;

    QPoint pos = QCursor::pos();
    QWidget *widget = QApplication::topLevelAt(pos);
    setParent(widget);
    raise();
    show();

    grabMouseSafely();
}

void CustomDragAndDropIcon::grabMouseSafely()
{
#if defined(Q_OS_WIN) && QT_VERSION < 0x050000
    // grabMouse calls SetWindowsHookEx() - this function causes a system-wide
    // freeze if any other app on the system installs a hook and fails to
    // process events.
    QWidgetPrivate *p = qt_widget_private(this);
    p->grabMouseWhileInWindow();
#else
    grabMouse();
#endif
}

void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event)
{
     QPoint globalPos = event->globalPos();
     releaseMouse();
     move(-1000, -1000); //-1000, -1000 is used to hide because hiding causes propblems with the mouse grabber
     QWidget* target = QApplication::widgetAt(globalPos - QPoint(2,2)); //-(2, 2) because:
                                                                        // otherwise we just get this widget

     if (CustomDragAndDrop::isAccepted()) // if the target widget accepted the enter event,
                                          // then create a drop event
         CustomDragAndDrop::drop(target, globalPos);
     CustomDragAndDrop::endCustomDrag();
}

void CustomDragAndDropIcon::mouseMoveEvent(QMouseEvent *event)
{
    QPoint globalPos = event->globalPos();
    QWidget * widget = QApplication::topLevelAt(globalPos); // grap the "current" top level widget
    if (widget) {
        setParent(widget); // set the current top level widget as parent
        QPoint pos = parentWidget()->mapFromGlobal(globalPos);
        if ((pos.y() > 30 && CustomDragAndDrop::isVisible())) // do not allow dragging over the menubar
            move(pos);
        else
            move(-1000, -1000); // no hiding because of mouse grabbing
        resize(m_size);
        show();
        update();
    }
    else {
       move(-1000, -1000); // if no top level widget is found we are out of the main window
    }
    QWidget* target = QApplication::widgetAt(globalPos - QPoint(2,2)); //-(2, 2) because:
                                                                       // otherwise we just get this widget
    if (target != m_oldTarget) {
      if (CustomDragAndDrop::isAccepted())
        CustomDragAndDrop::leave(m_oldTarget, globalPos);  // create DragLeave event if drag enter
                                                           // event was accepted
      bool wasAccepted = CustomDragAndDrop::isAccepted();
      CustomDragAndDrop::enter(target, globalPos);         // create and handle the create enter event
      releaseMouse(); // to set the cursor we have to disable the mouse grabber
      if (CustomDragAndDrop::isAccepted()) { // setting the right cursor and trigger animation
          setCursor(Qt::CrossCursor);
          if (!wasAccepted)
              enter();                      // trigger animation if enter event was accepted
      } else {
          setCursor(Qt::ForbiddenCursor);
          if (wasAccepted)
              leave();                     // trigger animation if we leave a widget that accepted
                                           // the drag enter event
      }
      // enable the mouse grabber again - after the curser is set
      grabMouseSafely();
    } else {
        if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget
                                             // accepted the DragEnter event
            CustomDragAndDrop::move(target, globalPos);
    }
    m_oldTarget = target;
}

void CustomDragAndDropIcon::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    QPainter p(this);
    if  (CustomDragAndDrop::isAccepted()) {
        p.setOpacity(m_previewAlpha);
        p.drawPixmap(0 ,0 , m_size.width(), m_size.height(), m_preview);
        p.setOpacity(m_iconAlpha);
        p.drawPixmap(0, 0, m_size.width(), m_size.height(), m_icon);
    } else {
        p.setOpacity(m_iconAlpha);
        p.drawPixmap(0, 0, m_size.width(), m_size.height(), m_icon);
        p.setOpacity(m_previewAlpha);
        p.drawPixmap(0 ,0 , m_size.width(), m_size.height(), m_preview);
    }
}

void CustomDragAndDropIcon::enter()
{
    connect(&m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(animateDrag(int)));
    m_timeLine.setFrameRange(0, 10);
    m_timeLine.setDuration(10);
    m_timeLine.setLoopCount(1);
    m_timeLine.setCurveShape(QTimeLine::EaseInCurve);
    m_timeLine.start();
    m_size  = m_icon.size();
    m_iconAlpha = 1;
    m_previewAlpha = 0;
}

void CustomDragAndDropIcon::leave()
{
    connect(&m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(animateDrag(int)));
    m_timeLine.setFrameRange(0, 10);
    m_timeLine.setDuration(250);
    m_timeLine.setLoopCount(1);
    m_timeLine.setCurveShape(QTimeLine::EaseInCurve);
    m_timeLine.start();
    m_size  = m_preview.size();
    m_iconAlpha = 0;
    m_previewAlpha = 1;
}

void CustomDragAndDropIcon::animateDrag(int frame)
{
    // interpolation of m_size and alpha values
    if (CustomDragAndDrop::isAccepted()) {
        // small -> big
        m_iconAlpha = 1.0 - qreal(frame) / 10.0;
        m_previewAlpha = qreal(frame) / 10.0;
        int width = qreal(m_preview.width()) * (qreal(frame) / 10.0) + qreal(m_icon.width()) * (1.0 - qreal(frame) / 10.0);
        int height = qreal(m_preview.height()) * (qreal(frame) / 10.0) + qreal(m_icon.height()) * (1 - qreal(frame) / 10.0);
        m_size = QSize(width, height);
    } else {
        // big -> small
        m_previewAlpha = 1.0 - qreal(frame) / 10.0;
        m_iconAlpha = qreal(frame) / 10.0;
        int width = qreal(m_icon.width()) * (qreal(frame) / 10.0) + qreal(m_preview.width()) * (1.0 - qreal(frame) / 10.0);
        int height = qreal(m_icon.height()) * (qreal(frame) / 10.0) + qreal(m_preview.height()) * (1 - qreal(frame) / 10.0);
        m_size = QSize(width, height);
    }
    QPoint p = pos();
    resize(m_size);
    move(p);
    update(); // redrawing needed
}

class CustomDragAndDropGuard { // This guard destroys the singleton in its destructor
public:                   // This should avoid that a memory leak is reported
    ~CustomDragAndDropGuard() {
        if (CustomDragAndDrop::m_instance)
            delete CustomDragAndDrop::m_instance;
    }
};

CustomDragAndDrop* CustomDragAndDrop::m_instance = 0;

CustomDragAndDrop::CustomDragAndDrop() : m_customDragActive(0), m_mimeData(0), m_accepted(false)
{
    m_widget = new CustomDragAndDropIcon(QApplication::topLevelWidgets().first());
    m_widget->move(-1000, 1000);
    m_widget->resize(32, 32);
    m_widget->show();
}

CustomDragAndDrop* CustomDragAndDrop::instance()
{
    static CustomDragAndDropGuard guard; // The destructor destroys the singleton. See above
    if (m_instance == 0)
        m_instance = new CustomDragAndDrop();
    return m_instance;
}

void CustomDragAndDrop::endCustomDrag()
{
    instance()->m_customDragActive = false;
}

void CustomDragAndDrop::startCustomDrag(const QPixmap icon, const QPixmap preview, QMimeData * mimeData)
{
    if (instance()->m_customDragActive) {
        qWarning("CustomDragAndDrop::startCustomDrag drag is active");
        return ;
    }
    instance()->m_customDragActive = true;
    instance()-> m_accepted = false;
    show();
    instance()->m_mimeData = mimeData;
    instance()->m_widget->setIcon(icon);
    instance()->m_widget->setPreview(preview);
    instance()->m_widget->startDrag();
}

bool CustomDragAndDrop::customDragActive()
{
    return instance()->m_customDragActive;
}

bool CustomDragAndDrop::isAccepted()
{
    return instance()->m_accepted;
}

void CustomDragAndDrop::enter(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDragEnterEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
        instance()-> m_accepted = event.isAccepted(); // if the event is accepted we enter the "accepted" state
    } else {
        instance()-> m_accepted = false;
    }
}

void CustomDragAndDrop::leave(QWidget *target, QPoint globalPos)
{
    Q_UNUSED(globalPos)
    if (target) {
        QDragLeaveEvent event;
        QApplication::sendEvent(target, &event);
    } else {
       qWarning() <<  "CustomDragAndDrop::leave leaving invalid target";
    }
}

void CustomDragAndDrop::move(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDragMoveEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
    } else {
        qWarning() <<  "CustomDragAndDrop::move move in invalid target";
    }
}

void CustomDragAndDrop::drop(QWidget *target, QPoint globalPos)
{
    if (target) {
        QPoint pos = target->mapFromGlobal(globalPos);
        QDropEvent event(pos, Qt::MoveAction, instance()->m_mimeData ,Qt::RightButton, Qt::NoModifier);
        QApplication::sendEvent(target, &event);
    } else {
        qWarning() <<  "CustomDragAndDrop::drop dropping in invalid target";
    }
}

bool CustomDragAndDrop::isAnimated()
{
    if (instance()->m_widget)
        return instance()->m_widget->isAnimated();
    return false;
}

} // namespace QmlDesignerItemLibraryDragAndDrop
} // namespave QmlDesigner
<|endoftext|>