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

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

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

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

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

#include "WindowlessGlxApplication.h"

#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>

#include "Magnum/Platform/Context.h"

#define None 0L // redef Xlib nonsense

namespace Magnum { namespace Platform {

#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments): WindowlessGlxApplication{arguments, Configuration{}}  {}
#endif

WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments, const Configuration& configuration): WindowlessGlxApplication{arguments, nullptr} {
    createContext(configuration);
}

WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t) {}

void WindowlessGlxApplication::createContext() { createContext({}); }

void WindowlessGlxApplication::createContext(const Configuration& configuration) {
    if(!tryCreateContext(configuration)) std::exit(1);
}

bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
    CORRADE_ASSERT(!_context, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false);

    _display = XOpenDisplay(nullptr);

    /* Check version */
    int major, minor;
    glXQueryVersion(_display, &major, &minor);
    if(major == 1 && minor < 4) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): GLX version 1.4 or greater is required";
        return false;
    }

    /* Choose config */
    int configCount = 0;
    static const int fbAttributes[] = { None };
    GLXFBConfig* configs = glXChooseFBConfig(_display, DefaultScreen(_display), fbAttributes, &configCount);
    if(!configCount) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): no supported framebuffer configuration found";
        return false;
    }

    GLint contextAttributes[] = {
        #ifdef MAGNUM_TARGET_GLES
        #ifdef MAGNUM_TARGET_GLES3
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        #elif defined(MAGNUM_TARGET_GLES2)
        GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
        #else
        #error unsupported OpenGL ES version
        #endif
        GLX_CONTEXT_MINOR_VERSION_ARB, 0,
        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
        #endif
        0
    };

    /** @todo Use some extension wrangler for this, not GLEW, as it apparently needs context to create context, yo dawg wtf. */
    PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
    _glContext = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, contextAttributes);
    if(!_glContext) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot create context";
        return false;
    }

    /* Create pbuffer */
    int pbufferAttributes[] = {
        GLX_PBUFFER_WIDTH,  32,
        GLX_PBUFFER_HEIGHT, 32,
        None
    };
    _pbuffer = glXCreatePbuffer(_display, configs[0], pbufferAttributes);

    XFree(configs);

    /* Set OpenGL context as current */
    if(!glXMakeContextCurrent(_display, _pbuffer, _pbuffer, _glContext)) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot make context current";
        return false;
    }

    _context.reset(new Platform::Context);
    return true;
}

WindowlessGlxApplication::~WindowlessGlxApplication() {
    _context.reset();

    glXMakeCurrent(_display, None, nullptr);
    glXDestroyContext(_display, _glContext);
}

}}
<commit_msg>Platform: remove obsolete comment.<commit_after>/*
    This file is part of Magnum.

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

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

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

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

#include "WindowlessGlxApplication.h"

#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>

#include "Magnum/Platform/Context.h"

#define None 0L // redef Xlib nonsense

namespace Magnum { namespace Platform {

#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments): WindowlessGlxApplication{arguments, Configuration{}}  {}
#endif

WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments, const Configuration& configuration): WindowlessGlxApplication{arguments, nullptr} {
    createContext(configuration);
}

WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t) {}

void WindowlessGlxApplication::createContext() { createContext({}); }

void WindowlessGlxApplication::createContext(const Configuration& configuration) {
    if(!tryCreateContext(configuration)) std::exit(1);
}

bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
    CORRADE_ASSERT(!_context, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false);

    _display = XOpenDisplay(nullptr);

    /* Check version */
    int major, minor;
    glXQueryVersion(_display, &major, &minor);
    if(major == 1 && minor < 4) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): GLX version 1.4 or greater is required";
        return false;
    }

    /* Choose config */
    int configCount = 0;
    static const int fbAttributes[] = { None };
    GLXFBConfig* configs = glXChooseFBConfig(_display, DefaultScreen(_display), fbAttributes, &configCount);
    if(!configCount) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): no supported framebuffer configuration found";
        return false;
    }

    GLint contextAttributes[] = {
        #ifdef MAGNUM_TARGET_GLES
        #ifdef MAGNUM_TARGET_GLES3
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        #elif defined(MAGNUM_TARGET_GLES2)
        GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
        #else
        #error unsupported OpenGL ES version
        #endif
        GLX_CONTEXT_MINOR_VERSION_ARB, 0,
        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
        #endif
        0
    };

    PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
    _glContext = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, contextAttributes);
    if(!_glContext) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot create context";
        return false;
    }

    /* Create pbuffer */
    int pbufferAttributes[] = {
        GLX_PBUFFER_WIDTH,  32,
        GLX_PBUFFER_HEIGHT, 32,
        None
    };
    _pbuffer = glXCreatePbuffer(_display, configs[0], pbufferAttributes);

    XFree(configs);

    /* Set OpenGL context as current */
    if(!glXMakeContextCurrent(_display, _pbuffer, _pbuffer, _glContext)) {
        Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot make context current";
        return false;
    }

    _context.reset(new Platform::Context);
    return true;
}

WindowlessGlxApplication::~WindowlessGlxApplication() {
    _context.reset();

    glXMakeCurrent(_display, None, nullptr);
    glXDestroyContext(_display, _glContext);
}

}}
<|endoftext|>


<commit_before>/**
    @file ConnectionSTREAMEntry.cpp
    @author Lime Microsystems
    @brief Implementation of STREAM board connection.
*/

#include "ConnectionSTREAM.h"
#include <iostream>
using namespace lime;

#ifdef __unix__
void ConnectionSTREAMEntry::handle_libusb_events()
{
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 250000;
    while(mProcessUSBEvents.load() == true)
    {
        int r = libusb_handle_events_timeout_completed(ctx, &tv, NULL);
        if(r != 0) printf("error libusb_handle_events %s\n", libusb_strerror(libusb_error(r)));
    }
}
#endif // __UNIX__

//! make a static-initialized entry in the registry
void __loadConnectionSTREAMEntry(void) //TODO fixme replace with LoadLibrary/dlopen
{
static ConnectionSTREAMEntry STREAMEntry;
}

int USBTransferContext::idCounter = 0;

ConnectionSTREAMEntry::ConnectionSTREAMEntry(void):
    ConnectionRegistryEntry("STREAM")
{
#ifdef __unix__
    int r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0)
        printf("Init Error %i\n", r); //there was an error
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
    mProcessUSBEvents.store(true);
    mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this);
#endif
}

ConnectionSTREAMEntry::ConnectionSTREAMEntry(const std::string entryName):
    ConnectionRegistryEntry(entryName)
{
#ifdef __unix__
    int r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0)
        printf("Init Error %i\n", r); //there was an error
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
    mProcessUSBEvents.store(true);
    mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this);
#endif
}

ConnectionSTREAMEntry::~ConnectionSTREAMEntry(void)
{
#ifdef __unix__
    mProcessUSBEvents.store(false);
    mUSBProcessingThread.join();
    libusb_exit(ctx);
#endif
}

#ifndef __unix__
/** @return name of usb device as string.
    @param index device index in list
*/
std::string ConnectionSTREAMEntry::DeviceName(unsigned int index)
{
    std::string name;
    char tempName[USB_STRING_MAXLEN];
    CCyUSBDevice device;
    if (index >= device.DeviceCount())
        return "";

    for (int i = 0; i < USB_STRING_MAXLEN; ++i)
            tempName[i] = device.DeviceName[i];
    if (device.bSuperSpeed == true)
        name = "USB 3.0";
    else if (device.bHighSpeed == true)
        name = "USB 2.0";
    else
        name = "USB";
    name += " (";
    name += tempName;
    name += ")";
    return name;
}
#endif

std::vector<ConnectionHandle> ConnectionSTREAMEntry::enumerate(const ConnectionHandle &hint)
{
    std::vector<ConnectionHandle> handles;

#ifndef __unix__
	CCyUSBDevice device;
	if (device.DeviceCount())
    {
		for (int i = 0; i<device.DeviceCount(); ++i)
        {
			if (hint.index >= 0 && hint.index != i)
				continue;
			if (device.IsOpen())
				device.Close();
            device.Open(i);
            ConnectionHandle handle;
            handle.media = "USB";
            handle.name = DeviceName(i);
            handle.index = i;
            std::wstring ws(device.SerialNumber);
            handle.serial = std::string(ws.begin(),ws.end());
            if (hint.serial.empty() or hint.serial == handle.serial)
            {
                handles.push_back(handle); //filter on serial
            }
            device.Close();
        }
    }
#else
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    int usbDeviceCount = libusb_get_device_list(ctx, &devs);

    if (usbDeviceCount < 0) {
        printf("failed to get libusb device list: %s\n", libusb_strerror(libusb_error(usbDeviceCount)));
        return handles;
    }

    for(int i=0; i<usbDeviceCount; ++i)
    {
        libusb_device_descriptor desc;
        int r = libusb_get_device_descriptor(devs[i], &desc);
        if(r<0)
            printf("failed to get device description\n");
        int pid = desc.idProduct;
        int vid = desc.idVendor;

        if(vid == 1204 && pid == 34323)
        {
            ConnectionHandle handle;
            handle.media = "USB";
            handle.name = "DigiGreen";
            handle.addr = std::to_string(int(pid))+":"+std::to_string(int(vid));
            handles.push_back(handle);
        }
        else if((vid == 1204 && pid == 241) || (vid == 1204 && pid == 243) || (vid == 7504 && pid == 24840))
        {
            libusb_device_handle *tempDev_handle(nullptr);
            if(libusb_open(devs[i], &tempDev_handle) != 0 || tempDev_handle == nullptr)
                continue;
            if(libusb_kernel_driver_active(tempDev_handle, 0) == 1)   //find out if kernel driver is attached
            {
                if(libusb_detach_kernel_driver(tempDev_handle, 0) == 0) //detach it
                    printf("Kernel Driver Detached!\n");
            }
            if(libusb_claim_interface(tempDev_handle, 0) < 0) //claim interface 0 (the first) of device
            {
                printf("Cannot Claim Interface\n");
            }

            ConnectionHandle handle;

            //check operating speed
            int speed = libusb_get_device_speed(devs[i]);
            if(speed == LIBUSB_SPEED_HIGH)
                handle.media = "USB 2.0";
            else if(speed == LIBUSB_SPEED_SUPER)
                handle.media = "USB 3.0";
            else
                handle.media = "USB";

            //read device name
            char data[255];
            r = libusb_get_string_descriptor_ascii(tempDev_handle,  LIBUSB_CLASS_COMM, (unsigned char*)data, sizeof(data));
            if(r > 0) handle.name = std::string(data, size_t(r));

            r = std::sprintf(data, "%.4x:%.4x", int(vid), int(pid));
            if (r > 0) handle.addr = std::string(data, size_t(r));

            if (desc.iSerialNumber > 0)
            {
                r = libusb_get_string_descriptor_ascii(tempDev_handle,desc.iSerialNumber,(unsigned char*)data, sizeof(data));
                if(r<0)
                    printf("failed to get serial number\n");
                else
                    handle.serial = std::string(data, size_t(r));
            }
            libusb_close(tempDev_handle);

            //add handle conditionally, filter by serial number
            if (hint.serial.empty() or hint.serial == handle.serial)
            {
                handles.push_back(handle);
            }
        }
    }

    libusb_free_device_list(devs, 1);
#endif
    return handles;
}

