<commit_before>#include "usb-mic-singstar.h"
#include "audio.h"
#include "../qemu-usb/desc.h"

#define DEVICENAME "logitech_usbmic"

namespace usb_mic_singstar {

static const uint8_t logitech_mic_dev_descriptor[] = {
    /* bLength             */ 0x12, //(18)
    /* bDescriptorType     */ 0x01, //(1)
    /* bcdUSB              */ WBVAL(0x0110), //(272)
    /* bDeviceClass        */ 0x00, //(0)
    /* bDeviceSubClass     */ 0x00, //(0)
    /* bDeviceProtocol     */ 0x00, //(0)
    /* bMaxPacketSize0     */ 0x08, //(8)
    /* idVendor            */ WBVAL(0x046D),
    /* idProduct           */ WBVAL(0x0000), //(0)
    /* bcdDevice           */ WBVAL(0x0001), //(1)
    /* iManufacturer       */ 0x01, //(1)
    /* iProduct            */ 0x02, //(2)
    /* iSerialNumber       */ 0x00, //(0) unused
    /* bNumConfigurations  */ 0x01, //(1)

};

static const uint8_t logitech_mic_config_descriptor[] = {

    /* Configuration 1 */
    0x09,   /* bLength */
    USB_CONFIGURATION_DESCRIPTOR_TYPE,    /* bDescriptorType */
    WBVAL(0x00b1),                        /* wTotalLength */
    0x02,                                 /* bNumInterfaces */
    0x01,                                 /* bConfigurationValue */
    0x00,                                 /* iConfiguration */
    USB_CONFIG_BUS_POWERED,               /* bmAttributes */
    USB_CONFIG_POWER_MA(90),              /* bMaxPower */

                                          /* Interface 0, Alternate Setting 0, Audio Control */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x00,                                 /* bInterfaceNumber */
    0x00,                                 /* bAlternateSetting */
    0x00,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOCONTROL,          /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Control Interface */
    AUDIO_CONTROL_INTERFACE_DESC_SZ(1),   /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_HEADER,                 /* bDescriptorSubtype */
    WBVAL(0x0100), /* 1.00 */             /* bcdADC */
    WBVAL(0x0028),                        /* wTotalLength */
    0x01,                                 /* bInCollection */
    0x01,                                 /* baInterfaceNr */

                                          /* Audio Input Terminal */
    AUDIO_INPUT_TERMINAL_DESC_SIZE,       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_INPUT_TERMINAL,         /* bDescriptorSubtype */
    0x01,                                 /* bTerminalID */
    WBVAL(AUDIO_TERMINAL_MICROPHONE),     /* wTerminalType */
    0x02,                                 /* bAssocTerminal */
    0x02,                                 /* bNrChannels */
    WBVAL(AUDIO_CHANNEL_L
        | AUDIO_CHANNEL_R),				/* wChannelConfig */
    0x00,                                 /* iChannelNames */
    0x00,                                 /* iTerminal */

                                          /* Audio Output Terminal */
    AUDIO_OUTPUT_TERMINAL_DESC_SIZE,      /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_OUTPUT_TERMINAL,        /* bDescriptorSubtype */
    0x02,                                 /* bTerminalID */
    WBVAL(AUDIO_TERMINAL_USB_STREAMING),  /* wTerminalType */
    0x01,                                 /* bAssocTerminal */
    0x03,                                 /* bSourceID */
    0x00,                                 /* iTerminal */

                                          /* Audio Feature Unit */
    AUDIO_FEATURE_UNIT_DESC_SZ(2,1),      /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_FEATURE_UNIT,           /* bDescriptorSubtype */
    0x03,                                 /* bUnitID */
    0x01,                                 /* bSourceID */
    0x01,                                 /* bControlSize */
    0x01,                                 /* bmaControls(0) */
    0x02,                                 /* bmaControls(1) */
    0x02,                                 /* bmaControls(2) */
    0x00,                                 /* iTerminal */

                                          /* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x00,                                 /* bAlternateSetting */
    0x00,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x01,                                 /* bAlternateSetting */
    0x01,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Streaming Interface */
    AUDIO_STREAMING_INTERFACE_DESC_SIZE,  /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_GENERAL,              /* bDescriptorSubtype */
    0x02,                                 /* bTerminalLink */
    0x01,                                 /* bDelay */
    WBVAL(AUDIO_FORMAT_PCM),              /* wFormatTag */

                                          /* Audio Type I Format */
    AUDIO_FORMAT_TYPE_I_DESC_SZ(5),       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */
    AUDIO_FORMAT_TYPE_I,                  /* bFormatType */
    0x01,                                 /* bNrChannels */
    0x02,                                 /* bSubFrameSize */
    0x10,                                 /* bBitResolution */
    0x05,                                 /* bSamFreqType */
    B3VAL(8000),                          /* tSamFreq 1 */
    B3VAL(11025),                         /* tSamFreq 2 */
    B3VAL(22050),                         /* tSamFreq 3 */
    B3VAL(44100),                         /* tSamFreq 4 */
    B3VAL(48000),                         /* tSamFreq 5 */

                                          /* Endpoint - Standard Descriptor */
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
    USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
    USB_ENDPOINT_IN(1),                   /* bEndpointAddress */
    USB_ENDPOINT_TYPE_ISOCHRONOUS
    | USB_ENDPOINT_SYNC_ASYNCHRONOUS,     /* bmAttributes */
    WBVAL(0x0064),                        /* wMaxPacketSize */
    0x01,                                 /* bInterval */
    0x00,                                 /* bRefresh */
    0x00,                                 /* bSynchAddress */

                                          /* Endpoint - Audio Streaming */
    AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
    AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
    AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
    0x01,                                 /* bmAttributes */
    0x00,                                 /* bLockDelayUnits */
    WBVAL(0x0000),                        /* wLockDelay */

                                          /* Interface 1, Alternate Setting 2, Audio Streaming - ? */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x02,                                 /* bAlternateSetting */
    0x01,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Streaming Interface */
    AUDIO_STREAMING_INTERFACE_DESC_SIZE,  /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_GENERAL,              /* bDescriptorSubtype */
    0x02,                                 /* bTerminalLink */
    0x01,                                 /* bDelay */
    WBVAL(AUDIO_FORMAT_PCM),              /* wFormatTag */

                                          /* Audio Type I Format */
    AUDIO_FORMAT_TYPE_I_DESC_SZ(5),       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */
    AUDIO_FORMAT_TYPE_I,                  /* bFormatType */
    0x02,                                 /* bNrChannels */
    0x02,                                 /* bSubFrameSize */
    0x10,                                 /* bBitResolution */
    0x05,                                 /* bSamFreqType */
    B3VAL(8000),                          /* tSamFreq 1 */
    B3VAL(11025),                         /* tSamFreq 2 */
    B3VAL(22050),                         /* tSamFreq 3 */
    B3VAL(44100),                         /* tSamFreq 4 */
    B3VAL(48000),                         /* tSamFreq 5 */

                                          /* Endpoint - Standard Descriptor */
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
    USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
    USB_ENDPOINT_IN(1),                   /* bEndpointAddress */
    USB_ENDPOINT_TYPE_ISOCHRONOUS
    | USB_ENDPOINT_SYNC_ASYNCHRONOUS,     /* bmAttributes */
    WBVAL(0x00c8),                        /* wMaxPacketSize */
    0x01,                                 /* bInterval */
    0x00,                                 /* bRefresh */
    0x00,                                 /* bSynchAddress */

                                          /* Endpoint - Audio Streaming */
    AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
    AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
    AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
    0x01,                                 /* bmAttributes */
    0x00,                                 /* bLockDelayUnits */
    WBVAL(0x0000),                        /* wLockDelay */

                                          /* Terminator */
    0                                     /* bLength */
};

static const USBDescStrings lt_desc_strings = {
    "",
    "Logitech",
    "USBMIC",
};

//Minified state
typedef struct SINGSTARMICMINIState {
    USBDevice dev;

    USBDesc desc;
    USBDescDevice desc_dev;
} SINGSTARMICMINIState;

class LogitechMicDevice : public SingstarDevice
{
public:
	virtual ~LogitechMicDevice() {}
	static USBDevice* CreateDevice(int port)
	{
		std::string api;
		{
			CONFIGVARIANT var(N_DEVICE_API, CONFIG_TYPE_CHAR);
			if (LoadSetting(port, DEVICENAME, var))
				api = var.strValue;
		}

		USBDevice* dev = SingstarDevice::CreateDevice(port, api);
		if (!dev)
			return NULL;

		SINGSTARMICMINIState *s = (SINGSTARMICMINIState *)dev;
		s->desc = {};
		s->desc_dev = {};

		s->desc.str = lt_desc_strings;
		if (usb_desc_parse_dev (logitech_mic_dev_descriptor, sizeof(logitech_mic_dev_descriptor), s->desc, s->desc_dev) < 0)
			goto fail;
		if (usb_desc_parse_config (logitech_mic_config_descriptor, sizeof(logitech_mic_config_descriptor), s->desc_dev) < 0)
			goto fail;

		s->dev.klass.usb_desc       = &s->desc;
		s->dev.klass.product_desc   = lt_desc_strings[2];
		usb_desc_init(&s->dev);
		return dev;
fail:
		s->dev.klass.unrealize (dev);
		return NULL;
	}
	static const char* TypeName()
	{
		return DEVICENAME;
	}
	static const TCHAR* Name()
	{
		return TEXT("Logitech USB Mic");
	}
};

REGISTER_DEVICE(DEVTYPE_LOGITECH_MIC, DEVICENAME, LogitechMicDevice);
};
#undef DEVICENAME<commit_msg>logitech-mic: fix nullptr error caused by full speed device variable being reset too<commit_after>#include "usb-mic-singstar.h"
#include "audio.h"
#include "../qemu-usb/desc.h"