IConnection *ConnectionSTREAMEntry::make(const ConnectionHandle &handle)
{
    return new ConnectionSTREAM(ctx, handle.addr, handle.serial, handle.index);
}
<commit_msg>limesdr - remove interface claim from enumeration<commit_after>/**
    @file ConnectionSTREAMEntry.cpp
    @author Lime Microsystems
    @brief Implementation of STREAM board connection.
*/

#include "ConnectionSTREAM.h"
#include <iostream>
using namespace lime;

#ifdef __unix__
void ConnectionSTREAMEntry::handle_libusb_events()
{
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 250000;
    while(mProcessUSBEvents.load() == true)
    {
        int r = libusb_handle_events_timeout_completed(ctx, &tv, NULL);
        if(r != 0) printf("error libusb_handle_events %s\n", libusb_strerror(libusb_error(r)));
    }
}
#endif // __UNIX__

//! make a static-initialized entry in the registry
void __loadConnectionSTREAMEntry(void) //TODO fixme replace with LoadLibrary/dlopen
{
static ConnectionSTREAMEntry STREAMEntry;
}

int USBTransferContext::idCounter = 0;

ConnectionSTREAMEntry::ConnectionSTREAMEntry(void):
    ConnectionRegistryEntry("STREAM")
{
#ifdef __unix__
    int r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0)
        printf("Init Error %i\n", r); //there was an error
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
    mProcessUSBEvents.store(true);
    mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this);
#endif
}

ConnectionSTREAMEntry::ConnectionSTREAMEntry(const std::string entryName):
    ConnectionRegistryEntry(entryName)
{
#ifdef __unix__
    int r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0)
        printf("Init Error %i\n", r); //there was an error
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
    mProcessUSBEvents.store(true);
    mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this);
#endif
}

ConnectionSTREAMEntry::~ConnectionSTREAMEntry(void)
{
#ifdef __unix__
    mProcessUSBEvents.store(false);
    mUSBProcessingThread.join();
    libusb_exit(ctx);
#endif
}

#ifndef __unix__
/** @return name of usb device as string.
    @param index device index in list
*/
std::string ConnectionSTREAMEntry::DeviceName(unsigned int index)
{
    std::string name;
    char tempName[USB_STRING_MAXLEN];
    CCyUSBDevice device;
    if (index >= device.DeviceCount())
        return "";

    for (int i = 0; i < USB_STRING_MAXLEN; ++i)
            tempName[i] = device.DeviceName[i];
    if (device.bSuperSpeed == true)
        name = "USB 3.0";
    else if (device.bHighSpeed == true)
        name = "USB 2.0";
    else
        name = "USB";
    name += " (";
    name += tempName;
    name += ")";
    return name;
}
#endif

std::vector<ConnectionHandle> ConnectionSTREAMEntry::enumerate(const ConnectionHandle &hint)
{
    std::vector<ConnectionHandle> handles;

#ifndef __unix__
	CCyUSBDevice device;
	if (device.DeviceCount())
    {
		for (int i = 0; i<device.DeviceCount(); ++i)
        {
			if (hint.index >= 0 && hint.index != i)
				continue;
			if (device.IsOpen())
				device.Close();
            device.Open(i);
            ConnectionHandle handle;
            handle.media = "USB";
            handle.name = DeviceName(i);
            handle.index = i;
            std::wstring ws(device.SerialNumber);
            handle.serial = std::string(ws.begin(),ws.end());
            if (hint.serial.empty() or hint.serial == handle.serial)
            {
                handles.push_back(handle); //filter on serial
            }
            device.Close();
        }
    }
#else
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    int usbDeviceCount = libusb_get_device_list(ctx, &devs);

    if (usbDeviceCount < 0) {
        printf("failed to get libusb device list: %s\n", libusb_strerror(libusb_error(usbDeviceCount)));
        return handles;
    }

    for(int i=0; i<usbDeviceCount; ++i)
    {
        libusb_device_descriptor desc;
        int r = libusb_get_device_descriptor(devs[i], &desc);
        if(r<0)
            printf("failed to get device description\n");
        int pid = desc.idProduct;
        int vid = desc.idVendor;

        if(vid == 1204 && pid == 34323)
        {
            ConnectionHandle handle;
            handle.media = "USB";
            handle.name = "DigiGreen";
            handle.addr = std::to_string(int(pid))+":"+std::to_string(int(vid));
            handles.push_back(handle);
        }
        else if((vid == 1204 && pid == 241) || (vid == 1204 && pid == 243) || (vid == 7504 && pid == 24840))
        {
            libusb_device_handle *tempDev_handle(nullptr);
            if(libusb_open(devs[i], &tempDev_handle) != 0 || tempDev_handle == nullptr)
                continue;

            ConnectionHandle handle;

            //check operating speed
            int speed = libusb_get_device_speed(devs[i]);
            if(speed == LIBUSB_SPEED_HIGH)
                handle.media = "USB 2.0";
            else if(speed == LIBUSB_SPEED_SUPER)
                handle.media = "USB 3.0";
            else
                handle.media = "USB";

            //read device name
            char data[255];
            r = libusb_get_string_descriptor_ascii(tempDev_handle,  LIBUSB_CLASS_COMM, (unsigned char*)data, sizeof(data));
            if(r > 0) handle.name = std::string(data, size_t(r));

            r = std::sprintf(data, "%.4x:%.4x", int(vid), int(pid));
            if (r > 0) handle.addr = std::string(data, size_t(r));

            if (desc.iSerialNumber > 0)
            {
                r = libusb_get_string_descriptor_ascii(tempDev_handle,desc.iSerialNumber,(unsigned char*)data, sizeof(data));
                if(r<0)
                    printf("failed to get serial number\n");
                else
                    handle.serial = std::string(data, size_t(r));
            }
            libusb_close(tempDev_handle);

            //add handle conditionally, filter by serial number
            if (hint.serial.empty() or hint.serial == handle.serial)
            {
                handles.push_back(handle);
            }
        }
    }

    libusb_free_device_list(devs, 1);
#endif
    return handles;
}

IConnection *ConnectionSTREAMEntry::make(const ConnectionHandle &handle)
{
    return new ConnectionSTREAM(ctx, handle.addr, handle.serial, handle.index);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2016 Stefan Tröger <stefantroeger@gmx.net>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "ViewProviderAttachExtension.h"
#include <Mod/Part/App/AttachExtension.h>

#include <Gui/BitmapFactory.h>

using namespace PartGui;

EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderAttachExtension, Gui::ViewProviderExtension)

ViewProviderAttachExtension::ViewProviderAttachExtension()
{
    initExtensionType(ViewProviderAttachExtension::getExtensionClassTypeId());
}

QIcon ViewProviderAttachExtension::extensionMergeOverlayIcons(const QIcon & orig) const
{
    QIcon mergedicon = orig;

    if (getExtendedViewProvider()->getObject()->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) {

        auto* attach = getExtendedViewProvider()->getObject()->getExtensionByType<Part::AttachExtension>();

        if (attach) {

            if(!attach->isAttacherActive()) {
                QPixmap px;

                static const char * const feature_detached_xpm[]={
                    "9 9 3 1",
                    ". c None",
                    "# c #cc00cc",
                    "a c #ffffff",
                    "...###...",
                    ".##aaa##.",
                    "##aaaaa##",
                    "##aaaaa##",
                    "#########",
                    "#########",
                    "#########",
                    ".##aaa##.",
                    ".##aaa##.",
                    "...###..."};

                    px = QPixmap(feature_detached_xpm);

                    mergedicon = Gui::BitmapFactoryInst::mergePixmap(mergedicon, px, Gui::BitmapFactoryInst::BottomLeft);
            }
        }
    }

    return mergedicon;
}

void ViewProviderAttachExtension::extensionUpdateData(const App::Property* prop)
{
    if (getExtendedViewProvider()->getObject()->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) {
        auto* attach = getExtendedViewProvider()->getObject()->getExtensionByType<Part::AttachExtension>();

        if(attach) {
            if( prop == &(attach->Support) ||
                prop == &(attach->MapMode) ||
                prop == &(attach->MapPathParameter) ||
                prop == &(attach->MapReversed) ||
                prop == &(attach->AttachmentOffset) ||
                prop == &(attach->AttacherType) ) {

                getExtendedViewProvider()->signalChangeIcon(); // signal icon change
            }
        }
    }

}

namespace Gui {
    EXTENSION_PROPERTY_SOURCE_TEMPLATE(PartGui::ViewProviderAttachExtensionPython, PartGui::ViewProviderAttachExtension)

// explicit template instantiation
    template class PartGuiExport ViewProviderExtensionPythonT<PartGui::ViewProviderAttachExtension>;
}
<commit_msg>fix MSVC compiler warning<commit_after>/***************************************************************************
 *   Copyright (c) 2016 Stefan Tröger <stefantroeger@gmx.net>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# ifdef _MSC_VER
#  define _USE_MATH_DEFINES
#  include <cmath>
# endif //_MSC_VER
#endif

#include "ViewProviderAttachExtension.h"
#include <Mod/Part/App/AttachExtension.h>

#include <Gui/BitmapFactory.h>

using namespace PartGui;

EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderAttachExtension, Gui::ViewProviderExtension)

ViewProviderAttachExtension::ViewProviderAttachExtension()
{
    initExtensionType(ViewProviderAttachExtension::getExtensionClassTypeId());
}

QIcon ViewProviderAttachExtension::extensionMergeOverlayIcons(const QIcon & orig) const
{
    QIcon mergedicon = orig;

    if (getExtendedViewProvider()->getObject()->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) {

        auto* attach = getExtendedViewProvider()->getObject()->getExtensionByType<Part::AttachExtension>();

        if (attach) {

            if(!attach->isAttacherActive()) {
                QPixmap px;

                static const char * const feature_detached_xpm[]={
                    "9 9 3 1",
                    ". c None",
                    "# c #cc00cc",
                    "a c #ffffff",
                    "...###...",
                    ".##aaa##.",
                    "##aaaaa##",
                    "##aaaaa##",
                    "#########",
                    "#########",
                    "#########",
                    ".##aaa##.",
                    ".##aaa##.",
                    "...###..."};

                    px = QPixmap(feature_detached_xpm);

                    mergedicon = Gui::BitmapFactoryInst::mergePixmap(mergedicon, px, Gui::BitmapFactoryInst::BottomLeft);
            }
        }
    }

    return mergedicon;
}

void ViewProviderAttachExtension::extensionUpdateData(const App::Property* prop)
{
    if (getExtendedViewProvider()->getObject()->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) {
        auto* attach = getExtendedViewProvider()->getObject()->getExtensionByType<Part::AttachExtension>();

        if(attach) {
            if( prop == &(attach->Support) ||
                prop == &(attach->MapMode) ||
                prop == &(attach->MapPathParameter) ||
                prop == &(attach->MapReversed) ||
                prop == &(attach->AttachmentOffset) ||
                prop == &(attach->AttacherType) ) {

                getExtendedViewProvider()->signalChangeIcon(); // signal icon change
            }
        }
    }

}

namespace Gui {
    EXTENSION_PROPERTY_SOURCE_TEMPLATE(PartGui::ViewProviderAttachExtensionPython, PartGui::ViewProviderAttachExtension)

// explicit template instantiation
    template class PartGuiExport ViewProviderExtensionPythonT<PartGui::ViewProviderAttachExtension>;
}
<|endoftext|>


<commit_before>#include "AnimationClipEditor.hpp"
#include <Engine/Animation/AnimationClip.hpp>
#include <Engine/Hymn.hpp>
#include <imgui.h>
#include <Engine/Util/FileSystem.hpp>
#include "Util/AssetConverterSkeleton.hpp"

using namespace GUI;

AnimationClipEditor::AnimationClipEditor() {
}

void AnimationClipEditor::Show() {
    if (ImGui::Begin(("Animation clip: " + animationClip->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(animationClip))).c_str(), &visible, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_ShowBorders)) {
        if (ImGui::Button("Open animation model")) {
            // Currently only fbx is tested.
            fileSelector.AddExtensions("fbx");

            // Set the initial path to the models directory.
            fileSelector.SetInitialPath((Hymn().GetPath()).c_str());
            fileSelector.SetFileSelectedCallback(std::bind(&AnimationClipEditor::FileSelected, this, std::placeholders::_1));
            fileSelector.SetVisible(true);
        }
    }
    ImGui::End();

    if (fileSelector.IsVisible())
        fileSelector.Show();
}

Animation::AnimationClip* GUI::AnimationClipEditor::GetAnimationClip() {
    return animationClip;
}

void AnimationClipEditor::SetAnimationClip(Animation::AnimationClip* animationClip) {
    this->animationClip = animationClip;
}

bool AnimationClipEditor::IsVisible() const {
    return visible;
}

void AnimationClipEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void GUI::AnimationClipEditor::FileSelected(const std::string& file) {
    std::string name = FileSystem::GetName(file).c_str();
    std::string newFile = Hymn().GetPath() + "/" + animationClip->path + name + ".asset";

    AssetConverterSkeleton con;
    con.Convert(file.c_str(), newFile.c_str(), false);

    animationClip->name = name;
}
<commit_msg>Remove unnecessary acquisition of C-string.<commit_after>#include "AnimationClipEditor.hpp"
#include <Engine/Animation/AnimationClip.hpp>
#include <Engine/Hymn.hpp>
#include <imgui.h>
#include <Engine/Util/FileSystem.hpp>
#include "Util/AssetConverterSkeleton.hpp"

using namespace GUI;

AnimationClipEditor::AnimationClipEditor() {
}

void AnimationClipEditor::Show() {
    if (ImGui::Begin(("Animation clip: " + animationClip->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(animationClip))).c_str(), &visible, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_ShowBorders)) {
        if (ImGui::Button("Open animation model")) {
            // Currently only fbx is tested.
            fileSelector.AddExtensions("fbx");

            // Set the initial path to the models directory.
            fileSelector.SetInitialPath((Hymn().GetPath()).c_str());
            fileSelector.SetFileSelectedCallback(std::bind(&AnimationClipEditor::FileSelected, this, std::placeholders::_1));
            fileSelector.SetVisible(true);
        }
    }
    ImGui::End();

    if (fileSelector.IsVisible())
        fileSelector.Show();
}

Animation::AnimationClip* GUI::AnimationClipEditor::GetAnimationClip() {
    return animationClip;
}

void AnimationClipEditor::SetAnimationClip(Animation::AnimationClip* animationClip) {
    this->animationClip = animationClip;
}

bool AnimationClipEditor::IsVisible() const {
    return visible;
}

void AnimationClipEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void GUI::AnimationClipEditor::FileSelected(const std::string& file) {
    std::string name = FileSystem::GetName(file);
    std::string newFile = Hymn().GetPath() + "/" + animationClip->path + name + ".asset";

    AssetConverterSkeleton con;
    con.Convert(file.c_str(), newFile.c_str(), false);

    animationClip->name = name;
}
<|endoftext|>


<commit_before>#include "StorageMergeChunkJob.h"
#include "System/Stopwatch.h"
#include "System/FileSystem.h"
#include "StorageEnvironment.h"
#include "StorageChunkMerger.h"

StorageMergeChunkJob::StorageMergeChunkJob(StorageEnvironment* env_,
 uint64_t contextID_, uint64_t shardID_,
 List<StorageFileChunk*>& inputChunks_,
 StorageFileChunk* mergeChunk_,
 ReadBuffer firstKey_, ReadBuffer lastKey_)
{
    StorageFileChunk**  itChunk;

    env = env_;
    contextID = contextID_;
    shardID = shardID_;

    FOREACH(itChunk, inputChunks_)
        inputChunks.Append(*itChunk);

    firstKey.Write(firstKey_);
    lastKey.Write(lastKey_);
    mergeChunk = mergeChunk_;
}

StorageMergeChunkJob::~StorageMergeChunkJob()
{
    delete mergeChunk;
}

void StorageMergeChunkJob::Execute()
{
    bool                ret;
    Buffer*             filename;
    StorageFileChunk**  itInputChunk;
    StorageChunkMerger  merger;
    List<Buffer*>       filenames;
    Stopwatch           sw;

    FOREACH (itInputChunk, inputChunks)
    {
        filename = &(*itInputChunk)->GetFilename();
        filenames.Add(filename);
    }

    Log_Debug("Merging %u chunks into chunk %U...",
     filenames.GetLength(),
     mergeChunk->GetChunkID());
    sw.Start();
    ret = merger.Merge(env, filenames, mergeChunk, firstKey, lastKey);
    sw.Stop();

    if (mergeChunk->writeError)
    {
        // write failed
        Log_Message("Unable to write chunk file %U to disk.", mergeChunk->GetChunkID());
        Log_Message("Free disk space: %s", HUMAN_BYTES(FS_FreeDiskSpace(mergeChunk->GetFilename().GetBuffer())));
        Log_Message("This should not happen.");
        Log_Message("Possible causes: not enough disk space, software bug...");
        STOP_FAIL(1);
    }

    if (ret)
    {
        Log_Debug("Done merging chunk %U, elapsed: %U, size: %s, bps: %sB/s",
         mergeChunk->GetChunkID(),
         (uint64_t) sw.Elapsed(), HUMAN_BYTES(mergeChunk->GetSize()),
         HUMAN_BYTES((uint64_t)(mergeChunk->GetSize() / (sw.Elapsed() / 1000.0))));
    }
    else
    {
        Log_Debug("Merge aborted, chunk %U, elapsed: %U, size: %s, bps: %sB/s, free disk space: %s",
         mergeChunk->GetChunkID(),
         (uint64_t) sw.Elapsed(), HUMAN_BYTES(mergeChunk->GetSize()),
         HUMAN_BYTES((uint64_t)(mergeChunk->GetSize() / (sw.Elapsed() / 1000.0))),
         HUMAN_BYTES(FS_FreeDiskSpace(mergeChunk->GetFilename().GetBuffer())));
    }
}

void StorageMergeChunkJob::OnComplete()
{
    env->OnChunkMerge(this); // deletes this
}
<commit_msg>Changed merge aborted log output.<commit_after>#include "StorageMergeChunkJob.h"
#include "System/Stopwatch.h"
#include "System/FileSystem.h"
#include "StorageEnvironment.h"
#include "StorageChunkMerger.h"

StorageMergeChunkJob::StorageMergeChunkJob(StorageEnvironment* env_,
 uint64_t contextID_, uint64_t shardID_,
 List<StorageFileChunk*>& inputChunks_,
 StorageFileChunk* mergeChunk_,
 ReadBuffer firstKey_, ReadBuffer lastKey_)
{
    StorageFileChunk**  itChunk;

    env = env_;
    contextID = contextID_;
    shardID = shardID_;

    FOREACH(itChunk, inputChunks_)
        inputChunks.Append(*itChunk);

    firstKey.Write(firstKey_);
    lastKey.Write(lastKey_);
    mergeChunk = mergeChunk_;
}

StorageMergeChunkJob::~StorageMergeChunkJob()
{
    delete mergeChunk;
}

void StorageMergeChunkJob::Execute()
{
    bool                ret;
    Buffer*             filename;
    StorageFileChunk**  itInputChunk;
    StorageChunkMerger  merger;
    List<Buffer*>       filenames;
    Stopwatch           sw;

    FOREACH (itInputChunk, inputChunks)
    {
        filename = &(*itInputChunk)->GetFilename();
        filenames.Add(filename);
    }

    Log_Debug("Merging %u chunks into chunk %U...",
     filenames.GetLength(),
     mergeChunk->GetChunkID());
    sw.Start();
    ret = merger.Merge(env, filenames, mergeChunk, firstKey, lastKey);
    sw.Stop();

    if (mergeChunk->writeError)
    {
        // write failed
        Log_Message("Unable to write chunk file %U to disk.", mergeChunk->GetChunkID());
        Log_Message("Free disk space: %s", HUMAN_BYTES(FS_FreeDiskSpace(mergeChunk->GetFilename().GetBuffer())));
        Log_Message("This should not happen.");
        Log_Message("Possible causes: not enough disk space, software bug...");
        STOP_FAIL(1);
    }

    if (ret)
    {
        Log_Debug("Done merging chunk %U, elapsed: %U, size: %s, bps: %sB/s",
         mergeChunk->GetChunkID(),
         (uint64_t) sw.Elapsed(), HUMAN_BYTES(mergeChunk->GetSize()),
         HUMAN_BYTES((uint64_t)(mergeChunk->GetSize() / (sw.Elapsed() / 1000.0))));
    }
    else
    {
        Log_Debug("Merge aborted, chunk %U, elapsed: %U, free disk space: %s",
         mergeChunk->GetChunkID(),
         (uint64_t) sw.Elapsed(),
         HUMAN_BYTES(FS_FreeDiskSpace(mergeChunk->GetFilename().GetBuffer())));
    }
}

void StorageMergeChunkJob::OnComplete()
{
    env->OnChunkMerge(this); // deletes this
}
<|endoftext|>


<commit_before>// Gnome.hh for fluxbox
// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen<at>fluxbox.org)
//
// 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.

// $Id$

#ifndef GNOME_HH
#define GNOME_HH

#include "AtomHandler.hh"

#include <X11/Xatom.h>
#include <vector>

class Gnome:public AtomHandler {
public:
    enum GnomeLayer {
        WIN_LAYER_DESKTOP = 0,
        WIN_LAYER_BELOW = 2,
        WIN_LAYER_NORMAL = 4,
        WIN_LAYER_ONTOP = 6,
        WIN_LAYER_DOCK = 8,
        WIN_LAYER_ABOVE_DOCK = 10,
        WIN_LAYER_MENU = 12
    };

    enum GnomeState {
        WIN_STATE_STICKY          = (1<<0), // everyone knows sticky
        WIN_STATE_MINIMIZED       = (1<<1), // Reserved - definition is unclear
        WIN_STATE_MAXIMIZED_VERT  = (1<<2), // window in maximized V state
        WIN_STATE_MAXIMIZED_HORIZ = (1<<3), // window in maximized H state
        WIN_STATE_HIDDEN          = (1<<4), // not on taskbar but window visible
        WIN_STATE_SHADED          = (1<<5), // shaded (MacOS / Afterstep style)
        WIN_STATE_HID_WORKSPACE   = (1<<6), // not on current desktop
        WIN_STATE_HID_TRANSIENT   = (1<<7), // owner of transient is hidden
        WIN_STATE_FIXED_POSITION  = (1<<8), // window is fixed in position even
        WIN_STATE_ARRANGE_IGNORE  = (1<<9)  // ignore for auto arranging
    };

    enum GnomeHints {
        WIN_HINTS_SKIP_FOCUS      = (1<<0), // skip this window
        WIN_HINTS_SKIP_WINLIST    = (1<<1), // do not show in window list
        WIN_HINTS_SKIP_TASKBAR    = (1<<2), // do not show on taskbar
        WIN_HINTS_GROUP_TRANSIENT = (1<<3), // Reserved - definition is unclear
        WIN_HINTS_FOCUS_ON_CLICK  = (1<<4)  // app only accepts focus if clicked
    };

    Gnome();
    ~Gnome();
    void initForScreen(BScreen &screen);
    void setupFrame(FluxboxWindow &win);
    void setupClient(WinClient &winclient) {}

    void updateWorkarea(BScreen &) { }
    void updateFocusedWindow(BScreen &, Window) { }
    void updateClientList(BScreen &screen);
    void updateWorkspaceNames(BScreen &screen);
    void updateCurrentWorkspace(BScreen &screen);
    void updateWorkspaceCount(BScreen &screen);

    void updateState(FluxboxWindow &win);
    void updateLayer(FluxboxWindow &win);
    void updateHints(FluxboxWindow &win);
    void updateWorkspace(FluxboxWindow &win);

    bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient);

    // ignore these ones
    void updateFrameClose(FluxboxWindow &win) {}
    void updateClientClose(WinClient &winclient) {}
    bool propertyNotify(WinClient &winclient, Atom the_property);

private:
    void setLayer(FluxboxWindow *win, int layer);
    void setState(FluxboxWindow *win, int state);
    void setLayer(int layer);
    void createAtoms();
    Atom m_gnome_wm_win_layer, m_gnome_wm_win_state, m_gnome_wm_win_hints,
        m_gnome_wm_win_app_state, m_gnome_wm_win_expanded_size,
        m_gnome_wm_win_icons, m_gnome_wm_win_workspace,
        m_gnome_wm_win_workspace_count, m_gnome_wm_win_workspace_names,
        m_gnome_wm_win_client_list;
    Atom m_gnome_wm_prot;
    Atom m_gnome_wm_supporting_wm_check;
    std::vector<Window> m_gnomewindows;
};

#endif // GNOME_HH
<commit_msg>added url for gnome-hints<commit_after>// Gnome.hh for fluxbox
// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen<at>fluxbox.org)
//
// 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.

// $Id$

#ifndef GNOME_HH
#define GNOME_HH

#include "AtomHandler.hh"

#include <X11/Xatom.h>
#include <vector>

// Implementes Gnome Window Manager Hints (http://developer.gnome.org/doc/standards/wm/book1.html)
class Gnome:public AtomHandler {
public:
    enum GnomeLayer {
        WIN_LAYER_DESKTOP = 0,
        WIN_LAYER_BELOW = 2,
        WIN_LAYER_NORMAL = 4,
        WIN_LAYER_ONTOP = 6,
        WIN_LAYER_DOCK = 8,
        WIN_LAYER_ABOVE_DOCK = 10,
        WIN_LAYER_MENU = 12
    };

    enum GnomeState {
        WIN_STATE_STICKY          = (1<<0), // everyone knows sticky
        WIN_STATE_MINIMIZED       = (1<<1), // Reserved - definition is unclear
        WIN_STATE_MAXIMIZED_VERT  = (1<<2), // window in maximized V state
        WIN_STATE_MAXIMIZED_HORIZ = (1<<3), // window in maximized H state
        WIN_STATE_HIDDEN          = (1<<4), // not on taskbar but window visible
        WIN_STATE_SHADED          = (1<<5), // shaded (MacOS / Afterstep style)
        WIN_STATE_HID_WORKSPACE   = (1<<6), // not on current desktop
        WIN_STATE_HID_TRANSIENT   = (1<<7), // owner of transient is hidden
        WIN_STATE_FIXED_POSITION  = (1<<8), // window is fixed in position even
        WIN_STATE_ARRANGE_IGNORE  = (1<<9)  // ignore for auto arranging
    };

    enum GnomeHints {
        WIN_HINTS_SKIP_FOCUS      = (1<<0), // skip this window
        WIN_HINTS_SKIP_WINLIST    = (1<<1), // do not show in window list
        WIN_HINTS_SKIP_TASKBAR    = (1<<2), // do not show on taskbar
        WIN_HINTS_GROUP_TRANSIENT = (1<<3), // Reserved - definition is unclear
        WIN_HINTS_FOCUS_ON_CLICK  = (1<<4)  // app only accepts focus if clicked
    };

    Gnome();
    ~Gnome();
    void initForScreen(BScreen &screen);
    void setupFrame(FluxboxWindow &win);
    void setupClient(WinClient &winclient) {}

    void updateWorkarea(BScreen &) { }
    void updateFocusedWindow(BScreen &, Window) { }
    void updateClientList(BScreen &screen);
    void updateWorkspaceNames(BScreen &screen);
    void updateCurrentWorkspace(BScreen &screen);
    void updateWorkspaceCount(BScreen &screen);

    void updateState(FluxboxWindow &win);
    void updateLayer(FluxboxWindow &win);
    void updateHints(FluxboxWindow &win);
    void updateWorkspace(FluxboxWindow &win);

    bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient);

    // ignore these ones
    void updateFrameClose(FluxboxWindow &win) {}
    void updateClientClose(WinClient &winclient) {}
    bool propertyNotify(WinClient &winclient, Atom the_property);

private:
    void setLayer(FluxboxWindow *win, int layer);
    void setState(FluxboxWindow *win, int state);
    void setLayer(int layer);
    void createAtoms();
    Atom m_gnome_wm_win_layer, m_gnome_wm_win_state, m_gnome_wm_win_hints,
        m_gnome_wm_win_app_state, m_gnome_wm_win_expanded_size,
        m_gnome_wm_win_icons, m_gnome_wm_win_workspace,
        m_gnome_wm_win_workspace_count, m_gnome_wm_win_workspace_names,
        m_gnome_wm_win_client_list;
    Atom m_gnome_wm_prot;
    Atom m_gnome_wm_supporting_wm_check;
    std::vector<Window> m_gnomewindows;
};

#endif // GNOME_HH
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <file.hpp>
#include <system.hpp>
#include <errors.hpp>
#include <io.hpp>
#include <print.hpp>
#include <math.hpp>

#include "fat32_specs.hpp"

static constexpr const size_t BUFFER_SIZE = 4096;

int main(int argc, char* argv[]){
    if(argc < 3){
        printf("usage: mkfs fs device \n");

        exit(1);
    }

    auto fs_str = argv[1];
    auto device_str = argv[2];

    std::string fs(fs_str);

    if(fs == "fat32"){
        // Open the device file
        auto fd = open(device_str);

        if(!fd.valid()){
            printf("mkfs: open error: %s\n", std::error_message(fd.error()));
            exit(1);
        }

        // Get the size of the device

        uint64_t size = 0;
        auto code = ioctl(device_str, ioctl_request::GET_BLK_SIZE, &size);

        if(code){
            printf("mkfs: ioctl error: %s\n", std::error_message(code));
            exit(1);
        }

        // Start computing and writing the FAT32 values

        printf("mkfs: Creating Fat32 filesystem on %s\n", device_str);
        printf("mkfs: Device size: %m\n", size);

        uint64_t sector_size = 512;
        uint64_t sectors_per_cluster = 8;
        uint64_t sectors = size / sector_size;

        uint64_t available_sectors = sectors - sectors_per_cluster;
        uint64_t available_clusters = available_sectors / sectors_per_cluster;

        // Compute the size of the FAT
        uint64_t fat_size_bytes = available_clusters * sizeof(uint32_t);
        uint64_t fat_size_sectors = std::ceil_divide(fat_size_bytes, sector_size);
        uint64_t fat_size_clusters = std::ceil_divide(fat_size_sectors, sectors_per_cluster);
        fat_size_sectors = fat_size_clusters * sectors_per_cluster;

        printf("mkfs: Device sectors : %u\n", sectors);
        printf("mkfs: Available sectors : %u\n", available_sectors);
        printf("mkfs: FAT sectors : %u\n", fat_size_sectors);

        uint64_t free_clusters = available_clusters - fat_size_clusters - 1;
        uint64_t free_sectors = free_clusters * sectors_per_cluster;

        printf("mkfs: Free sectors : %u\n", free_sectors);
        printf("mkfs: Free clusters : %u\n", free_clusters);

        auto* fat_bs = new fat32::fat_bs_t();

        fat_bs->bytes_per_sector = sector_size;
        fat_bs->sectors_per_cluster = sectors_per_cluster;
        fat_bs->reserved_sectors = sectors_per_cluster - 2;
        fat_bs->number_of_fat = 1;
        fat_bs->root_directories_entries = 0;
        fat_bs->total_sectors = 0;
        fat_bs->total_sectors_long = sectors;
        fat_bs->sectors_per_fat = 0;
        fat_bs->sectors_per_fat_long = fat_size_sectors;
        fat_bs->root_directory_cluster_start = 2;
        fat_bs->fs_information_sector = 1;
        std::copy_n(&fat_bs->file_system_type[0], "FAT32", 5);
        fat_bs->signature = 0xAA55;

        // Write the FAT BS
        auto status = write(*fd, reinterpret_cast<const char*>(fat_bs), sector_size, 0);

        if(!status.valid()){
            printf("mkfs: write error: %s\n", std::error_message(status.error()));
            exit(1);
        }

        // TODO Write fat_bs to write

        auto* fat_is = new fat32::fat_is_t();

        fat_is->allocated_clusters = 1;
        fat_is->free_clusters = free_clusters;
        fat_is->signature_start = 0x52526141;
        fat_is->signature_middle = 0x72724161;
        fat_is->signature_end = 0x000055AA;

        // Write the FAT IS
        status = write(*fd, reinterpret_cast<const char*>(fat_is), sector_size, sector_size);

        if(!status.valid()){
            printf("mkfs: write error: %s\n", std::error_message(status.error()));
            exit(1);
        }

        //TODO Write FAT

        //TODO Write Root Cluster

        delete fat_is;
        delete fat_bs;

        exit(0);
    }

    printf("mkfs: Unsupported filesystem %s\n", fs_str);

    exit(0);
}
<commit_msg>Remove TODO (already done)<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <file.hpp>
#include <system.hpp>
#include <errors.hpp>
#include <io.hpp>
#include <print.hpp>
#include <math.hpp>

#include "fat32_specs.hpp"

static constexpr const size_t BUFFER_SIZE = 4096;

int main(int argc, char* argv[]){
    if(argc < 3){
        printf("usage: mkfs fs device \n");

        exit(1);
    }

    auto fs_str = argv[1];
    auto device_str = argv[2];

    std::string fs(fs_str);

    if(fs == "fat32"){
        // Open the device file
        auto fd = open(device_str);

        if(!fd.valid()){
            printf("mkfs: open error: %s\n", std::error_message(fd.error()));
            exit(1);
        }

        // Get the size of the device

        uint64_t size = 0;
        auto code = ioctl(device_str, ioctl_request::GET_BLK_SIZE, &size);

        if(code){
            printf("mkfs: ioctl error: %s\n", std::error_message(code));
            exit(1);
        }

        // Start computing and writing the FAT32 values

        printf("mkfs: Creating Fat32 filesystem on %s\n", device_str);
        printf("mkfs: Device size: %m\n", size);

        uint64_t sector_size = 512;
        uint64_t sectors_per_cluster = 8;
        uint64_t sectors = size / sector_size;

        uint64_t available_sectors = sectors - sectors_per_cluster;
        uint64_t available_clusters = available_sectors / sectors_per_cluster;

        // Compute the size of the FAT
        uint64_t fat_size_bytes = available_clusters * sizeof(uint32_t);
        uint64_t fat_size_sectors = std::ceil_divide(fat_size_bytes, sector_size);
        uint64_t fat_size_clusters = std::ceil_divide(fat_size_sectors, sectors_per_cluster);
        fat_size_sectors = fat_size_clusters * sectors_per_cluster;

        printf("mkfs: Device sectors : %u\n", sectors);
        printf("mkfs: Available sectors : %u\n", available_sectors);
        printf("mkfs: FAT sectors : %u\n", fat_size_sectors);

        uint64_t free_clusters = available_clusters - fat_size_clusters - 1;
        uint64_t free_sectors = free_clusters * sectors_per_cluster;

        printf("mkfs: Free sectors : %u\n", free_sectors);
        printf("mkfs: Free clusters : %u\n", free_clusters);

        auto* fat_bs = new fat32::fat_bs_t();

        fat_bs->bytes_per_sector = sector_size;
        fat_bs->sectors_per_cluster = sectors_per_cluster;
        fat_bs->reserved_sectors = sectors_per_cluster - 2;
        fat_bs->number_of_fat = 1;
        fat_bs->root_directories_entries = 0;
        fat_bs->total_sectors = 0;
        fat_bs->total_sectors_long = sectors;
        fat_bs->sectors_per_fat = 0;
        fat_bs->sectors_per_fat_long = fat_size_sectors;
        fat_bs->root_directory_cluster_start = 2;
        fat_bs->fs_information_sector = 1;
        std::copy_n(&fat_bs->file_system_type[0], "FAT32", 5);
        fat_bs->signature = 0xAA55;

        // Write the FAT BS
        auto status = write(*fd, reinterpret_cast<const char*>(fat_bs), sector_size, 0);

        if(!status.valid()){
            printf("mkfs: write error: %s\n", std::error_message(status.error()));
            exit(1);
        }

        auto* fat_is = new fat32::fat_is_t();

        fat_is->allocated_clusters = 1;
        fat_is->free_clusters = free_clusters;
        fat_is->signature_start = 0x52526141;
        fat_is->signature_middle = 0x72724161;
        fat_is->signature_end = 0x000055AA;

        // Write the FAT IS
        status = write(*fd, reinterpret_cast<const char*>(fat_is), sector_size, sector_size);

        if(!status.valid()){
            printf("mkfs: write error: %s\n", std::error_message(status.error()));
            exit(1);
        }

        //TODO Write FAT

        //TODO Write Root Cluster

        delete fat_is;
        delete fat_bs;

        exit(0);
    }

    printf("mkfs: Unsupported filesystem %s\n", fs_str);

    exit(0);
}
<|endoftext|>


<commit_before>// Copyright (C) 2012, Luis Pedro Coelho <luis@luispedro.org>
// License: MIT

#include <iostream>
#include <memory>
#include <cmath>
#include <random>
#include <cassert>
#include <eigen3/Eigen/Dense>

using namespace Eigen;

extern "C" {
    #include <Python.h>
    #include <numpy/ndarrayobject.h>
}

namespace {

template <typename T>
int random_int(T& random, const int max) {
    std::uniform_int_distribution<int> dist(0, max - 1);
    return dist(random);
}

inline
float soft(float val, float lam) {
    return copysign(fdim(fabs(val), lam), val);
}

int coordinate_descent(const MatrixXf& X, const MatrixXf& Y, MatrixXf& B, const int max_iter, const float lam, int maxnops=-1, const float eps=1e-15) {
    std::mt19937 r;
    MatrixXf residuals = Y - B*X;
    if (maxnops == -1) {
        maxnops = 2*B.size();
    }
    int nops = 0;
    int i = 0;
    int j = 0;
    for (int it = 0; it != max_iter; ++it) {
        ++j;
        if (j == B.cols()) {
            j = 0;
            ++i;
            if (i == B.rows()) i = 0;
        }
        // Given everything else as fixed, this comes down to a very simple
        // 1-dimensional problem. We remember the current value:
        const float prev = B(i,j);
        float xy = 0.0;
        float x2 = 0.0;
        for (int k = 0; k != Y.cols(); ++k) {
            if (isnan(Y(i,k))) continue;
            x2 += X(j,k)*X(j,k);
            xy += X(j,k)*residuals(i,k);
        }
        const float step = (x2 == 0. ? 0. : (xy/x2));
        const float best = soft(prev + step, lam);
        if (fabs(best - prev) < eps) {
            ++nops;
            if (nops > maxnops) return it;
        } else {
            assert(!isnan(best));
            nops = 0;
            B(i,j) = best;
            // This is slow, but whatever
            residuals = Y - B*X;
        }
    }
    return max_iter;
}

Map<MatrixXf> as_eigen(PyArrayObject* arr) {
    assert(PyArray_EquivTypenums(PyArray_TYPE(arr), NPY_FLOAT32));
    return Map<MatrixXf>(
                    static_cast<float*>(PyArray_DATA(arr)),
                    PyArray_DIM(arr, 0),
                    PyArray_DIM(arr, 1));
}

const char* errmsg = "INTERNAL ERROR";
PyObject* py_lasso(PyObject* self, PyObject* args) {
    PyArrayObject* Y;
    PyArrayObject* X;
    PyArrayObject* B;
    int max_iter;
    float lam;
    float eps;
    if (!PyArg_ParseTuple(args, "OOOiff", &X, &Y, &B, &max_iter, &lam, &eps)) return NULL;
    if (!PyArray_Check(X) || //!PyArray_ISCARRAY_RO(X) ||
        !PyArray_Check(Y) || //!PyArray_ISCARRAY_RO(Y) ||
        !PyArray_Check(B) || //!PyArray_ISCARRAY(B) ||
        !PyArray_EquivTypenums(PyArray_TYPE(X), NPY_FLOAT32) ||
        !PyArray_EquivTypenums(PyArray_TYPE(Y), NPY_FLOAT32) ||
        !PyArray_EquivTypenums(PyArray_TYPE(B), NPY_FLOAT32)) {
        PyErr_SetString(PyExc_RuntimeError,errmsg);
        return 0;
    }
    MatrixXf mX = as_eigen(X);
    MatrixXf mY = as_eigen(Y);
    MatrixXf mB = as_eigen(B);
    max_iter *= mB.size();
    const int iters = coordinate_descent(mX, mY, mB, max_iter, lam, -1, eps);
    float* rB = static_cast<float*>(PyArray_DATA(B));
    for (int y = 0; y != mB.rows(); ++y) {
        for (int x = 0; x != mB.cols(); ++x) {
            *rB++ = mB(y,x);
        }

    }

    return Py_BuildValue("i", iters);
}

PyMethodDef methods[] = {
  {"lasso", py_lasso, METH_VARARGS , "Do NOT call directly.\n" },
  {NULL, NULL,0,NULL},
};

const char  * module_doc =
    "Internal Module.\n"
    "\n"
    "Do NOT use directly!\n";

} // namespace

extern "C"
void init_lasso()
  {
    import_array();
    (void)Py_InitModule3("_lasso", methods, module_doc);
  }

<commit_msg>RFCT Make Lasso use a solver class<commit_after>// Copyright (C) 2012, Luis Pedro Coelho <luis@luispedro.org>
// License: MIT

#include <iostream>
#include <memory>
#include <cmath>
#include <random>
#include <cassert>
#include <eigen3/Eigen/Dense>

using namespace Eigen;

extern "C" {
    #include <Python.h>
    #include <numpy/ndarrayobject.h>
}

namespace {

template <typename T>
int random_int(T& random, const int max) {
    std::uniform_int_distribution<int> dist(0, max - 1);
    return dist(random);
}
inline
float soft(float val, float lam) {
    return copysign(fdim(fabs(val), lam), val);
}
struct lasso_solver {
    lasso_solver(const MatrixXf& X, const MatrixXf& Y, MatrixXf& B, const int max_iter, const float lam, int maxnops=-1, const float eps=1e-15)
        :X(X)
        ,Y(Y)
        ,B(B)
        ,max_iter(max_iter)
        ,maxnops(maxnops == -1 ? 2*B.size() : maxnops)
        ,lam(lam)
        ,eps(eps)
        { }

    void next_coords(int& i, int& j) {
        ++j;
        if (j == B.cols()) {
            j = 0;
            ++i;
            if (i == B.rows()) i = 0;
        }
    }

    int solve() {
        MatrixXf residuals = Y - B*X;
        int nops = 0;
        int i = 0;
        int j = -1;
        for (int it = 0; it != max_iter; ++it) {
            this->next_coords(i, j);
            // Given everything else as fixed, this comes down to a very simple
            // 1-dimensional problem. We remember the current value:
            const float prev = B(i,j);
            float xy = 0.0;
            float x2 = 0.0;
            for (int k = 0; k != Y.cols(); ++k) {
                if (isnan(Y(i,k))) continue;
                x2 += X(j,k)*X(j,k);
                xy += X(j,k)*residuals(i,k);
            }
            const float step = (x2 == 0. ? 0. : (xy/x2));
            const float best = soft(prev + step, lam);
            if (fabs(best - prev) < eps) {
                ++nops;
                if (nops > maxnops) return it;
            } else {
                assert(!isnan(best));
                nops = 0;
                B(i,j) = best;
                // This is slow, but whatever
                residuals = Y - B*X;
            }
        }
        return max_iter;
    }
    std::mt19937 r;
    const MatrixXf& X;
    const MatrixXf& Y;
    MatrixXf& B;
    const int max_iter;
    const int maxnops;
    const float lam;
    const float eps;
};

Map<MatrixXf> as_eigen(PyArrayObject* arr) {
    assert(PyArray_EquivTypenums(PyArray_TYPE(arr), NPY_FLOAT32));
    return Map<MatrixXf>(
                    static_cast<float*>(PyArray_DATA(arr)),
                    PyArray_DIM(arr, 0),
                    PyArray_DIM(arr, 1));
}

const char* errmsg = "INTERNAL ERROR";
PyObject* py_lasso(PyObject* self, PyObject* args) {
    PyArrayObject* Y;
    PyArrayObject* X;
    PyArrayObject* B;
    int max_iter;
    float lam;
    float eps;
    if (!PyArg_ParseTuple(args, "OOOiff", &X, &Y, &B, &max_iter, &lam, &eps)) return NULL;
    if (!PyArray_Check(X) || //!PyArray_ISCARRAY_RO(X) ||
        !PyArray_Check(Y) || //!PyArray_ISCARRAY_RO(Y) ||
        !PyArray_Check(B) || //!PyArray_ISCARRAY(B) ||
        !PyArray_EquivTypenums(PyArray_TYPE(X), NPY_FLOAT32) ||
        !PyArray_EquivTypenums(PyArray_TYPE(Y), NPY_FLOAT32) ||
        !PyArray_EquivTypenums(PyArray_TYPE(B), NPY_FLOAT32)) {
        PyErr_SetString(PyExc_RuntimeError,errmsg);
        return 0;
    }
    MatrixXf mX = as_eigen(X);
    MatrixXf mY = as_eigen(Y);
    MatrixXf mB = as_eigen(B);
    max_iter *= mB.size();
    lasso_solver solver(mX, mY, mB, max_iter, lam, -1, eps);
    const int iters = solver.solve();
    float* rB = static_cast<float*>(PyArray_DATA(B));
    for (int y = 0; y != mB.rows(); ++y) {
        for (int x = 0; x != mB.cols(); ++x) {
            *rB++ = mB(y,x);
        }

    }

    return Py_BuildValue("i", iters);
}

PyMethodDef methods[] = {
  {"lasso", py_lasso, METH_VARARGS , "Do NOT call directly.\n" },
  {NULL, NULL,0,NULL},
};

const char  * module_doc =
    "Internal Module.\n"
    "\n"
    "Do NOT use directly!\n";

} // namespace

extern "C"
void init_lasso()
  {
    import_array();
    (void)Py_InitModule3("_lasso", methods, module_doc);
  }

<|endoftext|>


<commit_before>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

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

*/