#define DEVICENAME "logitech_usbmic"

namespace usb_mic_singstar {

static const uint8_t logitech_mic_dev_descriptor[] = {
    /* bLength             */ 0x12, //(18)
    /* bDescriptorType     */ 0x01, //(1)
    /* bcdUSB              */ WBVAL(0x0110), //(272)
    /* bDeviceClass        */ 0x00, //(0)
    /* bDeviceSubClass     */ 0x00, //(0)
    /* bDeviceProtocol     */ 0x00, //(0)
    /* bMaxPacketSize0     */ 0x08, //(8)
    /* idVendor            */ WBVAL(0x046D),
    /* idProduct           */ WBVAL(0x0000), //(0)
    /* bcdDevice           */ WBVAL(0x0001), //(1)
    /* iManufacturer       */ 0x01, //(1)
    /* iProduct            */ 0x02, //(2)
    /* iSerialNumber       */ 0x00, //(0) unused
    /* bNumConfigurations  */ 0x01, //(1)

};

static const uint8_t logitech_mic_config_descriptor[] = {

    /* Configuration 1 */
    0x09,   /* bLength */
    USB_CONFIGURATION_DESCRIPTOR_TYPE,    /* bDescriptorType */
    WBVAL(0x00b1),                        /* wTotalLength */
    0x02,                                 /* bNumInterfaces */
    0x01,                                 /* bConfigurationValue */
    0x00,                                 /* iConfiguration */
    USB_CONFIG_BUS_POWERED,               /* bmAttributes */
    USB_CONFIG_POWER_MA(90),              /* bMaxPower */

                                          /* Interface 0, Alternate Setting 0, Audio Control */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x00,                                 /* bInterfaceNumber */
    0x00,                                 /* bAlternateSetting */
    0x00,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOCONTROL,          /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Control Interface */
    AUDIO_CONTROL_INTERFACE_DESC_SZ(1),   /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_HEADER,                 /* bDescriptorSubtype */
    WBVAL(0x0100), /* 1.00 */             /* bcdADC */
    WBVAL(0x0028),                        /* wTotalLength */
    0x01,                                 /* bInCollection */
    0x01,                                 /* baInterfaceNr */

                                          /* Audio Input Terminal */
    AUDIO_INPUT_TERMINAL_DESC_SIZE,       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_INPUT_TERMINAL,         /* bDescriptorSubtype */
    0x01,                                 /* bTerminalID */
    WBVAL(AUDIO_TERMINAL_MICROPHONE),     /* wTerminalType */
    0x02,                                 /* bAssocTerminal */
    0x02,                                 /* bNrChannels */
    WBVAL(AUDIO_CHANNEL_L
        | AUDIO_CHANNEL_R),				/* wChannelConfig */
    0x00,                                 /* iChannelNames */
    0x00,                                 /* iTerminal */

                                          /* Audio Output Terminal */
    AUDIO_OUTPUT_TERMINAL_DESC_SIZE,      /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_OUTPUT_TERMINAL,        /* bDescriptorSubtype */
    0x02,                                 /* bTerminalID */
    WBVAL(AUDIO_TERMINAL_USB_STREAMING),  /* wTerminalType */
    0x01,                                 /* bAssocTerminal */
    0x03,                                 /* bSourceID */
    0x00,                                 /* iTerminal */

                                          /* Audio Feature Unit */
    AUDIO_FEATURE_UNIT_DESC_SZ(2,1),      /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_CONTROL_FEATURE_UNIT,           /* bDescriptorSubtype */
    0x03,                                 /* bUnitID */
    0x01,                                 /* bSourceID */
    0x01,                                 /* bControlSize */
    0x01,                                 /* bmaControls(0) */
    0x02,                                 /* bmaControls(1) */
    0x02,                                 /* bmaControls(2) */
    0x00,                                 /* iTerminal */

                                          /* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x00,                                 /* bAlternateSetting */
    0x00,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x01,                                 /* bAlternateSetting */
    0x01,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Streaming Interface */
    AUDIO_STREAMING_INTERFACE_DESC_SIZE,  /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_GENERAL,              /* bDescriptorSubtype */
    0x02,                                 /* bTerminalLink */
    0x01,                                 /* bDelay */
    WBVAL(AUDIO_FORMAT_PCM),              /* wFormatTag */

                                          /* Audio Type I Format */
    AUDIO_FORMAT_TYPE_I_DESC_SZ(5),       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */
    AUDIO_FORMAT_TYPE_I,                  /* bFormatType */
    0x01,                                 /* bNrChannels */
    0x02,                                 /* bSubFrameSize */
    0x10,                                 /* bBitResolution */
    0x05,                                 /* bSamFreqType */
    B3VAL(8000),                          /* tSamFreq 1 */
    B3VAL(11025),                         /* tSamFreq 2 */
    B3VAL(22050),                         /* tSamFreq 3 */
    B3VAL(44100),                         /* tSamFreq 4 */
    B3VAL(48000),                         /* tSamFreq 5 */

                                          /* Endpoint - Standard Descriptor */
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
    USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
    USB_ENDPOINT_IN(1),                   /* bEndpointAddress */
    USB_ENDPOINT_TYPE_ISOCHRONOUS
    | USB_ENDPOINT_SYNC_ASYNCHRONOUS,     /* bmAttributes */
    WBVAL(0x0064),                        /* wMaxPacketSize */
    0x01,                                 /* bInterval */
    0x00,                                 /* bRefresh */
    0x00,                                 /* bSynchAddress */

                                          /* Endpoint - Audio Streaming */
    AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
    AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
    AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
    0x01,                                 /* bmAttributes */
    0x00,                                 /* bLockDelayUnits */
    WBVAL(0x0000),                        /* wLockDelay */

                                          /* Interface 1, Alternate Setting 2, Audio Streaming - ? */
    USB_INTERFACE_DESC_SIZE,              /* bLength */
    USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
    0x01,                                 /* bInterfaceNumber */
    0x02,                                 /* bAlternateSetting */
    0x01,                                 /* bNumEndpoints */
    USB_CLASS_AUDIO,                      /* bInterfaceClass */
    AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
    AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
    0x00,                                 /* iInterface */

                                          /* Audio Streaming Interface */
    AUDIO_STREAMING_INTERFACE_DESC_SIZE,  /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_GENERAL,              /* bDescriptorSubtype */
    0x02,                                 /* bTerminalLink */
    0x01,                                 /* bDelay */
    WBVAL(AUDIO_FORMAT_PCM),              /* wFormatTag */

                                          /* Audio Type I Format */
    AUDIO_FORMAT_TYPE_I_DESC_SZ(5),       /* bLength */
    AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
    AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */
    AUDIO_FORMAT_TYPE_I,                  /* bFormatType */
    0x02,                                 /* bNrChannels */
    0x02,                                 /* bSubFrameSize */
    0x10,                                 /* bBitResolution */
    0x05,                                 /* bSamFreqType */
    B3VAL(8000),                          /* tSamFreq 1 */
    B3VAL(11025),                         /* tSamFreq 2 */
    B3VAL(22050),                         /* tSamFreq 3 */
    B3VAL(44100),                         /* tSamFreq 4 */
    B3VAL(48000),                         /* tSamFreq 5 */

                                          /* Endpoint - Standard Descriptor */
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
    USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
    USB_ENDPOINT_IN(1),                   /* bEndpointAddress */
    USB_ENDPOINT_TYPE_ISOCHRONOUS
    | USB_ENDPOINT_SYNC_ASYNCHRONOUS,     /* bmAttributes */
    WBVAL(0x00c8),                        /* wMaxPacketSize */
    0x01,                                 /* bInterval */
    0x00,                                 /* bRefresh */
    0x00,                                 /* bSynchAddress */

                                          /* Endpoint - Audio Streaming */
    AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
    AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
    AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
    0x01,                                 /* bmAttributes */
    0x00,                                 /* bLockDelayUnits */
    WBVAL(0x0000),                        /* wLockDelay */

                                          /* Terminator */
    0                                     /* bLength */
};

static const USBDescStrings lt_desc_strings = {
    "",
    "Logitech",
    "USBMIC",
};

//Minified state
typedef struct SINGSTARMICMINIState {
    USBDevice dev;

    USBDesc desc;
    USBDescDevice desc_dev;
} SINGSTARMICMINIState;

class LogitechMicDevice : public SingstarDevice
{
public:
	virtual ~LogitechMicDevice() {}
	static USBDevice* CreateDevice(int port)
	{
		std::string api;
		{
			CONFIGVARIANT var(N_DEVICE_API, CONFIG_TYPE_CHAR);
			if (LoadSetting(port, DEVICENAME, var))
				api = var.strValue;
		}

		USBDevice* dev = SingstarDevice::CreateDevice(port, api);
		if (!dev)
			return NULL;

		SINGSTARMICMINIState *s = (SINGSTARMICMINIState *)dev;
		const USBDescDevice *full = s->desc.full;
		s->desc = {};
		s->desc_dev = {};

		s->desc.str = lt_desc_strings;
		s->desc.full = &s->desc_dev;

		if (usb_desc_parse_dev (logitech_mic_dev_descriptor, sizeof(logitech_mic_dev_descriptor), s->desc, s->desc_dev) < 0)
			goto fail;
		if (usb_desc_parse_config (logitech_mic_config_descriptor, sizeof(logitech_mic_config_descriptor), s->desc_dev) < 0)
			goto fail;

		s->dev.klass.usb_desc       = &s->desc;
		s->dev.klass.product_desc   = lt_desc_strings[2];
		usb_desc_init(&s->dev);
		return dev;
fail:
		s->dev.klass.unrealize (dev);
		return NULL;
	}
	static const char* TypeName()
	{
		return DEVICENAME;
	}
	static const TCHAR* Name()
	{
		return TEXT("Logitech USB Mic");
	}
};

REGISTER_DEVICE(DEVTYPE_LOGITECH_MIC, DEVICENAME, LogitechMicDevice);
};
#undef DEVICENAME<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2010 Benjamin Close <Benjamin.Close@clearchain.com>
 * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <iostream>
#include "VirtualCamera.h"

#define guint int
#define guint8 const char *
#include "VirtualCameraDefaultImage.c"

using namespace std;

namespace wcl
{

CameraBuffer VirtualCamera::defaultBuffer;

VirtualCamera::VirtualCamera()
{
    if(VirtualCamera::defaultBuffer.start==NULL){
	VirtualCamera::defaultBuffer.start=(void *)gimp_image.pixel_data[0]; // NOTE: CONST LOST
	VirtualCamera::defaultBuffer.length=sizeof(gimp_image.pixel_data)/sizeof(gimp_image.pixel_data[0]);
    }

    Camera::setFormat(Camera::RGB8,640,480);
}

VirtualCamera::~VirtualCamera()
{}

void VirtualCamera::printDetails()
{
    cout << "WCL Virtual Camera" << endl;
    if ( this->buffers ){
	cout << "Using Provided Frames" << endl;
	cout << "| Current Frame: " << inUseBuffer << endl;
	cout << "| Total Frames: " << this->numBuffers << endl;
    } else {

	cout << "Using Default Frame" << endl;
    }
}

void VirtualCamera::setFormat(const ImageFormat f, const unsigned width, const unsigned height)
{
    cout << "VirtualCamera: SetFormat Called - not Virtual Camera only supports RGB" << endl;
}

void VirtualCamera::setExposureMode(const ExposureMode t)
{
    cout << "VirtualCamera: Confirming Exposure Mode change "
	 << "(Note: No change to the image will occur)" << endl;
}

void VirtualCamera::setControlValue(const Control control, const int value)
{
    cout << "VirtualCamera: Confirming control " << control << "Set to value "
	 << value << "(Note: No change to the image will occur)" << endl;
}

const unsigned char* VirtualCamera::getFrame()
{
    if( this->buffers ){
	const unsigned char *frame =
	   (const unsigned char *) this->buffers[this->inUseBuffer].start;
	this->inUseBuffer++;
	if( this->inUseBuffer > this->numBuffers){
	    this->inUseBuffer = 0;
	}
	return frame;
    }
    return (const unsigned char *)defaultBuffer.start;
}

void VirtualCamera::startup()
{}

void VirtualCamera::shutdown()
{
    this->buffers=NULL;
    this->inUseBuffer=0;
    this->numBuffers=0;

    //Reset the default format, size for the default image
    Camera::setFormat(Camera::RGB8,640,480);
}

void VirtualCamera::setFrames(const CameraBuffer *buffers, const unsigned bufferCount)
{
    this->buffers=const_cast<CameraBuffer *>(buffers); //NOTE: cost removed, though the buffer is still treated as read only internally
    this->numBuffers = bufferCount;
    this->inUseBuffer=0;
}

}; //namespace wcl
<commit_msg>camera: Support changing the virtual camera format if a buffer has been speficied<commit_after>/*-
 * Copyright (c) 2010 Benjamin Close <Benjamin.Close@clearchain.com>
 * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <iostream>
#include "VirtualCamera.h"

#define guint int
#define guint8 const char *
#include "VirtualCameraDefaultImage.c"

using namespace std;

namespace wcl
{

CameraBuffer VirtualCamera::defaultBuffer;

VirtualCamera::VirtualCamera()
{
    if(VirtualCamera::defaultBuffer.start==NULL){
	VirtualCamera::defaultBuffer.start=(void *)gimp_image.pixel_data[0]; // NOTE: CONST LOST
	VirtualCamera::defaultBuffer.length=sizeof(gimp_image.pixel_data)/sizeof(gimp_image.pixel_data[0]);
    }

    Camera::setFormat(Camera::RGB8,640,480);
}

VirtualCamera::~VirtualCamera()
{}

void VirtualCamera::printDetails()
{
    cout << "WCL Virtual Camera" << endl;
    if ( this->buffers ){
	cout << "Using Provided Frames" << endl;
	cout << "| Current Frame: " << inUseBuffer << endl;
	cout << "| Total Frames: " << this->numBuffers << endl;
    } else {

	cout << "Using Default Frame" << endl;
    }
}

void VirtualCamera::setFormat(const ImageFormat f, const unsigned width, const unsigned height)
{
    if( this->buffers )
	Camera::setFormat(f,width, height);

    else
	cout << "VirtualCamera:SetFormat: Virtual Camera default image only supports RGB" << endl;
}

void VirtualCamera::setExposureMode(const ExposureMode t)
{
    cout << "VirtualCamera: Confirming Exposure Mode change "
	 << "(Note: No change to the image will occur)" << endl;
}

void VirtualCamera::setControlValue(const Control control, const int value)
{
    cout << "VirtualCamera: Confirming control " << control << "Set to value "
	 << value << "(Note: No change to the image will occur)" << endl;
}

const unsigned char* VirtualCamera::getFrame()
{
    if( this->buffers ){
	const unsigned char *frame =
	   (const unsigned char *) this->buffers[this->inUseBuffer].start;
	this->inUseBuffer++;
	if( this->inUseBuffer > this->numBuffers){
	    this->inUseBuffer = 0;
	}
	return frame;
    }
    return (const unsigned char *)defaultBuffer.start;
}

void VirtualCamera::startup()
{}

void VirtualCamera::shutdown()
{
    this->buffers=NULL;
    this->inUseBuffer=0;
    this->numBuffers=0;

    //Reset the default format, size for the default image
    Camera::setFormat(Camera::RGB8,640,480);
}

void VirtualCamera::setFrames(const CameraBuffer *buffers, const unsigned bufferCount)
{
    this->buffers=const_cast<CameraBuffer *>(buffers); //NOTE: cost removed, though the buffer is still treated as read only internally
    this->numBuffers = bufferCount;
    this->inUseBuffer=0;
}

}; //namespace wcl
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/cpu/ppc/ppc_context.h"

#include <cinttypes>
#include <cstdlib>

#include "xenia/base/assert.h"
#include "xenia/base/string_util.h"

namespace xe {
namespace cpu {
namespace ppc {

uint64_t PPCContext::cr() const {
  uint64_t final_bits = 0;
  for (int i = 0; i < 8; ++i) {
    uint32_t crf = *(&cr0.value + i);
    uint64_t bits = (crf & 0x1) << (4 * (7 - i) + 3) |
                    ((crf >> 8) & 0x1) << (4 * (7 - i) + 2) |
                    ((crf >> 16) & 0x1) << (4 * (7 - i) + 1) |
                    ((crf >> 24) & 0x1) << (4 * (7 - i) + 0);
    final_bits |= bits << (i * 4);
  }
  return final_bits;
}

void PPCContext::set_cr(uint64_t value) {
  assert_always("not yet implemented");
}

std::string PPCContext::GetRegisterName(PPCRegister reg) {
  switch (reg) {
    case PPCRegister::kLR:
      return "lr";
    case PPCRegister::kCTR:
      return "ctr";
    case PPCRegister::kXER:
      return "xer";
    case PPCRegister::kFPSCR:
      return "fpscr";
    case PPCRegister::kVSCR:
      return "vscr";
    case PPCRegister::kCR:
      return "cr";
    default:
      if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
          static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
        return std::string("r") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kR0));
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kFR31)) {
        return std::string("fr") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kFR0));
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kVR128)) {
        return std::string("vr") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kVR0));
      } else {
        assert_unhandled_case(reg);
        return "?";
      }
  }
}

std::string PPCContext::GetStringFromValue(PPCRegister reg) const {
  switch (reg) {
    case PPCRegister::kLR:
      return string_util::to_hex_string(lr);
    case PPCRegister::kCTR:
      return string_util::to_hex_string(ctr);
    case PPCRegister::kXER:
      // return Int64ToHex(xer_ca);
      return "?";
    case PPCRegister::kFPSCR:
      // return Int64ToHex(fpscr);
      return "?";
    case PPCRegister::kVSCR:
      // return Int64ToHex(vscr_sat);
      return "?";
    case PPCRegister::kCR:
      // return Int64ToHex(cr);
      return "?";
    default:
      if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
          static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
        return string_util::to_hex_string(
            r[static_cast<int>(reg) - static_cast<int>(PPCRegister::kR0)]);
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kFR31)) {
        return string_util::to_hex_string(
            f[static_cast<int>(reg) - static_cast<int>(PPCRegister::kFR0)]);
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kVR128)) {
        return string_util::to_hex_string(
            v[static_cast<int>(reg) - static_cast<int>(PPCRegister::kVR0)]);
      } else {
        assert_unhandled_case(reg);
        return "";
      }
  }
}

void PPCContext::SetValueFromString(PPCRegister reg, std::string value) {
  // TODO(benvanik): set value from string to replace SetRegFromString?
  assert_always(false);
}

void PPCContext::SetRegFromString(const char* name, const char* value) {
  int n;
  if (sscanf(name, "r%d", &n) == 1) {
    this->r[n] = string_util::from_string<uint64_t>(value);
  } else if (sscanf(name, "f%d", &n) == 1) {
    this->f[n] = string_util::from_string<double>(value);
  } else if (sscanf(name, "v%d", &n) == 1) {
    this->v[n] = string_util::from_string<vec128_t>(value);
  } else if (std::strcmp(name, "cr") == 0) {
    this->set_cr(string_util::from_string<uint64_t>(value));
  } else {
    printf("Unrecognized register name: %s\n", name);
  }
}

bool PPCContext::CompareRegWithString(const char* name, const char* value,
                                      char* out_value,
                                      size_t out_value_size) const {
  int n;
  if (sscanf(name, "r%d", &n) == 1) {
    uint64_t expected = string_util::from_string<uint64_t>(value);
    if (this->r[n] != expected) {
      std::snprintf(out_value, out_value_size, "%016" PRIX64, this->r[n]);
      return false;
    }
    return true;
  } else if (sscanf(name, "f%d", &n) == 1) {
    if (std::strstr(value, "0x")) {
      // Special case: Treat float as integer.
      uint64_t expected = string_util::from_string<uint64_t>(value, true);

      union {
        double f;
        uint64_t u;
      } f2u;
      f2u.f = this->f[n];

      if (f2u.u != expected) {
        std::snprintf(out_value, out_value_size, "%016" PRIX64, f2u.u);
        return false;
      }
    } else {
      double expected = string_util::from_string<double>(value);

      // TODO(benvanik): epsilon
      if (this->f[n] != expected) {
        std::snprintf(out_value, out_value_size, "%f", this->f[n]);
        return false;
      }
    }
    return true;
  } else if (sscanf(name, "v%d", &n) == 1) {
    vec128_t expected = string_util::from_string<vec128_t>(value);
    if (this->v[n] != expected) {
      std::snprintf(out_value, out_value_size, "[%.8X, %.8X, %.8X, %.8X]",
                    this->v[n].i32[0], this->v[n].i32[1], this->v[n].i32[2],
                    this->v[n].i32[3]);
      return false;
    }
    return true;
  } else if (std::strcmp(name, "cr") == 0) {
    uint64_t actual = this->cr();
    uint64_t expected = string_util::from_string<uint64_t>(value);
    if (actual != expected) {
      std::snprintf(out_value, out_value_size, "%016" PRIX64, actual);
      return false;
    }
    return true;
  } else {
    assert_always("Unrecognized register name: %s\n", name);
    return false;
  }
}

}  // namespace ppc
}  // namespace cpu
}  // namespace xe
<commit_msg>Fixed PPCContext::cr() returning incorrectly shifted state.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/cpu/ppc/ppc_context.h"

#include <cinttypes>
#include <cstdlib>

#include "xenia/base/assert.h"
#include "xenia/base/string_util.h"

namespace xe {
namespace cpu {
namespace ppc {

uint64_t PPCContext::cr() const {
  uint64_t final_bits = 0;
  for (int i = 0; i < 8; ++i) {
    union {
      uint32_t value;
      struct {
        uint8_t lt;
        uint8_t gt;
        uint8_t eq;
        uint8_t so;
      };
    } crf;
    crf.value = *(&cr0.value + i);
    uint64_t bits = (crf.lt & 0x1) << 3 | (crf.gt & 0x1) << 2 |
                    (crf.eq & 0x1) << 1 | (crf.so & 0x1) << 0;
    final_bits |= bits << ((7 - i) * 4);
  }
  return final_bits;
}

void PPCContext::set_cr(uint64_t value) {
  assert_always("not yet implemented");
}

std::string PPCContext::GetRegisterName(PPCRegister reg) {
  switch (reg) {
    case PPCRegister::kLR:
      return "lr";
    case PPCRegister::kCTR:
      return "ctr";
    case PPCRegister::kXER:
      return "xer";
    case PPCRegister::kFPSCR:
      return "fpscr";
    case PPCRegister::kVSCR:
      return "vscr";
    case PPCRegister::kCR:
      return "cr";
    default:
      if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
          static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
        return std::string("r") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kR0));
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kFR31)) {
        return std::string("fr") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kFR0));
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kVR128)) {
        return std::string("vr") +
               std::to_string(static_cast<int>(reg) -
                              static_cast<int>(PPCRegister::kVR0));
      } else {
        assert_unhandled_case(reg);
        return "?";
      }
  }
}

std::string PPCContext::GetStringFromValue(PPCRegister reg) const {
  switch (reg) {
    case PPCRegister::kLR:
      return string_util::to_hex_string(lr);
    case PPCRegister::kCTR:
      return string_util::to_hex_string(ctr);
    case PPCRegister::kXER:
      // return Int64ToHex(xer_ca);
      return "?";
    case PPCRegister::kFPSCR:
      // return Int64ToHex(fpscr);
      return "?";
    case PPCRegister::kVSCR:
      // return Int64ToHex(vscr_sat);
      return "?";
    case PPCRegister::kCR:
      // return Int64ToHex(cr);
      return "?";
    default:
      if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
          static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
        return string_util::to_hex_string(
            r[static_cast<int>(reg) - static_cast<int>(PPCRegister::kR0)]);
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kFR31)) {
        return string_util::to_hex_string(
            f[static_cast<int>(reg) - static_cast<int>(PPCRegister::kFR0)]);
      } else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
                 static_cast<int>(reg) <=
                     static_cast<int>(PPCRegister::kVR128)) {
        return string_util::to_hex_string(
            v[static_cast<int>(reg) - static_cast<int>(PPCRegister::kVR0)]);
      } else {
        assert_unhandled_case(reg);
        return "";
      }
  }
}

void PPCContext::SetValueFromString(PPCRegister reg, std::string value) {
  // TODO(benvanik): set value from string to replace SetRegFromString?
  assert_always(false);
}

void PPCContext::SetRegFromString(const char* name, const char* value) {
  int n;
  if (sscanf(name, "r%d", &n) == 1) {
    this->r[n] = string_util::from_string<uint64_t>(value);
  } else if (sscanf(name, "f%d", &n) == 1) {
    this->f[n] = string_util::from_string<double>(value);
  } else if (sscanf(name, "v%d", &n) == 1) {
    this->v[n] = string_util::from_string<vec128_t>(value);
  } else if (std::strcmp(name, "cr") == 0) {
    this->set_cr(string_util::from_string<uint64_t>(value));
  } else {
    printf("Unrecognized register name: %s\n", name);
  }
}

bool PPCContext::CompareRegWithString(const char* name, const char* value,
                                      char* out_value,
                                      size_t out_value_size) const {
  int n;
  if (sscanf(name, "r%d", &n) == 1) {
    uint64_t expected = string_util::from_string<uint64_t>(value);
    if (this->r[n] != expected) {
      std::snprintf(out_value, out_value_size, "%016" PRIX64, this->r[n]);
      return false;
    }
    return true;
  } else if (sscanf(name, "f%d", &n) == 1) {
    if (std::strstr(value, "0x")) {
      // Special case: Treat float as integer.
      uint64_t expected = string_util::from_string<uint64_t>(value, true);

      union {
        double f;
        uint64_t u;
      } f2u;
      f2u.f = this->f[n];

      if (f2u.u != expected) {
        std::snprintf(out_value, out_value_size, "%016" PRIX64, f2u.u);
        return false;
      }
    } else {
      double expected = string_util::from_string<double>(value);

      // TODO(benvanik): epsilon
      if (this->f[n] != expected) {
        std::snprintf(out_value, out_value_size, "%f", this->f[n]);
        return false;
      }
    }
    return true;
  } else if (sscanf(name, "v%d", &n) == 1) {
    vec128_t expected = string_util::from_string<vec128_t>(value);
    if (this->v[n] != expected) {
      std::snprintf(out_value, out_value_size, "[%.8X, %.8X, %.8X, %.8X]",
                    this->v[n].i32[0], this->v[n].i32[1], this->v[n].i32[2],
                    this->v[n].i32[3]);
      return false;
    }
    return true;
  } else if (std::strcmp(name, "cr") == 0) {
    uint64_t actual = this->cr();
    uint64_t expected = string_util::from_string<uint64_t>(value);
    if (actual != expected) {
      std::snprintf(out_value, out_value_size, "%016" PRIX64, actual);
      return false;
    }
    return true;
  } else {
    assert_always("Unrecognized register name: %s\n", name);
    return false;
  }
}

}  // namespace ppc
}  // namespace cpu
}  // namespace xe
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_META_REF_TYPE_HPP
#define STAN_MATH_PRIM_META_REF_TYPE_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta/is_eigen.hpp>
#include <stan/math/prim/meta/is_eigen_map_base.hpp>
#include <stan/math/prim/meta/is_arena_matrix.hpp>
#include <stan/math/prim/meta/is_vector.hpp>
#include <stan/math/prim/meta/plain_type.hpp>

#include <type_traits>

namespace stan {

/**
 * If the condition is true determines appropriate type for assigning expression
 * of given type to, to evaluate expensive expressions, but not make a copy if T
 * involves no calculations. This works similarly as `Eigen::Ref`. It also
 * handles rvalue references, so it can be used with perfect forwarding. If the
 * condition is false the expression will never be evaluated.
 *
 * Warning: if a variable of this type could be assigned a rvalue, make sure
 * template parameter `T` is of correct reference type (rvalue).
 * @tparam T type to determine reference for
 */