#include "file/path.h"
#include "file/dicom/element.h"
#include "get_set.h"
#include "debug.h"

namespace MR {
  namespace File {
    namespace Dicom {

      void Element::set (const std::string& filename, bool force_read, bool read_write)
      {
        group = element = VR = 0;
        size = 0;
        start = data = next = NULL;
        is_BE = is_transfer_syntax_BE = false;
        parents.clear();

        fmap = new File::MMap (filename, read_write);

        if (fmap->size() < 256)
          throw Exception ("\"" + fmap->name() + "\" is too small to be a valid DICOM file");

        next = fmap->address();

        if (memcmp (next + 128, "DICM", 4)) {
          is_explicit = false;
          DEBUG ("DICOM magic number not found in file \"" + fmap->name() + "\" - trying truncated format");
          if (!force_read)
            if (!Path::has_suffix (fmap->name(), ".dcm"))
              throw Exception ("file \"" + fmap->name() + "\" does not have the DICOM magic number or the .dcm extension - assuming not DICOM");
        }
        else next += 132;

        try { set_explicit_encoding(); }
        catch (Exception) {
          throw Exception ("\"" + fmap->name() + "\" is not a valid DICOM file");
          fmap = NULL;
        }
      }

      void Element::set_explicit_encoding ()
      {
        assert (fmap);
        if (read_GR_EL())
          throw Exception ("\"" + fmap->name() + "\" is too small to be DICOM");

        is_explicit = true;
        next = start;
        VR = ByteOrder::BE (*reinterpret_cast<uint16_t*> (start+4));

        if ((VR == VR_OB) | (VR == VR_OW) | (VR == VR_OF) | (VR == VR_SQ) |
            (VR == VR_UN) | (VR == VR_AE) | (VR == VR_AS) | (VR == VR_AT) |
            (VR == VR_CS) | (VR == VR_DA) | (VR == VR_DS) | (VR == VR_DT) |
            (VR == VR_FD) | (VR == VR_FL) | (VR == VR_IS) | (VR == VR_LO) |
            (VR == VR_LT) | (VR == VR_PN) | (VR == VR_SH) | (VR == VR_SL) |
            (VR == VR_SS) | (VR == VR_ST) | (VR == VR_TM) | (VR == VR_UI) |
            (VR == VR_UL) | (VR == VR_US) | (VR == VR_UT)) return;

        DEBUG ("using implicit DICOM encoding");
        is_explicit = false;
      }