template <bool Condition, typename T, typename = void>
struct ref_type_if {
  using T_plain = plain_type_t<T>;
  using T_optionally_ref
      = std::conditional_t<std::is_rvalue_reference<T>::value,
                           std::remove_reference_t<T>, const T&>;
  using type = std::conditional_t<
      Eigen::internal::traits<Eigen::Ref<std::decay_t<T_plain>>>::
              template match<std::decay_t<T>>::MatchAtCompileTime
          || !Condition,
      T_optionally_ref, T_plain>;
};

template <bool Condition, typename T>
struct ref_type_if<Condition, T, require_not_eigen_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <bool Condition, typename T>
struct ref_type_if<Condition, T, require_eigen_map_base_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <typename T>
using ref_type_t = typename ref_type_if<true, T>::type;

template <bool Condition, typename T>
using ref_type_if_t = typename ref_type_if<Condition, T>::type;

/**
 * Determines appropriate type for assigning expression of given type to, so
 * that the resulting type has directly accessible contiguous colum-major data,
 * which is needed to copy to OpenCL device for construction of matrix_cl.
 *
 * THis is similar to `ref_type` except this also copies expressions, which do
 * not have contiguous data (in both dimensions) or have row major storage
 * order.
 *
 * Warning: if a variable of this type could be assigned a rvalue, make sure
 * template parameter `T` is of correct reference type (rvalue).
 * @tparam T type to determine reference for
 */