      bool Element::read_GR_EL ()
      {
        group = element = VR = 0;
        size = 0;
        start = next;
        data = next = NULL;

        if (start < fmap->address())
          throw Exception ("invalid DICOM element");

        if (start + 8 > fmap->address() + fmap->size())
          return true;

        is_BE = is_transfer_syntax_BE;

        group = get<uint16_t> (start, is_BE);

        if (group == GROUP_BYTE_ORDER_SWAPPED) {
          if (!is_BE)
            throw Exception ("invalid DICOM group ID " + str (group) + " in file \"" + fmap->name() + "\"");

          is_BE = false;
          group = GROUP_BYTE_ORDER;
        }
        element = get<uint16_t> (start+2, is_BE);

        return false;
      }

      bool Element::read ()
      {
        if (read_GR_EL())
          return false;

        data = start + 8;
        if ((is_explicit && group != GROUP_SEQUENCE) || group == GROUP_BYTE_ORDER) {

          // explicit encoding:
          VR = ByteOrder::BE (*reinterpret_cast<uint16_t*> (start+4));
          if (VR == VR_OB || VR == VR_OW || VR == VR_OF || VR == VR_SQ || VR == VR_UN || VR == VR_UT) {
            size = get<uint32_t> (start+8, is_BE);
            data += 4;
          }
          else size = get<uint16_t> (start+6, is_BE);

        }
        else {

          // implicit encoding:
          std::string name = tag_name();
          if (!name.size()) {
            if (group%2 == 0)
              DEBUG (printf ("WARNING: unknown DICOM tag (%02X %02X) "
                    "with implicit encoding in file \"", group, element)
                  + fmap->name() + "\"");
            VR = VR_UN;
          }
          else {
            union {
              char t[2];
              uint16_t i;
            } d = { { name[0], name[1] } };
            VR = ByteOrder::BE (d.i);
          }
          size = get<uint32_t> (start+4, is_BE);
        }

        next = data;
        if (size == LENGTH_UNDEFINED) {
          if (VR != VR_SQ && !(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_ITEM))
            throw Exception ("undefined length used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
                + " (" + str (group) + ", " + str (element)
                + ") in file \"" + fmap->name() + "\"");
        }
        else if (next+size > fmap->address() + fmap->size())
          throw Exception ("file \"" + fmap->name() + "\" is too small to contain DICOM elements specified");
        else if (size%2)
          throw Exception ("odd length (" + str (size) + ") used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
              + " (" + str (group) + ", " + str (element) + ") in file \"" + fmap->name() + "");
        else if (VR != VR_SQ && ( group != GROUP_SEQUENCE || element != ELEMENT_SEQUENCE_ITEM ) )
          next += size;

        if (parents.size())
          if ((parents.back().end && data > parents.back().end) ||
              (group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_DELIMITATION_ITEM))
            parents.pop_back();

        if (VR == VR_SQ) {
          if (size == LENGTH_UNDEFINED)
            parents.push_back (Sequence (group, element, NULL));
          else
            parents.push_back (Sequence (group, element, data + size));
        }

        switch (group) {
          case GROUP_BYTE_ORDER:
            switch (element) {
              case ELEMENT_TRANSFER_SYNTAX_UID:
                if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.1", size) == 0) {
                  is_BE = is_transfer_syntax_BE = false; // explicit VR Little Endian
                  is_explicit = true;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.2", size) == 0) {
                  is_BE = is_transfer_syntax_BE = true; // Explicit VR Big Endian
                  is_explicit = true;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2", size) == 0) {
                  is_BE = is_transfer_syntax_BE = false; // Implicit VR Little Endian
                  is_explicit = false;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.1.99", size) == 0) {
                  throw Exception ("DICOM deflated explicit VR little endian transfer syntax not supported");
                }
                else WARN ("unknown DICOM transfer syntax: \"" + std::string (reinterpret_cast<const char*> (data), size)
                    + "\" in file \"" + fmap->name() + "\" - ignored");
                break;
            }

            break;
        }

        return true;
      }

      Element::Type Element::type () const
      {
        if (!VR) return INVALID;
        if (VR == VR_FD || VR == VR_FL) return FLOAT;
        if (VR == VR_SL || VR == VR_SS) return INT;
        if (VR == VR_UL || VR == VR_US) return UINT;
        if (VR == VR_SQ) return SEQ;
        if (VR == VR_AE || VR == VR_AS || VR == VR_CS || VR == VR_DA ||
            VR == VR_DS || VR == VR_DT || VR == VR_IS || VR == VR_LO ||
            VR == VR_LT || VR == VR_PN || VR == VR_SH || VR == VR_ST ||
            VR == VR_TM || VR == VR_UI || VR == VR_UT || VR == VR_AT) return STRING;
        return OTHER;
      }

      std::vector<int32_t> Element::get_int () const
      {
        std::vector<int32_t> V;
        if (VR == VR_SL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (int32_t))
            V.push_back (get<int32_t> (p, is_BE));
        else if (VR == VR_SS)
          for (const uint8_t* p = data; p < data + size; p += sizeof (int16_t))
            V.push_back (get<int16_t> (p, is_BE));
        else if (VR == VR_IS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++)
            V[n] = to<int32_t> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();

        return V;
      }

      std::vector<uint32_t> Element::get_uint () const
      {
        std::vector<uint32_t> V;
        if (VR == VR_UL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (uint32_t))
            V.push_back (get<uint32_t> (p, is_BE));
        else if (VR == VR_US)
          for (const uint8_t* p = data; p < data + size; p += sizeof (uint16_t))
            V.push_back (get<uint16_t> (p, is_BE));
        else if (VR == VR_IS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++) V[n] = to<uint32_t> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();
        return V;
      }