template <typename T, typename = void>
struct ref_type_for_opencl {
  using T_val = std::remove_reference_t<T>;
  using T_plain_col_major = std::conditional_t<
      std::is_same<typename Eigen::internal::traits<T_val>::XprKind,
                   Eigen::MatrixXpr>::value,
      Eigen::Matrix<value_type_t<T>, T_val::RowsAtCompileTime,
                    T_val::ColsAtCompileTime>,
      Eigen::Array<value_type_t<T>, T_val::RowsAtCompileTime,
                   T_val::ColsAtCompileTime>>;
  using T_optionally_ref
      = std::conditional_t<std::is_rvalue_reference<T>::value, T_val, const T&>;
  // Setting Outer stride of Ref to 0 (default) won't actually check that
  // expression has contiguous outer stride. Instead we need to check that
  // evaluator flags contain LinearAccessBit and PacketAccessBit.
  using type = std::conditional_t<
      Eigen::internal::traits<Eigen::Ref<std::decay_t<T_plain_col_major>>>::
              template match<T_val>::MatchAtCompileTime
          && (Eigen::internal::evaluator<T_val>::Flags & Eigen::LinearAccessBit)
          && (Eigen::internal::evaluator<T_val>::Flags
              & Eigen::PacketAccessBit),
      T_optionally_ref, T_plain_col_major>;
};

template <typename T>
struct ref_type_for_opencl<T, require_not_eigen_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <typename T>
struct ref_type_for_opencl<T, require_eigen_map_base_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <typename T>
using ref_type_for_opencl_t = typename ref_type_for_opencl<T>::type;

}  // namespace stan

#endif
<commit_msg>add specialization for arena_matrix that uses Eigen::Map<> underneath<commit_after>#ifndef STAN_MATH_PRIM_META_REF_TYPE_HPP
#define STAN_MATH_PRIM_META_REF_TYPE_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta/is_eigen.hpp>
#include <stan/math/prim/meta/is_eigen_map_base.hpp>
#include <stan/math/prim/meta/is_arena_matrix.hpp>
#include <stan/math/prim/meta/is_vector.hpp>
#include <stan/math/prim/meta/plain_type.hpp>