      std::vector<double> Element::get_float () const
      {
        std::vector<double> V;
        if (VR == VR_FD)
          for (const uint8_t* p = data; p < data + size; p += sizeof (float64))
            V.push_back (get<float64> (p, is_BE));
        else if (VR == VR_FL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (float32))
            V.push_back (get<float32> (p, is_BE));
        else if (VR == VR_DS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++)
            V[n] = to<double> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();
        return V;
      }

      std::vector<std::string> Element::get_string () const
      {
        if (VR == VR_AT) {
          std::vector<std::string> strings;
          strings.push_back (printf ("%02X %02X", get<uint16_t> (data, is_BE), get<uint16_t> (data+2, is_BE)));
          return strings;
        }

        std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
        for (std::vector<std::string>::iterator i = strings.begin(); i != strings.end(); ++i) {
          *i = strip (*i);
          replace (*i, '^', ' ');
        }
        return strings;
      }

      namespace {
        template <class T>
          inline void print_vec (const std::vector<T>& V)
          {
            for (size_t n = 0; n < V.size(); n++)
              fprintf (stdout, "%s ", str (V[n]).c_str());
          }
      }

      std::ostream& operator<< (std::ostream& stream, const Element& item)
      {
        const std::string& name (item.tag_name());

        stream << "[DCM] ";
        size_t indent = item.level() + ( item.VR == VR_SQ ? 0 : 1 );
        for (size_t i = 0; i < indent; i++)
          stream << "  ";
        if (item.VR == VR_SQ)
          stream << "+ ";
        else if (item.group == GROUP_SEQUENCE && item.element == ELEMENT_SEQUENCE_ITEM)
          stream << "- ";
        else
          stream << "  ";
        stream << printf ("%02X %02X ", item.group, item.element)
            + reinterpret_cast<const char*> (&item.VR)[1] + reinterpret_cast<const char*> (&item.VR)[0] + " "
            + str ( item.size == LENGTH_UNDEFINED ? 0 : item.size ) + " "
            + str (item.offset (item.start)) + " " + ( name.size() ? name.substr (2) : "unknown" ) + " ";

        switch (item.type()) {
          case Element::INT:
            stream << item.get_int();
            break;
          case Element::UINT:
            stream << item.get_uint();
            break;
          case Element::FLOAT:
            stream << item.get_float();
            break;
          case Element::STRING:
            if (item.group == GROUP_DATA && item.element == ELEMENT_DATA)
              stream << "(data)";
            else
              stream << item.get_string();
            break;
          case Element::SEQ:
            break;
          default:
            if (item.group != GROUP_SEQUENCE || item.element != ELEMENT_SEQUENCE_ITEM)
              stream << "unknown data type";
        }
        if (item.group%2)
          stream << " [ PRIVATE ]";

        stream << "\n";

        return stream;
      }

    }
  }
}

<commit_msg>DICOM: issue debug message for unknown tag whether private or public<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

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

*/

#include "file/path.h"
#include "file/dicom/element.h"
#include "get_set.h"
#include "debug.h"

namespace MR {
  namespace File {
    namespace Dicom {

      void Element::set (const std::string& filename, bool force_read, bool read_write)
      {
        group = element = VR = 0;
        size = 0;
        start = data = next = NULL;
        is_BE = is_transfer_syntax_BE = false;
        parents.clear();

        fmap = new File::MMap (filename, read_write);

        if (fmap->size() < 256)
          throw Exception ("\"" + fmap->name() + "\" is too small to be a valid DICOM file");

        next = fmap->address();

        if (memcmp (next + 128, "DICM", 4)) {
          is_explicit = false;
          DEBUG ("DICOM magic number not found in file \"" + fmap->name() + "\" - trying truncated format");
          if (!force_read)
            if (!Path::has_suffix (fmap->name(), ".dcm"))
              throw Exception ("file \"" + fmap->name() + "\" does not have the DICOM magic number or the .dcm extension - assuming not DICOM");
        }
        else next += 132;

        try { set_explicit_encoding(); }
        catch (Exception) {
          throw Exception ("\"" + fmap->name() + "\" is not a valid DICOM file");
          fmap = NULL;
        }
      }

      void Element::set_explicit_encoding ()
      {
        assert (fmap);
        if (read_GR_EL())
          throw Exception ("\"" + fmap->name() + "\" is too small to be DICOM");

        is_explicit = true;
        next = start;
        VR = ByteOrder::BE (*reinterpret_cast<uint16_t*> (start+4));

        if ((VR == VR_OB) | (VR == VR_OW) | (VR == VR_OF) | (VR == VR_SQ) |
            (VR == VR_UN) | (VR == VR_AE) | (VR == VR_AS) | (VR == VR_AT) |
            (VR == VR_CS) | (VR == VR_DA) | (VR == VR_DS) | (VR == VR_DT) |
            (VR == VR_FD) | (VR == VR_FL) | (VR == VR_IS) | (VR == VR_LO) |
            (VR == VR_LT) | (VR == VR_PN) | (VR == VR_SH) | (VR == VR_SL) |
            (VR == VR_SS) | (VR == VR_ST) | (VR == VR_TM) | (VR == VR_UI) |
            (VR == VR_UL) | (VR == VR_US) | (VR == VR_UT)) return;

        DEBUG ("using implicit DICOM encoding");
        is_explicit = false;
      }

      bool Element::read_GR_EL ()
      {
        group = element = VR = 0;
        size = 0;
        start = next;
        data = next = NULL;

        if (start < fmap->address())
          throw Exception ("invalid DICOM element");

        if (start + 8 > fmap->address() + fmap->size())
          return true;

        is_BE = is_transfer_syntax_BE;

        group = get<uint16_t> (start, is_BE);

        if (group == GROUP_BYTE_ORDER_SWAPPED) {
          if (!is_BE)
            throw Exception ("invalid DICOM group ID " + str (group) + " in file \"" + fmap->name() + "\"");

          is_BE = false;
          group = GROUP_BYTE_ORDER;
        }
        element = get<uint16_t> (start+2, is_BE);

        return false;
      }

      bool Element::read ()
      {
        if (read_GR_EL())
          return false;

        data = start + 8;
        if ((is_explicit && group != GROUP_SEQUENCE) || group == GROUP_BYTE_ORDER) {

          // explicit encoding:
          VR = ByteOrder::BE (*reinterpret_cast<uint16_t*> (start+4));
          if (VR == VR_OB || VR == VR_OW || VR == VR_OF || VR == VR_SQ || VR == VR_UN || VR == VR_UT) {
            size = get<uint32_t> (start+8, is_BE);
            data += 4;
          }
          else size = get<uint16_t> (start+6, is_BE);

        }
        else {

          // implicit encoding:
          std::string name = tag_name();
          if (!name.size()) {
            DEBUG (printf ("WARNING: unknown DICOM tag (%02X %02X) "
                  "with implicit encoding in file \"", group, element)
                + fmap->name() + "\"");
            VR = VR_UN;
          }
          else {
            union {
              char t[2];
              uint16_t i;
            } d = { { name[0], name[1] } };
            VR = ByteOrder::BE (d.i);
          }
          size = get<uint32_t> (start+4, is_BE);
        }

        next = data;
        if (size == LENGTH_UNDEFINED) {
          if (VR != VR_SQ && !(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_ITEM))
            throw Exception ("undefined length used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
                + " (" + str (group) + ", " + str (element)
                + ") in file \"" + fmap->name() + "\"");
        }
        else if (next+size > fmap->address() + fmap->size())
          throw Exception ("file \"" + fmap->name() + "\" is too small to contain DICOM elements specified");
        else if (size%2)
          throw Exception ("odd length (" + str (size) + ") used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
              + " (" + str (group) + ", " + str (element) + ") in file \"" + fmap->name() + "");
        else if (VR != VR_SQ && ( group != GROUP_SEQUENCE || element != ELEMENT_SEQUENCE_ITEM ) )
          next += size;

        if (parents.size())
          if ((parents.back().end && data > parents.back().end) ||
              (group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_DELIMITATION_ITEM))
            parents.pop_back();

        if (VR == VR_SQ) {
          if (size == LENGTH_UNDEFINED)
            parents.push_back (Sequence (group, element, NULL));
          else
            parents.push_back (Sequence (group, element, data + size));
        }

        switch (group) {
          case GROUP_BYTE_ORDER:
            switch (element) {
              case ELEMENT_TRANSFER_SYNTAX_UID:
                if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.1", size) == 0) {
                  is_BE = is_transfer_syntax_BE = false; // explicit VR Little Endian
                  is_explicit = true;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.2", size) == 0) {
                  is_BE = is_transfer_syntax_BE = true; // Explicit VR Big Endian
                  is_explicit = true;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2", size) == 0) {
                  is_BE = is_transfer_syntax_BE = false; // Implicit VR Little Endian
                  is_explicit = false;
                }
                else if (strncmp (reinterpret_cast<const char*> (data), "1.2.840.10008.1.2.1.99", size) == 0) {
                  throw Exception ("DICOM deflated explicit VR little endian transfer syntax not supported");
                }
                else WARN ("unknown DICOM transfer syntax: \"" + std::string (reinterpret_cast<const char*> (data), size)
                    + "\" in file \"" + fmap->name() + "\" - ignored");
                break;
            }

            break;
        }