#include <type_traits>

namespace stan {

/**
 * If the condition is true determines appropriate type for assigning expression
 * of given type to, to evaluate expensive expressions, but not make a copy if T
 * involves no calculations. This works similarly as `Eigen::Ref`. It also
 * handles rvalue references, so it can be used with perfect forwarding. If the
 * condition is false the expression will never be evaluated.
 *
 * Warning: if a variable of this type could be assigned a rvalue, make sure
 * template parameter `T` is of correct reference type (rvalue).
 * @tparam T type to determine reference for
 */
template <bool Condition, typename T, typename = void>
struct ref_type_if {
  using T_plain = plain_type_t<T>;
  using T_optionally_ref
      = std::conditional_t<std::is_rvalue_reference<T>::value,
                           std::remove_reference_t<T>, const T&>;
  using type = std::conditional_t<
      Eigen::internal::traits<Eigen::Ref<std::decay_t<T_plain>>>::
              template match<std::decay_t<T>>::MatchAtCompileTime
          || !Condition,
      T_optionally_ref, T_plain>;
};

template <bool Condition, typename T>
struct ref_type_if<Condition, T, require_not_eigen_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <bool Condition, typename T>
struct ref_type_if<Condition, T, require_arena_matrix_t<T>> {
  using type = typename ref_type_if<Condition, Eigen::Map<typename std::decay_t<T>::MatrixType>>::type;
};

template <typename T>
using ref_type_t = typename ref_type_if<true, T>::type;

template <bool Condition, typename T>
using ref_type_if_t = typename ref_type_if<Condition, T>::type;

/**
 * Determines appropriate type for assigning expression of given type to, so
 * that the resulting type has directly accessible contiguous colum-major data,
 * which is needed to copy to OpenCL device for construction of matrix_cl.
 *
 * THis is similar to `ref_type` except this also copies expressions, which do
 * not have contiguous data (in both dimensions) or have row major storage
 * order.
 *
 * Warning: if a variable of this type could be assigned a rvalue, make sure
 * template parameter `T` is of correct reference type (rvalue).
 * @tparam T type to determine reference for
 */
template <typename T, typename = void>
struct ref_type_for_opencl {
  using T_val = std::remove_reference_t<T>;
  using T_plain_col_major = std::conditional_t<
      std::is_same<typename Eigen::internal::traits<T_val>::XprKind,
                   Eigen::MatrixXpr>::value,
      Eigen::Matrix<value_type_t<T>, T_val::RowsAtCompileTime,
                    T_val::ColsAtCompileTime>,
      Eigen::Array<value_type_t<T>, T_val::RowsAtCompileTime,
                   T_val::ColsAtCompileTime>>;
  using T_optionally_ref
      = std::conditional_t<std::is_rvalue_reference<T>::value, T_val, const T&>;
  // Setting Outer stride of Ref to 0 (default) won't actually check that
  // expression has contiguous outer stride. Instead we need to check that
  // evaluator flags contain LinearAccessBit and PacketAccessBit.
  using type = std::conditional_t<
      Eigen::internal::traits<Eigen::Ref<std::decay_t<T_plain_col_major>>>::
              template match<T_val>::MatchAtCompileTime
          && (Eigen::internal::evaluator<T_val>::Flags & Eigen::LinearAccessBit)
          && (Eigen::internal::evaluator<T_val>::Flags
              & Eigen::PacketAccessBit),
      T_optionally_ref, T_plain_col_major>;
};

template <typename T>
struct ref_type_for_opencl<T, require_not_eigen_t<T>> {
  using type = std::conditional_t<std::is_rvalue_reference<T>::value,
                                  std::remove_reference_t<T>, const T&>;
};

template <typename T>
struct ref_type_for_opencl<T, require_arena_matrix_t<T>> {
  using type = typename ref_type_for_opencl<Eigen::Map<typename std::decay_t<T>::MatrixType>>::type;
};

template <typename T>
using ref_type_for_opencl_t = typename ref_type_for_opencl<T>::type;

}  // namespace stan

#endif
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    KeyValueFileParser.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    September 2008
*/

#include "KeyValueFileParser.h"

#include <algorithm>
#include <fstream>
#include <functional>
#include <Basics/SysTools.h>

using namespace std;
using namespace SysTools;

KeyValPair::KeyValPair() :
  strKey(""),
  wstrKey(L""),
  strKeyUpper(""),
  wstrKeyUpper(L""),
  strValue(""),
  wstrValue(L""),
  strValueUpper(""),
  wstrValueUpper(L"")
{}

KeyValPair::KeyValPair(const string& key, const string& value) :
  strKey(key),
  wstrKey(key.begin(), key.end()),

  strValue(value),
  wstrValue(value.begin(), value.end())
{
  vstrValue = Tokenize(value);
  for (size_t i = 0;i<vstrValue.size();i++) {
    vwstrValue.push_back(wstring(vstrValue[i].begin(), vstrValue[i].end()));
  }
  FillDerivedData();
}

KeyValPair::KeyValPair(const wstring& key, const wstring& value) :
  strKey(key.begin(), key.end()),
  wstrKey(key),

  strValue(value.begin(), value.end()),
  wstrValue(value)
{
  vwstrValue = Tokenize(value);
  for (size_t i = 0;i<vwstrValue.size();i++) {
    vstrValue.push_back(string(vwstrValue[i].begin(), vwstrValue[i].end()));
  }
  FillDerivedData();
}

void KeyValPair::FillDerivedData() {
  int    _iValue;
  UINT32 _uiValue;
  float  _fValue;

  for (size_t i = 0;i<vwstrValue.size();i++) {
    if (FromString(_iValue, vstrValue[i]))
      viValue.push_back(_iValue);
    else
      viValue.push_back(0);

    if (FromString(_uiValue, vstrValue[i]))
      vuiValue.push_back(_uiValue);
    else
      vuiValue.push_back(0);

    if (FromString(_fValue, vstrValue[i]))
      vfValue.push_back(_fValue);
    else
      vfValue.push_back(0.0f);
  }

  if (vwstrValue.size() > 0) {
    iValue  = viValue[0];
    uiValue = vuiValue[0];
    fValue  = vfValue[0];
  } else {
    iValue  = 0;
    uiValue = 0;
    fValue  = 0.0f;
  }

  strKeyUpper  = ToUpperCase(strKey);
  wstrKeyUpper = ToUpperCase(wstrKey);
  strValueUpper  = ToUpperCase(strValue);
  wstrValueUpper  = ToUpperCase(wstrValue);
}

KeyValueFileParser::KeyValueFileParser(const string& strFilename, bool bStopOnEmptyLine, const string& strToken, const std::string& strEndToken)
{
  m_bFileReadable = ParseFile(strFilename, bStopOnEmptyLine, strToken, strEndToken);
}

KeyValueFileParser::KeyValueFileParser(const wstring& wstrFilename, bool bStopOnEmptyLine, const wstring& wstrToken, const std::wstring& wstrEndToken)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  string strToken(wstrToken.begin(), wstrToken.end());
  string strEndToken(wstrEndToken.begin(), wstrEndToken.end());

  m_bFileReadable = ParseFile(strFilename, bStopOnEmptyLine, strToken, strEndToken);
}

KeyValueFileParser::~KeyValueFileParser()
{
}

KeyValPair* KeyValueFileParser::GetData(const string&  strKey, const bool bCaseSensitive) {
  if (!bCaseSensitive) {
    string upperKey(strKey);
    transform(upperKey.begin(), upperKey.end(), upperKey.begin(), ::toupper);
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].strKeyUpper == upperKey) return &m_vecTokens[i];
  } else {
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].strKey == strKey) return &m_vecTokens[i];
  }
  return NULL;
}

KeyValPair* KeyValueFileParser::GetData(const wstring& wstrKey, const bool bCaseSensitive) {
  if (!bCaseSensitive) {
    wstring wupperKey(wstrKey);
    transform(wupperKey.begin(), wupperKey.end(), wupperKey.begin(), ::toupper);
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].wstrKeyUpper == wupperKey) return &m_vecTokens[i];
  } else {
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].wstrKey == wstrKey) return &m_vecTokens[i];
  }
  return NULL;
}

struct matching_keys : public std::binary_function<std::string,
                                                   KeyValPair,
                                                   bool> {
  bool operator()(const std::string &key, const KeyValPair &kv) const {
    return key == kv.strKey;
  }
};

const KeyValPair* KeyValueFileParser::GetData(const std::string& strKey,
                                              const bool bCaseSensitive) const
{
  std::string key(strKey);
  if(!bCaseSensitive) {
    std::transform(key.begin(), key.end(), key.begin(), ::toupper);
  }

  std::vector<KeyValPair>::const_iterator iter;
  iter = std::find_if(m_vecTokens.begin(), m_vecTokens.end(),
                      std::bind1st(matching_keys(), key));

  if(iter == m_vecTokens.end()) {
    return NULL;
  }
  return &(*iter);
}

bool KeyValueFileParser::ParseFile(const std::string& strFilename, bool bStopOnEmptyLine, const std::string& strToken, const std::string& strEndToken) {
  string line;
  ifstream fileData(strFilename.c_str(),ios::binary);

  m_iStopPos = 0;
  if (fileData.is_open())
  {
    while (! fileData.eof() )
    {
      getline (fileData,line);
      RemoveLeadingWhitespace(line);

      // remove windows line endings
      if (line.length() > 0 && line[line.length()-1] == 13)
        line = line.substr(0,line.length()-1);

      if ((strEndToken != "" && strEndToken == line) ||
          (bStopOnEmptyLine && line.empty()))  {
        m_iStopPos = fileData.tellg();
        break;
      }

      if (line[0] == '#') continue;        // skip comments
      if (line.find_first_of(strToken) == string::npos) continue;  // skip invalid lines

      string strKey = line.substr(0, line.find_first_of(strToken));
      RemoveTailingWhitespace(strKey);

      line = line.substr(line.find_first_of(strToken)+strToken.length(), line.length());
      RemoveLeadingWhitespace(line);
      RemoveTailingWhitespace(line);

      if (strKey.length() == 0 || line.length() == 0) continue;

      KeyValPair newKey(strKey, line);
      m_vecTokens.push_back(newKey);
    }
    fileData.close();
  } else return false;

  return true;
}
<commit_msg>Remove EOL whitespace.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    KeyValueFileParser.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    September 2008
*/

#include "KeyValueFileParser.h"

#include <algorithm>
#include <fstream>
#include <functional>
#include <Basics/SysTools.h>

using namespace std;
using namespace SysTools;

KeyValPair::KeyValPair() :
  strKey(""),
  wstrKey(L""),
  strKeyUpper(""),
  wstrKeyUpper(L""),
  strValue(""),
  wstrValue(L""),
  strValueUpper(""),
  wstrValueUpper(L"")
{}

KeyValPair::KeyValPair(const string& key, const string& value) :
  strKey(key),
  wstrKey(key.begin(), key.end()),

  strValue(value),
  wstrValue(value.begin(), value.end())
{
  vstrValue = Tokenize(value);
  for (size_t i = 0;i<vstrValue.size();i++) {
    vwstrValue.push_back(wstring(vstrValue[i].begin(), vstrValue[i].end()));
  }
  FillDerivedData();
}

KeyValPair::KeyValPair(const wstring& key, const wstring& value) :
  strKey(key.begin(), key.end()),
  wstrKey(key),

  strValue(value.begin(), value.end()),
  wstrValue(value)
{
  vwstrValue = Tokenize(value);
  for (size_t i = 0;i<vwstrValue.size();i++) {
    vstrValue.push_back(string(vwstrValue[i].begin(), vwstrValue[i].end()));
  }
  FillDerivedData();
}

void KeyValPair::FillDerivedData() {
  int    _iValue;
  UINT32 _uiValue;
  float  _fValue;

  for (size_t i = 0;i<vwstrValue.size();i++) {
    if (FromString(_iValue, vstrValue[i]))
      viValue.push_back(_iValue);
    else
      viValue.push_back(0);

    if (FromString(_uiValue, vstrValue[i]))
      vuiValue.push_back(_uiValue);
    else
      vuiValue.push_back(0);

    if (FromString(_fValue, vstrValue[i]))
      vfValue.push_back(_fValue);
    else
      vfValue.push_back(0.0f);
  }

  if (vwstrValue.size() > 0) {
    iValue  = viValue[0];
    uiValue = vuiValue[0];
    fValue  = vfValue[0];
  } else {
    iValue  = 0;
    uiValue = 0;
    fValue  = 0.0f;
  }

  strKeyUpper  = ToUpperCase(strKey);
  wstrKeyUpper = ToUpperCase(wstrKey);
  strValueUpper  = ToUpperCase(strValue);
  wstrValueUpper  = ToUpperCase(wstrValue);
}

KeyValueFileParser::KeyValueFileParser(const string& strFilename, bool bStopOnEmptyLine, const string& strToken, const std::string& strEndToken)
{
  m_bFileReadable = ParseFile(strFilename, bStopOnEmptyLine, strToken, strEndToken);
}

KeyValueFileParser::KeyValueFileParser(const wstring& wstrFilename, bool bStopOnEmptyLine, const wstring& wstrToken, const std::wstring& wstrEndToken)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  string strToken(wstrToken.begin(), wstrToken.end());
  string strEndToken(wstrEndToken.begin(), wstrEndToken.end());

  m_bFileReadable = ParseFile(strFilename, bStopOnEmptyLine, strToken, strEndToken);
}

KeyValueFileParser::~KeyValueFileParser()
{
}

KeyValPair* KeyValueFileParser::GetData(const string&  strKey, const bool bCaseSensitive) {
  if (!bCaseSensitive) {
    string upperKey(strKey);
    transform(upperKey.begin(), upperKey.end(), upperKey.begin(), ::toupper);
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].strKeyUpper == upperKey) return &m_vecTokens[i];
  } else {
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].strKey == strKey) return &m_vecTokens[i];
  }
  return NULL;
}

KeyValPair* KeyValueFileParser::GetData(const wstring& wstrKey, const bool bCaseSensitive) {
  if (!bCaseSensitive) {
    wstring wupperKey(wstrKey);
    transform(wupperKey.begin(), wupperKey.end(), wupperKey.begin(), ::toupper);
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].wstrKeyUpper == wupperKey) return &m_vecTokens[i];
  } else {
    for (UINT32 i = 0;i<m_vecTokens.size();i++) if (m_vecTokens[i].wstrKey == wstrKey) return &m_vecTokens[i];
  }
  return NULL;
}

struct matching_keys : public std::binary_function<std::string,
                                                   KeyValPair,
                                                   bool> {
  bool operator()(const std::string &key, const KeyValPair &kv) const {
    return key == kv.strKey;
  }
};

const KeyValPair* KeyValueFileParser::GetData(const std::string& strKey,
                                              const bool bCaseSensitive) const
{
  std::string key(strKey);
  if(!bCaseSensitive) {
    std::transform(key.begin(), key.end(), key.begin(), ::toupper);
  }

  std::vector<KeyValPair>::const_iterator iter;
  iter = std::find_if(m_vecTokens.begin(), m_vecTokens.end(),
                      std::bind1st(matching_keys(), key));

  if(iter == m_vecTokens.end()) {
    return NULL;
  }
  return &(*iter);
}

bool KeyValueFileParser::ParseFile(const std::string& strFilename, bool bStopOnEmptyLine, const std::string& strToken, const std::string& strEndToken) {
  string line;
  ifstream fileData(strFilename.c_str(),ios::binary);

  m_iStopPos = 0;
  if (fileData.is_open())
  {
    while (! fileData.eof() )
    {
      getline (fileData,line);
      RemoveLeadingWhitespace(line);

      // remove windows line endings
      if (line.length() > 0 && line[line.length()-1] == 13)
        line = line.substr(0,line.length()-1);

      if ((strEndToken != "" && strEndToken == line) ||
          (bStopOnEmptyLine && line.empty()))  {
        m_iStopPos = fileData.tellg();
        break;
      }

      if (line[0] == '#') continue;        // skip comments
      if (line.find_first_of(strToken) == string::npos) continue;  // skip invalid lines

      string strKey = line.substr(0, line.find_first_of(strToken));
      RemoveTailingWhitespace(strKey);

      line = line.substr(line.find_first_of(strToken)+strToken.length(), line.length());
      RemoveLeadingWhitespace(line);
      RemoveTailingWhitespace(line);

      if (strKey.length() == 0 || line.length() == 0) continue;

      KeyValPair newKey(strKey, line);
      m_vecTokens.push_back(newKey);
    }
    fileData.close();
  } else return false;

  return true;
}
<|endoftext|>


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