        return true;
      }

      Element::Type Element::type () const
      {
        if (!VR) return INVALID;
        if (VR == VR_FD || VR == VR_FL) return FLOAT;
        if (VR == VR_SL || VR == VR_SS) return INT;
        if (VR == VR_UL || VR == VR_US) return UINT;
        if (VR == VR_SQ) return SEQ;
        if (VR == VR_AE || VR == VR_AS || VR == VR_CS || VR == VR_DA ||
            VR == VR_DS || VR == VR_DT || VR == VR_IS || VR == VR_LO ||
            VR == VR_LT || VR == VR_PN || VR == VR_SH || VR == VR_ST ||
            VR == VR_TM || VR == VR_UI || VR == VR_UT || VR == VR_AT) return STRING;
        return OTHER;
      }

      std::vector<int32_t> Element::get_int () const
      {
        std::vector<int32_t> V;
        if (VR == VR_SL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (int32_t))
            V.push_back (get<int32_t> (p, is_BE));
        else if (VR == VR_SS)
          for (const uint8_t* p = data; p < data + size; p += sizeof (int16_t))
            V.push_back (get<int16_t> (p, is_BE));
        else if (VR == VR_IS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++)
            V[n] = to<int32_t> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();

        return V;
      }

      std::vector<uint32_t> Element::get_uint () const
      {
        std::vector<uint32_t> V;
        if (VR == VR_UL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (uint32_t))
            V.push_back (get<uint32_t> (p, is_BE));
        else if (VR == VR_US)
          for (const uint8_t* p = data; p < data + size; p += sizeof (uint16_t))
            V.push_back (get<uint16_t> (p, is_BE));
        else if (VR == VR_IS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++) V[n] = to<uint32_t> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();
        return V;
      }

      std::vector<double> Element::get_float () const
      {
        std::vector<double> V;
        if (VR == VR_FD)
          for (const uint8_t* p = data; p < data + size; p += sizeof (float64))
            V.push_back (get<float64> (p, is_BE));
        else if (VR == VR_FL)
          for (const uint8_t* p = data; p < data + size; p += sizeof (float32))
            V.push_back (get<float32> (p, is_BE));
        else if (VR == VR_DS) {
          std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
          V.resize (strings.size());
          for (size_t n = 0; n < V.size(); n++)
            V[n] = to<double> (strings[n]);
        }
        else
          report_unknown_tag_with_implicit_syntax();
        return V;
      }

      std::vector<std::string> Element::get_string () const
      {
        if (VR == VR_AT) {
          std::vector<std::string> strings;
          strings.push_back (printf ("%02X %02X", get<uint16_t> (data, is_BE), get<uint16_t> (data+2, is_BE)));
          return strings;
        }

        std::vector<std::string> strings (split (std::string (reinterpret_cast<const char*> (data), size), "\\", false));
        for (std::vector<std::string>::iterator i = strings.begin(); i != strings.end(); ++i) {
          *i = strip (*i);
          replace (*i, '^', ' ');
        }
        return strings;
      }

      namespace {
        template <class T>
          inline void print_vec (const std::vector<T>& V)
          {
            for (size_t n = 0; n < V.size(); n++)
              fprintf (stdout, "%s ", str (V[n]).c_str());
          }
      }

      std::ostream& operator<< (std::ostream& stream, const Element& item)
      {
        const std::string& name (item.tag_name());

        stream << "[DCM] ";
        size_t indent = item.level() + ( item.VR == VR_SQ ? 0 : 1 );
        for (size_t i = 0; i < indent; i++)
          stream << "  ";
        if (item.VR == VR_SQ)
          stream << "+ ";
        else if (item.group == GROUP_SEQUENCE && item.element == ELEMENT_SEQUENCE_ITEM)
          stream << "- ";
        else
          stream << "  ";
        stream << printf ("%02X %02X ", item.group, item.element)
            + reinterpret_cast<const char*> (&item.VR)[1] + reinterpret_cast<const char*> (&item.VR)[0] + " "
            + str ( item.size == LENGTH_UNDEFINED ? 0 : item.size ) + " "
            + str (item.offset (item.start)) + " " + ( name.size() ? name.substr (2) : "unknown" ) + " ";

        switch (item.type()) {
          case Element::INT:
            stream << item.get_int();
            break;
          case Element::UINT:
            stream << item.get_uint();
            break;
          case Element::FLOAT:
            stream << item.get_float();
            break;
          case Element::STRING:
            if (item.group == GROUP_DATA && item.element == ELEMENT_DATA)
              stream << "(data)";
            else
              stream << item.get_string();
            break;
          case Element::SEQ:
            break;
          default:
            if (item.group != GROUP_SEQUENCE || item.element != ELEMENT_SEQUENCE_ITEM)
              stream << "unknown data type";
        }
        if (item.group%2)
          stream << " [ PRIVATE ]";

        stream << "\n";

        return stream;
      }

    }
  }
}

<|endoftext|>


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

/**
 * memory.cc - Contains stub definition of C++ new/delete operators.
 *
 * These definitions are intended to be used for testing and are weak symbols
 * to allow them to be replaced by definitions from a STL implementation.
 * These versions simply wrap malloc() and free(), they do not provide a
 * C++-specific allocator.
 */

#include <stddef.h>
#include <stdlib.h>
#include "stdexcept.h"
#include "atomic.h"

namespace std
{
	struct nothrow_t {};
}

/// The type of the function called when allocation fails.
typedef void (*new_handler)();
/**
 * The function to call when allocation fails.  By default, there is no
 * handler and a bad allocation exception is thrown if an allocation fails.
 */
static new_handler new_handl;

namespace std
{
	/**
	 * Sets a function to be called when there is a failure in new.
	 */
	__attribute__((weak))
	new_handler set_new_handler(new_handler handler)
	{
		return ATOMIC_SWAP(&new_handl, handler);
	}
	__attribute__((weak))
	new_handler get_new_handler(void)
	{
		return ATOMIC_LOAD(&new_handl);
	}
}

__attribute__((weak))
void* operator new(size_t size)
{
	if (0 == size)
	{
		size = 1;
	}
	void * mem = malloc(size);
	while (0 == mem)
	{
		new_handler h = std::get_new_handler();
		if (0 != h)
		{
			h();
		}
		else
		{
			throw std::bad_alloc();
		}
		mem = malloc(size);
	}

	return mem;
}

__attribute__((weak))
void* operator new(size_t size, const std::nothrow_t &) throw()
{
	try {
		return :: operator new(size);
	} catch (...) {
		// nothrow operator new should return NULL in case of
		// std::bad_alloc exception in new handler
		return NULL;
	}
}

__attribute__((weak))
void operator delete(void * ptr)
{
	free(ptr);
}

__attribute__((weak))
void * operator new[](size_t size)
{
	return ::operator new(size);
}

__attribute__((weak))
void * operator new[](size_t size, const std::nothrow_t &) throw()
{
	try {
		return ::operator new[](size);
	} catch (...) {
		// nothrow operator new should return NULL in case of
		// std::bad_alloc exception in new handler
		return NULL;
	}
}

__attribute__((weak))
void operator delete[](void * ptr) throw()
{
	::operator delete(ptr);
}

<commit_msg>Make exception specifications conditional on language dialect for new / delete operators (fixes warnings when compiling as C++11)<commit_after>/*
 * Copyright 2010-2011 PathScale, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * memory.cc - Contains stub definition of C++ new/delete operators.
 *
 * These definitions are intended to be used for testing and are weak symbols
 * to allow them to be replaced by definitions from a STL implementation.
 * These versions simply wrap malloc() and free(), they do not provide a
 * C++-specific allocator.
 */

#include <stddef.h>
#include <stdlib.h>
#include "stdexcept.h"
#include "atomic.h"

namespace std
{
	struct nothrow_t {};
}

/// The type of the function called when allocation fails.
typedef void (*new_handler)();
/**
 * The function to call when allocation fails.  By default, there is no
 * handler and a bad allocation exception is thrown if an allocation fails.
 */
static new_handler new_handl;

namespace std
{
	/**
	 * Sets a function to be called when there is a failure in new.
	 */
	__attribute__((weak))
	new_handler set_new_handler(new_handler handler)
	{
		return ATOMIC_SWAP(&new_handl, handler);
	}
	__attribute__((weak))
	new_handler get_new_handler(void)
	{
		return ATOMIC_LOAD(&new_handl);
	}
}

__attribute__((weak))
void* operator new(size_t size)
{
	if (0 == size)
	{
		size = 1;
	}
	void * mem = malloc(size);
	while (0 == mem)
	{
		new_handler h = std::get_new_handler();
		if (0 != h)
		{
			h();
		}
		else
		{
			throw std::bad_alloc();
		}
		mem = malloc(size);
	}

	return mem;
}

__attribute__((weak))
void* operator new(size_t size, const std::nothrow_t &) throw()
{
	try {
		return :: operator new(size);
	} catch (...) {
		// nothrow operator new should return NULL in case of
		// std::bad_alloc exception in new handler
		return NULL;
	}
}

__attribute__((weak))
void operator delete(void * ptr)
#if __cplusplus < 201000L
throw()
#endif
{
	free(ptr);
}

__attribute__((weak))
void * operator new[](size_t size)
#if __cplusplus < 201000L
throw(std::bad_alloc)
#endif
{
	return ::operator new(size);
}

__attribute__((weak))
void * operator new[](size_t size, const std::nothrow_t &) throw()
{
	try {
		return ::operator new[](size);
	} catch (...) {
		// nothrow operator new should return NULL in case of
		// std::bad_alloc exception in new handler
		return NULL;
	}
}

__attribute__((weak))
void operator delete[](void * ptr)
#if __cplusplus < 201000L
throw()
#endif
{
	::operator delete(ptr);
}

<|endoftext|>