#include "console.h"

#include <QX11Info>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QTextStream>

#include <qjson/parser.h>
#include <qjson/serializer.h>

#include <kscreen/config.h>
#include <kscreen/output.h>
#include <kscreen/mode.h>
#include <kscreen/configmonitor.h>
#include <kscreen/edid.h>

#include <KStandardDirs>

using namespace KScreen;

Console::Console(QObject* parent): QObject(parent)
{
    qDebug() << "START";
    QDateTime date = QDateTime::currentDateTime();
    m_config = Config::current();
    qDebug() << "Config::current() took" << date.msecsTo(QDateTime::currentDateTime()) << "milliseconds";
}

Console::~Console()
{

}

void Console::printConfig()
{
    if (!m_config) {
        qDebug() << "Config is invalid, probably backend couldn't load";
        return;
    }
    if (!m_config->screen()) {
        qDebug() << "No screen in the configuration, broken backend";
        return;
    }

    qDebug() << "Screen:";
    qDebug() << "maxSize:" << m_config->screen()->maxSize();
    qDebug() << "minSize:" << m_config->screen()->minSize();
    qDebug() << "currentSize:" << m_config->screen()->currentSize();

    OutputList outputs = m_config->outputs();
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "\n-----------------------------------------------------\n";
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        if (!output->isConnected()) {
            continue;
        }
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Rotation: " << output->rotation();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->currentMode()->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentModeId();
        qDebug() << "Preferred Mode: " << output->preferredModeId();
        qDebug() << "Preferred modes: " << output->preferredModes();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        Edid* edid = output->edid();
        qDebug() << "EDID Info: ";
        if (edid != 0) {
            qDebug() << "\tDevice ID: " << edid->deviceId();
            qDebug() << "\tName: " << edid->name();
            qDebug() << "\tVendor: " << edid->vendor();
            qDebug() << "\tSerial: " << edid->serial();
            qDebug() << "\tEISA ID: " << edid->eisaId();
            qDebug() << "\tHash: " << edid->hash();
            qDebug() << "\tWidth: " << edid->width();
            qDebug() << "\tHeight: " << edid->height();
            qDebug() << "\tGamma: " << edid->gamma();
            qDebug() << "\tRed: " << edid->red();
            qDebug() << "\tGreen: " << edid->green();
            qDebug() << "\tBlue: " << edid->blue();
            qDebug() << "\tWhite: " << edid->white();
        } else {
            qDebug() << "\tUnavailable";
        }
    }
}

void Console::printSerializations()
{
    QString path = KStandardDirs::locateLocal("data", "kscreen/");
    qDebug() << "Configs in: " << path;

    QDir dir(path);
    QStringList files = dir.entryList(QDir::Files);
    qDebug() << "Number of files: " << files.count() << endl;

    bool ok;
    QJson::Parser parser;
    QJson::Serializer serializer;
    serializer.setIndentMode(QJson::IndentFull);
    Q_FOREACH(const QString fileName, files) {
        ok = true;
        qDebug() << fileName;
        QFile file(path + "/" + fileName);
        file.open(QFile::ReadOnly);
        QVariant data = parser.parse(file.readAll(), &ok);
        if (!ok) {
            qDebug() << "    " << "can't parse file";
            qDebug() << "    " << parser.errorString();
            continue;
        }

        qDebug() << serializer.serialize(data) << endl;
    }
}

void Console::monitor()
{
    ConfigMonitor::instance()->addConfig(m_config);
}

void Console::monitorAndPrint()
{
    monitor();
    connect(ConfigMonitor::instance(), SIGNAL(configurationChanged()), SLOT(printConfig()));
}

#include <console.moc>
<commit_msg>Only show EDID when it is valid<commit_after>/*************************************************************************************
 *  Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org>              *
 *                                                                                *
 *  This program is free software; you can redistribute it and/or                    *
 *  modify it under the terms of the GNU General Public License                      *
 *  as published by the Free Software Foundation; either version 2                   *
 *  of the License, or (at your option) any later version.                           *
 *                                                                                *
 *  This program is distributed in the hope that it will be useful,                  *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
 *  GNU General Public License for more details.                                     *
 *                                                                                *
 *  You should have received a copy of the GNU General Public License                *
 *  along with this program; if not, write to the Free Software                      *
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
 *************************************************************************************/

#include "console.h"

#include <QX11Info>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QTextStream>

#include <qjson/parser.h>
#include <qjson/serializer.h>

#include <kscreen/config.h>
#include <kscreen/output.h>
#include <kscreen/mode.h>
#include <kscreen/configmonitor.h>
#include <kscreen/edid.h>

#include <KStandardDirs>

using namespace KScreen;

Console::Console(QObject* parent): QObject(parent)
{
    qDebug() << "START";
    QDateTime date = QDateTime::currentDateTime();
    m_config = Config::current();
    qDebug() << "Config::current() took" << date.msecsTo(QDateTime::currentDateTime()) << "milliseconds";
}

Console::~Console()
{

}

void Console::printConfig()
{
    if (!m_config) {
        qDebug() << "Config is invalid, probably backend couldn't load";
        return;
    }
    if (!m_config->screen()) {
        qDebug() << "No screen in the configuration, broken backend";
        return;
    }

    qDebug() << "Screen:";
    qDebug() << "maxSize:" << m_config->screen()->maxSize();
    qDebug() << "minSize:" << m_config->screen()->minSize();
    qDebug() << "currentSize:" << m_config->screen()->currentSize();

    OutputList outputs = m_config->outputs();
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "\n-----------------------------------------------------\n";
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        if (!output->isConnected()) {
            continue;
        }
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Rotation: " << output->rotation();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->currentMode()->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentModeId();
        qDebug() << "Preferred Mode: " << output->preferredModeId();
        qDebug() << "Preferred modes: " << output->preferredModes();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        Edid* edid = output->edid();
        qDebug() << "EDID Info: ";
        if (edid && edid->isValid()) {
            qDebug() << "\tDevice ID: " << edid->deviceId();
            qDebug() << "\tName: " << edid->name();
            qDebug() << "\tVendor: " << edid->vendor();
            qDebug() << "\tSerial: " << edid->serial();
            qDebug() << "\tEISA ID: " << edid->eisaId();
            qDebug() << "\tHash: " << edid->hash();
            qDebug() << "\tWidth: " << edid->width();
            qDebug() << "\tHeight: " << edid->height();
            qDebug() << "\tGamma: " << edid->gamma();
            qDebug() << "\tRed: " << edid->red();
            qDebug() << "\tGreen: " << edid->green();
            qDebug() << "\tBlue: " << edid->blue();
            qDebug() << "\tWhite: " << edid->white();
        } else {
            qDebug() << "\tUnavailable";
        }
    }
}

void Console::printSerializations()
{
    QString path = KStandardDirs::locateLocal("data", "kscreen/");
    qDebug() << "Configs in: " << path;

    QDir dir(path);
    QStringList files = dir.entryList(QDir::Files);
    qDebug() << "Number of files: " << files.count() << endl;

    bool ok;
    QJson::Parser parser;
    QJson::Serializer serializer;
    serializer.setIndentMode(QJson::IndentFull);
    Q_FOREACH(const QString fileName, files) {
        ok = true;
        qDebug() << fileName;
        QFile file(path + "/" + fileName);
        file.open(QFile::ReadOnly);
        QVariant data = parser.parse(file.readAll(), &ok);
        if (!ok) {
            qDebug() << "    " << "can't parse file";
            qDebug() << "    " << parser.errorString();
            continue;
        }

        qDebug() << serializer.serialize(data) << endl;
    }
}

void Console::monitor()
{
    ConfigMonitor::instance()->addConfig(m_config);
}

void Console::monitorAndPrint()
{
    monitor();
    connect(ConfigMonitor::instance(), SIGNAL(configurationChanged()), SLOT(printConfig()));
}

#include <console.moc>
<|endoftext|>