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

#include "config.h"
#include "platform/graphics/ImageSource.h"

#include "platform/graphics/DeferredImageDecoder.h"
#include "platform/image-decoders/ImageDecoder.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"

namespace blink {

ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
    : m_alphaOption(alphaOption)
    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
{
}

ImageSource::~ImageSource()
{
}

size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame)
{
    return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0;
}

bool ImageSource::initialized() const
{
    return m_decoder;
}

void ImageSource::setData(SharedBuffer& data, bool allDataReceived)
{
    // Make the decoder by sniffing the bytes.
    // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
    // If insufficient bytes are available to determine the image type, no decoder plugin will be
    // made.
    if (!m_decoder)
        m_decoder = DeferredImageDecoder::create(data, m_alphaOption, m_gammaAndColorProfileOption);

    if (m_decoder)
        m_decoder->setData(data, allDataReceived);
}

String ImageSource::filenameExtension() const
{
    return m_decoder ? m_decoder->filenameExtension() : String();
}

bool ImageSource::isSizeAvailable()
{
    return m_decoder && m_decoder->isSizeAvailable();
}

bool ImageSource::hasColorProfile() const
{
    return m_decoder && m_decoder->hasColorProfile();
}

IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
{
    return frameSizeAtIndex(0, shouldRespectOrientation);
}

IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
{
    if (!m_decoder)
        return IntSize();

    IntSize size = m_decoder->frameSizeAtIndex(index);
    if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight())
        return IntSize(size.height(), size.width());

    return size;
}

bool ImageSource::getHotSpot(IntPoint& hotSpot) const
{
    return m_decoder ? m_decoder->hotSpot(hotSpot) : false;
}

int ImageSource::repetitionCount()
{
    return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
}

size_t ImageSource::frameCount() const
{
    return m_decoder ? m_decoder->frameCount() : 0;
}

PassRefPtr<NativeImageSkia> ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return nullptr;

    ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
        return nullptr;

    // Zero-height images can cause problems for some ports.  If we have an
    // empty image dimension, just bail.
    if (size().isEmpty())
        return nullptr;

    // Return the buffer contents as a native image.  For some ports, the data
    // is already in a native container, and this just increments its refcount.
    return buffer->asNewNativeImage();
}

float ImageSource::frameDurationAtIndex(size_t index) const
{
    if (!m_decoder)
        return 0;

    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
    // for more information.
    const float duration = m_decoder->frameDurationAtIndex(index) / 1000.0f;
    if (duration < 0.011f)
        return 0.100f;
    return duration;
}

ImageOrientation ImageSource::orientationAtIndex(size_t) const
{
    return m_decoder ? m_decoder->orientation() : DefaultImageOrientation;
}

bool ImageSource::frameHasAlphaAtIndex(size_t index) const
{
    return !m_decoder || m_decoder->frameHasAlphaAtIndex(index);
}

bool ImageSource::frameIsCompleteAtIndex(size_t index) const
{
    return m_decoder && m_decoder->frameIsCompleteAtIndex(index);
}

unsigned ImageSource::frameBytesAtIndex(size_t index) const
{
    if (!m_decoder)
        return 0;
    return m_decoder->frameBytesAtIndex(index);
}

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

#include "config.h"
#include "platform/graphics/ImageSource.h"

#include "platform/graphics/DeferredImageDecoder.h"
#include "platform/image-decoders/ImageDecoder.h"

namespace blink {

ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
    : m_alphaOption(alphaOption)
    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
{
}

ImageSource::~ImageSource()
{
}

size_t ImageSource::clearCacheExceptFrame(size_t clearExceptFrame)
{
    return m_decoder ? m_decoder->clearCacheExceptFrame(clearExceptFrame) : 0;
}

bool ImageSource::initialized() const
{
    return m_decoder;
}

void ImageSource::setData(SharedBuffer& data, bool allDataReceived)
{
    // Create a decoder by sniffing the encoded data. If insufficient data bytes are available to
    // determine the encoded image type, no decoder is created.
    if (!m_decoder)
        m_decoder = DeferredImageDecoder::create(data, m_alphaOption, m_gammaAndColorProfileOption);

    if (m_decoder)
        m_decoder->setData(data, allDataReceived);
}

String ImageSource::filenameExtension() const
{
    return m_decoder ? m_decoder->filenameExtension() : String();
}

bool ImageSource::isSizeAvailable()
{
    return m_decoder && m_decoder->isSizeAvailable();
}

bool ImageSource::hasColorProfile() const
{
    return m_decoder && m_decoder->hasColorProfile();
}

IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
{
    return frameSizeAtIndex(0, shouldRespectOrientation);
}

IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
{
    if (!m_decoder)
        return IntSize();

    IntSize size = m_decoder->frameSizeAtIndex(index);
    if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight())
        return IntSize(size.height(), size.width());

    return size;
}

bool ImageSource::getHotSpot(IntPoint& hotSpot) const
{
    return m_decoder ? m_decoder->hotSpot(hotSpot) : false;
}

int ImageSource::repetitionCount()
{
    return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
}

size_t ImageSource::frameCount() const
{
    return m_decoder ? m_decoder->frameCount() : 0;
}

PassRefPtr<NativeImageSkia> ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return nullptr;

    ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
        return nullptr;

    // Zero-height images can cause problems for some ports.  If we have an
    // empty image dimension, just bail.
    if (size().isEmpty())
        return nullptr;

    // Return the buffer contents as a native image.  For some ports, the data
    // is already in a native container, and this just increments its refcount.
    return buffer->asNewNativeImage();
}

float ImageSource::frameDurationAtIndex(size_t index) const
{
    if (!m_decoder)
        return 0;

    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
    // for more information.
    const float duration = m_decoder->frameDurationAtIndex(index) / 1000.0f;
    if (duration < 0.011f)
        return 0.100f;
    return duration;
}

ImageOrientation ImageSource::orientationAtIndex(size_t) const
{
    return m_decoder ? m_decoder->orientation() : DefaultImageOrientation;
}

bool ImageSource::frameHasAlphaAtIndex(size_t index) const
{
    return !m_decoder || m_decoder->frameHasAlphaAtIndex(index);
}

bool ImageSource::frameIsCompleteAtIndex(size_t index) const
{
    return m_decoder && m_decoder->frameIsCompleteAtIndex(index);
}

unsigned ImageSource::frameBytesAtIndex(size_t index) const
{
    return m_decoder ? m_decoder->frameBytesAtIndex(index) : 0;
}

} // namespace blink
<|endoftext|>


<commit_before>// See the file COPYRIGHT.txt for authors and copyright information.
// See the file LICENSE.txt for copying conditions.

#include "File.h"
#include <fstream>
#include <iostream>
#include "strlib.h"

namespace cfg
{

File::File()
{
    resetSettings();
}

File::File(const string& filename)
{
    resetSettings();
    loadFromFile(filename);
}

File::File(const ConfigMap& defaultOptions, bool warnings)
{
    resetSettings();
    showWarnings = warnings;
    setDefaultOptions(defaultOptions);
}

File::File(const string& filename, const ConfigMap& defaultOptions, bool warnings)
{
    resetSettings();
    showWarnings = warnings;
    setDefaultOptions(defaultOptions);
    loadFromFile(filename);
}

File::~File()
{
    if (autosave)
        writeToFile();
}

bool File::loadFromFile(const string& filename)
{
    bool status = false;
    configFilename = filename;
    std::vector<string> lines;
    if (strlib::readLinesFromFile(configFilename, lines, false))
    {
        parseLines(lines);
        status = true;
    }
    else if (showWarnings)
        std::cout << "Error loading \"" << configFilename << "\"\n";
    return status;
}

void File::loadFromString(const string& str)
{
    std::vector<string> lines;
    strlib::getLinesFromString(str, lines, false);
    parseLines(lines);
}

bool File::writeToFile(string filename) const
{
    if (filename.empty())
        filename = configFilename;
    // Write the string to the output file
    return strlib::writeStringToFile(filename, buildString());
}

void File::writeToString(string& str) const
{
    for (const auto& section: options) // Go through all of the sections
    {
        if (!section.first.empty())
            str += '[' + section.first + "]\n"; // Add the section line if it is not blank
        for (const auto& o: section.second) // Go through all of the options in this section
            str += o.first + " = " + o.second.buildArrayString() + '\n';
        str += '\n';
    }
    if (!str.empty() && str.back() == '\n')
        str.pop_back(); // Strip the extra new line at the end
}

string File::buildString() const
{
    string configStr;
    writeToString(configStr);
    return configStr;
}

void File::setShowWarnings(bool setting)
{
    showWarnings = setting;
}

void File::setAutosave(bool setting)
{
    autosave = setting;
}

void File::resetSettings()
{
    showWarnings = false;
    autosave = false;
}

Option& File::operator()(const string& name, const string& section)
{
    return options[section][name];
}

Option& File::operator()(const string& name)
{
    return options[currentSection][name];
}

bool File::optionExists(const string& name, const string& section) const
{
    auto sectionFound = options.find(section);
    return (sectionFound != options.end() && sectionFound->second.find(name) != sectionFound->second.end());
}

bool File::optionExists(const string& name) const
{
    return optionExists(name, currentSection);
}

void File::setDefaultOptions(const ConfigMap& defaultOptions)
{
    options.insert(defaultOptions.begin(), defaultOptions.end());
}

void File::useSection(const string& section)
{
    currentSection = section;
}

File::ConfigMap::iterator File::begin()
{
    return options.begin();
}

File::ConfigMap::iterator File::end()
{
    return options.end();
}

File::Section& File::getSection(const string& section)
{
    return options[section];
}

File::Section& File::getSection()
{
    return options[currentSection];
}

bool File::sectionExists(const string& section) const
{
    return (options.find(section) != options.end());
}

bool File::sectionExists() const
{
    return sectionExists(currentSection);
}

bool File::eraseOption(const string& name, const string& section)
{
    bool status = false;
    auto sectionFound = options.find(section);
    if (sectionFound != options.end()) // If the section exists
        status = (sectionFound->second.erase(name) > 0); // Erase the option
    return status;
}

bool File::eraseOption(const string& name)
{
    return eraseOption(name, currentSection);
}

bool File::eraseSection(const string& section)
{
    return (options.erase(section) > 0);
}

bool File::eraseSection()
{
    return eraseSection(currentSection);
}

void File::clear()
{
    options.clear();
}

void File::parseLines(std::vector<string>& lines)
{
    currentArrayStack.clear();
    arrayOptionName.clear();
    string section;
    bool multiLineComment = false;
    Comment commentType = Comment::None;
    for (string& line: lines) // Iterate through the std::vector of strings
    {
        strlib::trimWhitespace(line);
        commentType = stripComments(line, multiLineComment);

        if (commentType == Comment::Start)
            multiLineComment = true;

        if (!multiLineComment && !line.empty()) // Don't process a comment or an empty line
        {
            if (isSection(line))
                parseSectionLine(line, section); // Example: "[Section]"
            else
                parseOptionLine(line, section); // Example: "Option = Value"
        }

        if (commentType == Comment::End)
            multiLineComment = false;
    }
}

bool File::isSection(const string& section) const
{
    return (section.size() >= 2 && section.front() == '[' && section.back() == ']');
}

void File::parseSectionLine(const string& line, string& section)
{
    section = line.substr(1, line.size() - 2); // Set the current section
    options[section]; // Add that section to the map
}

void File::parseOptionLine(const string& line, const string& section)
{
    if (!currentArrayStack.empty())
    {
        // Process another line in the array
        // This could be 1 of 3 things:
        // 1. { (array start)
        // 2. X (another value)
        // 3. } (array end)
        string value = line;
        strlib::trimWhitespace(value);
        if (value.back() == ',')
            value.pop_back();
        strlib::trimWhitespace(value); // In case there was whitespace before the comma
        if (!value.empty())
        {
            Option& option = getArrayOption(section, arrayOptionName);
            if (value == "{")
                startArray(option);
            else if (value == "}")
                currentArrayStack.pop_back();
            else
                setOption(option.push(), value);
        }
    }
    else
    {
        // Process a regular option line (or the start of a new array)
        size_t equalPos = line.find("="); // Find the position of the "=" symbol
        if (equalPos != string::npos && equalPos >= 1) // Ignore the line if there is no "=" symbol
        {
            string name, value;
            // Extract the name and value
            name = line.substr(0, equalPos);
            value = line.substr(equalPos + 1);
            // Trim any whitespace around the name and value
            strlib::trimWhitespace(name);
            strlib::trimWhitespace(value);
            // Check if this is the start of an array
            Option& option = options[section][name];
            if (value == "{")
            {
                arrayOptionName = name;
                currentArrayStack.assign(1, 0);
            }
            else
            {
                if (!setOption(option, value) && showWarnings)
                {
                    std::cout << "Warning: Option \"" << name << "\" in [" << section << "] was out of range.\n";
                    std::cout << "    Using default value: " << option.toStringWithQuotes() << std::endl;
                }
            }
        }
    }
}

bool File::setOption(Option& option, const string& value)
{
    string trimmedValue = value;
    bool trimmedQuotes = strlib::trimQuotes(trimmedValue); // Remove quotes if any
    bool optionSet = (option = trimmedValue); // Try to set the option
    if (trimmedQuotes) // If quotes were removed
        option.setQuotes(true); // Add quotes to the option
    return optionSet;
}

Option& File::getArrayOption(const string& section, const string& name)
{
    Option* currentOption = &options[section][name];
    // Start at 1, because the 0th element represents the current option above
    for (unsigned i = 1; i < currentArrayStack.size(); ++i)
        currentOption = &((*currentOption)[currentArrayStack[i]]);
    return *currentOption;
}

void File::startArray(Option& option)
{
    option.push(); // This new option will be holding the array starting with this "{"
    currentArrayStack.push_back(option.size() - 1);
}

bool File::isEndComment(const string& str) const
{
    return (str.find("*/") != string::npos);
}

File::Comment File::getCommentType(const string& str, bool checkEnd) const
{
    // Comment symbols and types
    static const std::vector<string> commentSymbols = {"/*", "//", "#", "::", ";"};
    static const std::vector<Comment> commentTypes = {Comment::Start, Comment::Single, Comment::Single, Comment::Single, Comment::Single};

    Comment commentType = Comment::None;

    // This is optional so the function returns the correct result
    if (checkEnd && isEndComment(str))
        commentType = Comment::End;

    // Find out which comment type the string is, if any
    for (unsigned int i = 0; (commentType == Comment::None && i < commentSymbols.size()); i++)
    {
        if (str.compare(0, commentSymbols[i].size(), commentSymbols[i]) == 0)
            commentType = commentTypes[i];
    }

    // This check is required for comments using the multi-line symbols on a single line
    if (!checkEnd && commentType == Comment::Start && isEndComment(str))
        commentType = Comment::Single;

    return commentType;
}

File::Comment File::stripComments(string& str, bool checkEnd)
{
    Comment commentType = getCommentType(str, checkEnd);
    if (commentType == Comment::Single)
        str.clear();
    return commentType;
}

}
<commit_msg>Fixed include typo<commit_after>// See the file COPYRIGHT.txt for authors and copyright information.
// See the file LICENSE.txt for copying conditions.

#include "file.h"
#include <fstream>
#include <iostream>
#include "strlib.h"

namespace cfg
{

File::File()
{
    resetSettings();
}

File::File(const string& filename)
{
    resetSettings();
    loadFromFile(filename);
}

File::File(const ConfigMap& defaultOptions, bool warnings)
{
    resetSettings();
    showWarnings = warnings;
    setDefaultOptions(defaultOptions);
}

File::File(const string& filename, const ConfigMap& defaultOptions, bool warnings)
{
    resetSettings();
    showWarnings = warnings;
    setDefaultOptions(defaultOptions);
    loadFromFile(filename);
}

File::~File()
{
    if (autosave)
        writeToFile();
}

bool File::loadFromFile(const string& filename)
{
    bool status = false;
    configFilename = filename;
    std::vector<string> lines;
    if (strlib::readLinesFromFile(configFilename, lines, false))
    {
        parseLines(lines);
        status = true;
    }
    else if (showWarnings)
        std::cout << "Error loading \"" << configFilename << "\"\n";
    return status;
}

void File::loadFromString(const string& str)
{
    std::vector<string> lines;
    strlib::getLinesFromString(str, lines, false);
    parseLines(lines);
}

bool File::writeToFile(string filename) const
{
    if (filename.empty())
        filename = configFilename;
    // Write the string to the output file
    return strlib::writeStringToFile(filename, buildString());
}

void File::writeToString(string& str) const
{
    for (const auto& section: options) // Go through all of the sections
    {
        if (!section.first.empty())
            str += '[' + section.first + "]\n"; // Add the section line if it is not blank
        for (const auto& o: section.second) // Go through all of the options in this section
            str += o.first + " = " + o.second.buildArrayString() + '\n';
        str += '\n';
    }
    if (!str.empty() && str.back() == '\n')
        str.pop_back(); // Strip the extra new line at the end
}

string File::buildString() const
{
    string configStr;
    writeToString(configStr);
    return configStr;
}

void File::setShowWarnings(bool setting)
{
    showWarnings = setting;
}

void File::setAutosave(bool setting)
{
    autosave = setting;
}

void File::resetSettings()
{
    showWarnings = false;
    autosave = false;
}

Option& File::operator()(const string& name, const string& section)
{
    return options[section][name];
}

Option& File::operator()(const string& name)
{
    return options[currentSection][name];
}

bool File::optionExists(const string& name, const string& section) const
{
    auto sectionFound = options.find(section);
    return (sectionFound != options.end() && sectionFound->second.find(name) != sectionFound->second.end());
}

bool File::optionExists(const string& name) const
{
    return optionExists(name, currentSection);
}

void File::setDefaultOptions(const ConfigMap& defaultOptions)
{
    options.insert(defaultOptions.begin(), defaultOptions.end());
}

void File::useSection(const string& section)
{
    currentSection = section;
}

File::ConfigMap::iterator File::begin()
{
    return options.begin();
}

File::ConfigMap::iterator File::end()
{
    return options.end();
}

File::Section& File::getSection(const string& section)
{
    return options[section];
}

File::Section& File::getSection()
{
    return options[currentSection];
}

bool File::sectionExists(const string& section) const
{
    return (options.find(section) != options.end());
}

bool File::sectionExists() const
{
    return sectionExists(currentSection);
}

bool File::eraseOption(const string& name, const string& section)
{
    bool status = false;
    auto sectionFound = options.find(section);
    if (sectionFound != options.end()) // If the section exists
        status = (sectionFound->second.erase(name) > 0); // Erase the option
    return status;
}

bool File::eraseOption(const string& name)
{
    return eraseOption(name, currentSection);
}

bool File::eraseSection(const string& section)
{
    return (options.erase(section) > 0);
}

bool File::eraseSection()
{
    return eraseSection(currentSection);
}

void File::clear()
{
    options.clear();
}

void File::parseLines(std::vector<string>& lines)
{
    currentArrayStack.clear();
    arrayOptionName.clear();
    string section;
    bool multiLineComment = false;
    Comment commentType = Comment::None;
    for (string& line: lines) // Iterate through the std::vector of strings
    {
        strlib::trimWhitespace(line);
        commentType = stripComments(line, multiLineComment);

        if (commentType == Comment::Start)
            multiLineComment = true;

        if (!multiLineComment && !line.empty()) // Don't process a comment or an empty line
        {
            if (isSection(line))
                parseSectionLine(line, section); // Example: "[Section]"
            else
                parseOptionLine(line, section); // Example: "Option = Value"
        }

        if (commentType == Comment::End)
            multiLineComment = false;
    }
}

bool File::isSection(const string& section) const
{
    return (section.size() >= 2 && section.front() == '[' && section.back() == ']');
}

void File::parseSectionLine(const string& line, string& section)
{
    section = line.substr(1, line.size() - 2); // Set the current section
    options[section]; // Add that section to the map
}

void File::parseOptionLine(const string& line, const string& section)
{
    if (!currentArrayStack.empty())
    {
        // Process another line in the array
        // This could be 1 of 3 things:
        // 1. { (array start)
        // 2. X (another value)
        // 3. } (array end)
        string value = line;
        strlib::trimWhitespace(value);
        if (value.back() == ',')
            value.pop_back();
        strlib::trimWhitespace(value); // In case there was whitespace before the comma
        if (!value.empty())
        {
            Option& option = getArrayOption(section, arrayOptionName);
            if (value == "{")
                startArray(option);
            else if (value == "}")
                currentArrayStack.pop_back();
            else
                setOption(option.push(), value);
        }
    }
    else
    {
        // Process a regular option line (or the start of a new array)
        size_t equalPos = line.find("="); // Find the position of the "=" symbol
        if (equalPos != string::npos && equalPos >= 1) // Ignore the line if there is no "=" symbol
        {
            string name, value;
            // Extract the name and value
            name = line.substr(0, equalPos);
            value = line.substr(equalPos + 1);
            // Trim any whitespace around the name and value
            strlib::trimWhitespace(name);
            strlib::trimWhitespace(value);
            // Check if this is the start of an array
            Option& option = options[section][name];
            if (value == "{")
            {
                arrayOptionName = name;
                currentArrayStack.assign(1, 0);
            }
            else
            {
                if (!setOption(option, value) && showWarnings)
                {
                    std::cout << "Warning: Option \"" << name << "\" in [" << section << "] was out of range.\n";
                    std::cout << "    Using default value: " << option.toStringWithQuotes() << std::endl;
                }
            }
        }
    }
}

bool File::setOption(Option& option, const string& value)
{
    string trimmedValue = value;
    bool trimmedQuotes = strlib::trimQuotes(trimmedValue); // Remove quotes if any
    bool optionSet = (option = trimmedValue); // Try to set the option
    if (trimmedQuotes) // If quotes were removed
        option.setQuotes(true); // Add quotes to the option
    return optionSet;
}

Option& File::getArrayOption(const string& section, const string& name)
{
    Option* currentOption = &options[section][name];
    // Start at 1, because the 0th element represents the current option above
    for (unsigned i = 1; i < currentArrayStack.size(); ++i)
        currentOption = &((*currentOption)[currentArrayStack[i]]);
    return *currentOption;
}

void File::startArray(Option& option)
{
    option.push(); // This new option will be holding the array starting with this "{"
    currentArrayStack.push_back(option.size() - 1);
}

bool File::isEndComment(const string& str) const
{
    return (str.find("*/") != string::npos);
}

File::Comment File::getCommentType(const string& str, bool checkEnd) const
{
    // Comment symbols and types
    static const std::vector<string> commentSymbols = {"/*", "//", "#", "::", ";"};
    static const std::vector<Comment> commentTypes = {Comment::Start, Comment::Single, Comment::Single, Comment::Single, Comment::Single};

    Comment commentType = Comment::None;

    // This is optional so the function returns the correct result
    if (checkEnd && isEndComment(str))
        commentType = Comment::End;

    // Find out which comment type the string is, if any
    for (unsigned int i = 0; (commentType == Comment::None && i < commentSymbols.size()); i++)
    {
        if (str.compare(0, commentSymbols[i].size(), commentSymbols[i]) == 0)
            commentType = commentTypes[i];
    }

    // This check is required for comments using the multi-line symbols on a single line
    if (!checkEnd && commentType == Comment::Start && isEndComment(str))
        commentType = Comment::Single;

    return commentType;
}

File::Comment File::stripComments(string& str, bool checkEnd)
{
    Comment commentType = getCommentType(str, checkEnd);
    if (commentType == Comment::Single)
        str.clear();
    return commentType;
}

}
<|endoftext|>


<commit_before>#include "SettingsUI.h"

#include <iostream>

/* DLGTEMPLATEEX Structure */
#include <pshpack1.h>
typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
#include <poppack.h>

#include "../3RVX/3RVX.h"
#include "../3RVX/CommCtl.h"
#include "../3RVX/LanguageTranslator.h"
#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "Tabs/General.h"
#include "Tabs/Display.h"
#include "Tabs/OSD.h"
#include "Tabs/Hotkeys.h"
#include "Tabs/About.h"
#include "UITranslator.h"
#include "Updater/Updater.h"
#include "Updater/UpdaterWindow.h"

/* Needed to determine whether the Apply button is enabled/disabled */
static const int IDD_APPLYNOW = 0x3021;

const wchar_t *MUTEX_NAME = L"Local\\3RVXSettings";
HANDLE mutex;
HWND tabWnd = NULL;
bool relaunch = false;

int APIENTRY wWinMain(
        _In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPTSTR lpCmdLine,
        _In_ int nCmdShow) {

	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

    Logger::Start();
    CLOG(L"Starting SettingsUI...");

    bool alreadyRunning = false;
    mutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
            CloseHandle(mutex);
        }
        alreadyRunning = true;
    }

    /* Inspect command line parameters to determine whether this settings
     * instance is being launched as an update checker. */
    std::wstring cmdLine(lpCmdLine);
    if (cmdLine.find(L"-update") != std::wstring::npos) {
        if (alreadyRunning) {
            return EXIT_SUCCESS;
        } else {
            /* If this is the only settings instance running, we release the
             * mutex so that the user can launch the settings app. If this
             * happens, the updater is closed to prevent settings file race
             * conditions. */
            if (mutex) {
                ReleaseMutex(mutex);
                CloseHandle(mutex);
            }
        }

        if (Updater::NewerVersionAvailable()) {
            Settings::Instance()->Load();
            CLOG(L"An update is available. Showing update icon.");
            UpdaterWindow uw;
            PostMessage(
                uw.Handle(),
                _3RVX::WM_3RVX_SETTINGSCTRL,
                _3RVX::MSG_UPDATEICON,
                NULL);
            uw.DoModal();
        } else {
#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
            CLOG(L"No update available. Press [enter] to terminate");
            std::cin.get();
#endif
        }

        /* Process was used for updates; time to quit. */
        return EXIT_SUCCESS;
    }

    if (alreadyRunning) {
        HWND settingsWnd = _3RVX::MasterSettingsHwnd();
        CLOG(L"A settings instance is already running. Moving window [%d] "
            L"to the foreground.", (int) settingsWnd);
        SetForegroundWindow(settingsWnd);
        SendMessage(
            settingsWnd,
            _3RVX::WM_3RVX_SETTINGSCTRL,
            _3RVX::MSG_ACTIVATE,
            NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    HWND updater = _3RVX::UpdaterHwnd();
    if (updater != 0) {
        CLOG(L"Telling updater to close");
        SendMessage(updater, WM_CLOSE, 0, 0);
    }

    SettingsUI mainWnd(hInstance);
    INT_PTR result;
    do {
        result = mainWnd.LaunchPropertySheet();
        CLOG(L"Relaunch: %s", relaunch ? L"TRUE" : L"FALSE");
    } while (relaunch == true);

    return result;
}

SettingsUI::SettingsUI(HINSTANCE hInstance) :
Window(
        Window::Builder(_3RVX::CLASS_3RVX_SETTINGS)
        .Title(_3RVX::CLASS_3RVX_SETTINGS)
        .InstanceHandle(hInstance)
        .Icon(LoadIcon(NULL, MAKEINTRESOURCE(IDI_SETTINGS)))
        .Build()) {

    Settings::Instance()->Load();

    _tabs.push_back((_general = new General));
    _tabs.push_back((_display = new Display));
    _tabs.push_back((_osd = new OSD));
    _tabs.push_back((_hotkeys = new Hotkeys));
    _tabs.push_back((_about = new About));
}

INT_PTR SettingsUI::LaunchPropertySheet() {
    HPROPSHEETPAGE *pages = new HPROPSHEETPAGE[_tabs.size()];
    for (size_t i = 0; i < _tabs.size(); ++i) {
        pages[i] = _tabs[i]->PageHandle();
    }

    PROPSHEETHEADER psh = { 0 };
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_USECALLBACK;
    psh.hwndParent = Window::Handle();
    psh.hInstance = Window::InstanceHandle();
    psh.pszIcon = MAKEINTRESOURCE(IDI_SETTINGS);
    psh.pszCaption = L"3RVX Settings";
    psh.nStartPage = 0;
    psh.nPages = _tabs.size();
    psh.phpage = pages;
    psh.pfnCallback = PropSheetProc;

    tabWnd = NULL;

    /* Position the window if this is the first launch */
    if (relaunch == false) {
        POINT pt = { 0 };
        GetCursorPos(&pt);
        MoveWindow(Window::Handle(),
            pt.x - XOFFSET, pt.y - YOFFSET, 0, 0, TRUE);
    }

    relaunch = false;

    CLOG(L"Launching modal property sheet.");
    return PropertySheet(&psh);
}

LRESULT SettingsUI::WndProc(
        HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    if (message == WM_DESTROY) {
        PostQuitMessage(0);
    } else if (message == _3RVX::WM_3RVX_SETTINGSCTRL) {
        switch (wParam) {
        case _3RVX::MSG_ACTIVATE:
            CLOG(L"Received request to activate window from external program");
            SetActiveWindow(tabWnd);
            break;

        case _3RVX::MSG_MUSTRESTART:
            relaunch = true;
            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}

int CALLBACK PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam) {
    switch (msg) {
    case PSCB_PRECREATE:
        /* Disable the help button: */
        if (((LPDLGTEMPLATEEX) lParam)->signature == 0xFFFF) {
            ((LPDLGTEMPLATEEX) lParam)->style &= ~DS_CONTEXTHELP;
        } else {
            ((LPDLGTEMPLATE) lParam)->style &= ~DS_CONTEXTHELP;
        }

        /* Show window in the taskbar: */
        ((LPDLGTEMPLATE) lParam)->dwExtendedStyle |= WS_EX_APPWINDOW;
        break;

    case PSCB_INITIALIZED:
        UITranslator::TranslateWindowText(hWnd);

        if (tabWnd == NULL) {
            tabWnd = hWnd;
        }

        /* These values are hard-coded in case the user has a non-english GUI
           but wants to change the program language */
        UITranslator::TranslateControlText(
            hWnd, IDOK, std::wstring(L"OK"));
        UITranslator::TranslateControlText(
            hWnd, IDCANCEL, std::wstring(L"Cancel"));
        UITranslator::TranslateControlText(
            hWnd, IDD_APPLYNOW, std::wstring(L"Apply"));
        break;

    case PSCB_BUTTONPRESSED:
        if (lParam == PSBTN_OK || lParam == PSBTN_APPLYNOW) {
            HWND hApply = GetDlgItem(hWnd, IDD_APPLYNOW);
            if (IsWindowEnabled(hApply)) {
                /* Save settings*/
                CLOG(L"Saving settings...");
//                for (SettingsTab *tab : _tabs) {
//                    tab->SaveSettings();
//                }
                Settings::Instance()->Save();

                CLOG(L"Notifying 3RVX process of settings change");
                _3RVX::Message(_3RVX::MSG_LOAD, NULL, true);

                if (lParam == PSBTN_APPLYNOW && relaunch == true) {
                    /* Language was changed */
                    SendMessage(tabWnd, WM_CLOSE, NULL, NULL);
                } else {
                    relaunch = false;
                }
            }
        }
        break;
    }

    return TRUE;
}<commit_msg>Use names in propsheet proc consistent with W32 API reference<commit_after>#include "SettingsUI.h"

#include <iostream>

/* DLGTEMPLATEEX Structure */
#include <pshpack1.h>
typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
#include <poppack.h>

#include "../3RVX/3RVX.h"
#include "../3RVX/CommCtl.h"
#include "../3RVX/LanguageTranslator.h"
#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "Tabs/General.h"
#include "Tabs/Display.h"
#include "Tabs/OSD.h"
#include "Tabs/Hotkeys.h"
#include "Tabs/About.h"
#include "UITranslator.h"
#include "Updater/Updater.h"
#include "Updater/UpdaterWindow.h"

/* Needed to determine whether the Apply button is enabled/disabled */
static const int IDD_APPLYNOW = 0x3021;

const wchar_t *MUTEX_NAME = L"Local\\3RVXSettings";
HANDLE mutex;
HWND tabWnd = NULL;
bool relaunch = false;

int APIENTRY wWinMain(
        _In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPTSTR lpCmdLine,
        _In_ int nCmdShow) {

	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

    Logger::Start();
    CLOG(L"Starting SettingsUI...");

    bool alreadyRunning = false;
    mutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
            CloseHandle(mutex);
        }
        alreadyRunning = true;
    }

    /* Inspect command line parameters to determine whether this settings
     * instance is being launched as an update checker. */
    std::wstring cmdLine(lpCmdLine);
    if (cmdLine.find(L"-update") != std::wstring::npos) {
        if (alreadyRunning) {
            return EXIT_SUCCESS;
        } else {
            /* If this is the only settings instance running, we release the
             * mutex so that the user can launch the settings app. If this
             * happens, the updater is closed to prevent settings file race
             * conditions. */
            if (mutex) {
                ReleaseMutex(mutex);
                CloseHandle(mutex);
            }
        }

        if (Updater::NewerVersionAvailable()) {
            Settings::Instance()->Load();
            CLOG(L"An update is available. Showing update icon.");
            UpdaterWindow uw;
            PostMessage(
                uw.Handle(),
                _3RVX::WM_3RVX_SETTINGSCTRL,
                _3RVX::MSG_UPDATEICON,
                NULL);
            uw.DoModal();
        } else {
#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
            CLOG(L"No update available. Press [enter] to terminate");
            std::cin.get();
#endif
        }

        /* Process was used for updates; time to quit. */
        return EXIT_SUCCESS;
    }

    if (alreadyRunning) {
        HWND settingsWnd = _3RVX::MasterSettingsHwnd();
        CLOG(L"A settings instance is already running. Moving window [%d] "
            L"to the foreground.", (int) settingsWnd);
        SetForegroundWindow(settingsWnd);
        SendMessage(
            settingsWnd,
            _3RVX::WM_3RVX_SETTINGSCTRL,
            _3RVX::MSG_ACTIVATE,
            NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    HWND updater = _3RVX::UpdaterHwnd();
    if (updater != 0) {
        CLOG(L"Telling updater to close");
        SendMessage(updater, WM_CLOSE, 0, 0);
    }

    SettingsUI mainWnd(hInstance);
    INT_PTR result;
    do {
        result = mainWnd.LaunchPropertySheet();
        CLOG(L"Relaunch: %s", relaunch ? L"TRUE" : L"FALSE");
    } while (relaunch == true);

    return result;
}

SettingsUI::SettingsUI(HINSTANCE hInstance) :
Window(
        Window::Builder(_3RVX::CLASS_3RVX_SETTINGS)
        .Title(_3RVX::CLASS_3RVX_SETTINGS)
        .InstanceHandle(hInstance)
        .Icon(LoadIcon(NULL, MAKEINTRESOURCE(IDI_SETTINGS)))
        .Build()) {

    Settings::Instance()->Load();

    _tabs.push_back((_general = new General));
    _tabs.push_back((_display = new Display));
    _tabs.push_back((_osd = new OSD));
    _tabs.push_back((_hotkeys = new Hotkeys));
    _tabs.push_back((_about = new About));
}

INT_PTR SettingsUI::LaunchPropertySheet() {
    HPROPSHEETPAGE *pages = new HPROPSHEETPAGE[_tabs.size()];
    for (size_t i = 0; i < _tabs.size(); ++i) {
        pages[i] = _tabs[i]->PageHandle();
    }

    PROPSHEETHEADER psh = { 0 };
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_USECALLBACK;
    psh.hwndParent = Window::Handle();
    psh.hInstance = Window::InstanceHandle();
    psh.pszIcon = MAKEINTRESOURCE(IDI_SETTINGS);
    psh.pszCaption = L"3RVX Settings";
    psh.nStartPage = 0;
    psh.nPages = _tabs.size();
    psh.phpage = pages;
    psh.pfnCallback = PropSheetProc;

    tabWnd = NULL;

    /* Position the window if this is the first launch */
    if (relaunch == false) {
        POINT pt = { 0 };
        GetCursorPos(&pt);
        MoveWindow(Window::Handle(),
            pt.x - XOFFSET, pt.y - YOFFSET, 0, 0, TRUE);
    }

    relaunch = false;

    CLOG(L"Launching modal property sheet.");
    return PropertySheet(&psh);
}

LRESULT SettingsUI::WndProc(
        HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    if (message == WM_DESTROY) {
        PostQuitMessage(0);
    } else if (message == _3RVX::WM_3RVX_SETTINGSCTRL) {
        switch (wParam) {
        case _3RVX::MSG_ACTIVATE:
            CLOG(L"Received request to activate window from external program");
            SetActiveWindow(tabWnd);
            break;

        case _3RVX::MSG_MUSTRESTART:
            relaunch = true;
            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}

int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) {
    switch (uMsg) {
    case PSCB_PRECREATE:
        /* Disable the help button: */
        if (((LPDLGTEMPLATEEX) lParam)->signature == 0xFFFF) {
            ((LPDLGTEMPLATEEX) lParam)->style &= ~DS_CONTEXTHELP;
        } else {
            ((LPDLGTEMPLATE) lParam)->style &= ~DS_CONTEXTHELP;
        }

        /* Show window in the taskbar: */
        ((LPDLGTEMPLATE) lParam)->dwExtendedStyle |= WS_EX_APPWINDOW;
        break;

    case PSCB_INITIALIZED:
        UITranslator::TranslateWindowText(hwndDlg);

        if (tabWnd == NULL) {
            tabWnd = hwndDlg;
        }

        /* These values are hard-coded in case the user has a non-english GUI
           but wants to change the program language */
        UITranslator::TranslateControlText(
            hwndDlg, IDOK, std::wstring(L"OK"));
        UITranslator::TranslateControlText(
            hwndDlg, IDCANCEL, std::wstring(L"Cancel"));
        UITranslator::TranslateControlText(
            hwndDlg, IDD_APPLYNOW, std::wstring(L"Apply"));
        break;

    case PSCB_BUTTONPRESSED:
        if (lParam == PSBTN_OK || lParam == PSBTN_APPLYNOW) {
            HWND hApply = GetDlgItem(hwndDlg, IDD_APPLYNOW);
            if (IsWindowEnabled(hApply)) {
                /* Save settings*/
                CLOG(L"Saving settings...");
//                for (SettingsTab *tab : _tabs) {
//                    tab->SaveSettings();
//                }
                Settings::Instance()->Save();

                CLOG(L"Notifying 3RVX process of settings change");
                _3RVX::Message(_3RVX::MSG_LOAD, NULL, true);

                if (lParam == PSBTN_APPLYNOW && relaunch == true) {
                    /* Language was changed */
                    SendMessage(tabWnd, WM_CLOSE, NULL, NULL);
                } else {
                    relaunch = false;
                }
            }
        }
        break;
    }

    return TRUE;
}<|endoftext|>


<commit_before>//
// Created by Shubin Fedor on 19/08/14.
// Copyright (c) 2014 SOOMLA. All rights reserved.
//

#include "CCGate.h"
#include "CCLevelUpConsts.h"
#include "CCGateStorage.h"

namespace soomla {

#define TAG "SOOMLA Gate"

    bool CCGate::init(cocos2d::__String *id, cocos2d::__String *name) {
        if (!name) {
            name = cocos2d::__String::create("");
        }
        bool result = CCSoomlaEntity::init(id, name, NULL);

        if (result) {
            registerEvents();

            return true;
        }

        return result;
    }

    bool CCGate::initWithDictionary(cocos2d::__Dictionary *dict) {
        bool result = CCSoomlaEntity::initWithDictionary(dict);

        if (result) {
            registerEvents();

            return true;
        }

        return result;
    }

    char const *CCGate::getType() const {
        return CCLevelUpConsts::JSON_JSON_TYPE_GATE;
    }

    bool CCGate::open() {
        //  check in gate storage if it's already open
        if (CCGateStorage::getInstance()->isOpen(this)) {
            return true;
        }
        return openInner();
    }

    void CCGate::forceOpen(bool open) {
        if (isOpen() == open) {
            // if it's already open why open it again?
            return;
        }

        CCGateStorage::getInstance()->setOpen(this, open);
        if (open) {
            unregisterEvents();
        } else {
            // we can do this here ONLY becasue we check 'isOpen == open' a few lines above.
            registerEvents();
        }
    }

    bool CCGate::isOpen() {
        return CCGateStorage::getInstance()->isOpen(this);
    }

    bool CCGate::canOpen() {
        // check in gate storage if the gate is open
        if (CCGateStorage::getInstance()->isOpen(this)) {
            return true;
        }

        return canOpenInner();
    }

}
<commit_msg>fix gate logic<commit_after>//
// Created by Shubin Fedor on 19/08/14.
// Copyright (c) 2014 SOOMLA. All rights reserved.
//

#include "CCGate.h"
#include "CCLevelUpConsts.h"
#include "CCGateStorage.h"

namespace soomla {

#define TAG "SOOMLA Gate"

    bool CCGate::init(cocos2d::__String *id, cocos2d::__String *name) {
        if (!name) {
            name = cocos2d::__String::create("");
        }
        bool result = CCSoomlaEntity::init(id, name, NULL);

        if (result) {
            registerEvents();

            return true;
        }

        return result;
    }

    bool CCGate::initWithDictionary(cocos2d::__Dictionary *dict) {
        bool result = CCSoomlaEntity::initWithDictionary(dict);

        if (result) {
            registerEvents();

            return true;
        }

        return result;
    }

    char const *CCGate::getType() const {
        return CCLevelUpConsts::JSON_JSON_TYPE_GATE;
    }

    bool CCGate::open() {
        //  check in gate storage if it's already open
        if (CCGateStorage::getInstance()->isOpen(this)) {
            return true;
        }
        return openInner();
    }

    void CCGate::forceOpen(bool open) {
        if (isOpen() == open) {
            // if it's already open why open it again?
            return;
        }

        CCGateStorage::getInstance()->setOpen(this, open);
        if (open) {
            unregisterEvents();
        } else {
            // we can do this here ONLY becasue we check 'isOpen == open' a few lines above.
            registerEvents();
        }
    }

    bool CCGate::isOpen() {
        return CCGateStorage::getInstance()->isOpen(this);
    }

    bool CCGate::canOpen() {
        // check in gate storage if the gate is open
        if (CCGateStorage::getInstance()->isOpen(this)) {
            return false;
        }

        return canOpenInner();
    }

}
<|endoftext|>


<commit_before>#ifndef DUCK_H
#include "Duck.h"
#endif

#ifndef MALLARDUCK_H
#include "MallardDuck.h"
#endif

#ifndef REDHEADDUCK_H
#include "RedHeadDuck.h"
#endif

#ifndef RUBBERDUCK_H
#include "RubberDuck.h"
#endif

#ifndef FLYBEHAVIOR_H
#include "flyBehavior.h"
#endif

#ifndef QUACKBEHAVIOR_H
#include "QuackBehavior.h"
#endif

#include <iostream>
#include <algorithm>
#include <vector>

void makeDuckDo( Duck *singleDuck )
{
  std::cout << std::endl;

  singleDuck->fly();
  singleDuck->quack();
  singleDuck->swim();
  singleDuck->display();

  std::cout << std::endl;
}

void makeDuckDie( Duck *singleDuck )
{
  delete singleDuck;
  singleDuck = 0;
}

int main( int argc, char **argv )
{
  std::cout << "Example of Inheritance Issue: " << std::endl;

  std::vector< Duck* > barrel;

  barrel.push_back( new Duck() );
  barrel.push_back( new MallardDuck() );
  barrel.push_back( new RedHeadDuck() );
  barrel.push_back( new RubberDuck() );

  for_each( barrel.begin(), barrel.end(), makeDuckDo );
  std::cout << " !It's hunting season! " << std::endl;
  for_each( barrel.begin(), barrel.end(), makeDuckDie );

  return 0;
}
<commit_msg>Fixed captialization in included filename<commit_after>#ifndef DUCK_H
#include "Duck.h"
#endif

#ifndef MALLARDUCK_H
#include "MallardDuck.h"
#endif

#ifndef REDHEADDUCK_H
#include "RedHeadDuck.h"
#endif

#ifndef RUBBERDUCK_H
#include "RubberDuck.h"
#endif

#ifndef FLYBEHAVIOR_H
#include "FlyBehavior.h"
#endif

#ifndef QUACKBEHAVIOR_H
#include "QuackBehavior.h"
#endif

#include <iostream>
#include <algorithm>
#include <vector>

void makeDuckDo( Duck *singleDuck )
{
  std::cout << std::endl;

  singleDuck->fly();
  singleDuck->quack();
  singleDuck->swim();
  singleDuck->display();

  std::cout << std::endl;
}

void makeDuckDie( Duck *singleDuck )
{
  delete singleDuck;
  singleDuck = 0;
}

int main( int argc, char **argv )
{
  std::cout << "Example of Inheritance Issue: " << std::endl;

  std::vector< Duck* > barrel;

  barrel.push_back( new Duck() );
  barrel.push_back( new MallardDuck() );
  barrel.push_back( new RedHeadDuck() );
  barrel.push_back( new RubberDuck() );

  for_each( barrel.begin(), barrel.end(), makeDuckDo );
  std::cout << " !It's hunting season! " << std::endl;
  for_each( barrel.begin(), barrel.end(), makeDuckDie );

  return 0;
}
<|endoftext|>


<commit_before>#pragma once

#define GIF_FRAME_LENGTH 33

#include "concurrentmap.hpp"
#include "emojis.hpp"
#include "messages/lazyloadedimage.hpp"
#include "signalvector.hpp"
#include "twitch/emotevalue.hpp"

#include <QMap>
#include <QMutex>
#include <QRegularExpression>
#include <QString>
#include <QTimer>
#include <boost/signals2.hpp>

namespace chatterino {

struct EmoteData {
    EmoteData()
    {
    }

    EmoteData(messages::LazyLoadedImage *_image)
        : image(_image)
    {
    }

    messages::LazyLoadedImage *image = nullptr;
};

typedef ConcurrentMap<QString, EmoteData> EmoteMap;

class EmoteManager
{
    EmoteManager();

public:
    static EmoteManager &getInstance()
    {
        static EmoteManager instance;
        return instance;
    }

    void loadGlobalEmotes();

    void reloadBTTVChannelEmotes(const QString &channelName,
                                 std::weak_ptr<EmoteMap> channelEmoteMap);
    void reloadFFZChannelEmotes(const QString &channelName,
                                std::weak_ptr<EmoteMap> channelEmoteMap);

    ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes();
    EmoteMap &getFFZEmotes();
    EmoteMap &getChatterinoEmotes();
    EmoteMap &getBTTVChannelEmoteFromCaches();
    EmoteMap &getEmojis();
    ConcurrentMap<int, EmoteData> &getFFZChannelEmoteFromCaches();
    ConcurrentMap<long, EmoteData> &getTwitchEmoteFromCache();

    EmoteData getCheerImage(long long int amount, bool animated);

    EmoteData getTwitchEmoteById(long int id, const QString &emoteName);

    int getGeneration()
    {
        return _generation;
    }

    void incGeneration()
    {
        _generation++;
    }

    boost::signals2::signal<void()> &getGifUpdateSignal();

    // Bit badge/emotes?
    ConcurrentMap<QString, messages::LazyLoadedImage *> miscImageCache;

private:
    /// Emojis
    QRegularExpression findShortCodesRegex;

    // shortCodeToEmoji maps strings like "sunglasses" to its emoji
    QMap<QString, EmojiData> emojiShortCodeToEmoji;

    // Maps the first character of the emoji unicode string to a vector of possible emojis
    QMap<QChar, QVector<EmojiData>> emojiFirstByte;

    //            url      Emoji-one image
    EmoteMap emojiCache;
    EmoteMap emojis;

    void loadEmojis();

public:
    void parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords, const QString &text);

    QString replaceShortCodes(const QString &text);

    std::vector<std::string> emojiShortCodes;

    /// Twitch emotes
    void refreshTwitchEmotes(const std::string &roomID);

    struct TwitchAccountEmoteData {
        struct TwitchEmote {
            std::string id;
            std::string code;
        };

        //       emote set
        std::map<std::string, std::vector<TwitchEmote>> emoteSets;

        std::vector<std::string> emoteCodes;

        bool filled = false;
    };

    std::map<std::string, TwitchAccountEmoteData> twitchAccountEmotes;

private:
    //            emote code
    ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;

    //        emote id
    ConcurrentMap<long, EmoteData> _twitchEmoteFromCache;

    /// BTTV emotes
    EmoteMap bttvChannelEmotes;

public:
    ConcurrentMap<QString, EmoteMap> bttvChannels;
    EmoteMap bttvGlobalEmotes;
    SignalVector<std::string> bttvGlobalEmoteCodes;
    //       roomID
    std::map<std::string, SignalVector<std::string>> bttvChannelEmoteCodes;
    EmoteMap _bttvChannelEmoteFromCaches;

private:
    void loadBTTVEmotes();

    /// FFZ emotes
    EmoteMap ffzChannelEmotes;

public:
    ConcurrentMap<QString, EmoteMap> ffzChannels;
    EmoteMap ffzGlobalEmotes;
    SignalVector<std::string> ffzGlobalEmoteCodes;
    std::map<std::string, SignalVector<std::string>> ffzChannelEmoteCodes;

private:
    ConcurrentMap<int, EmoteData> _ffzChannelEmoteFromCaches;

    void loadFFZEmotes();

    /// Chatterino emotes
    EmoteMap _chatterinoEmotes;

    boost::signals2::signal<void()> gifUpdateTimerSignal;
    QTimer gifUpdateTimer;
    bool gifUpdateTimerInitiated = false;

    // methods
    static QString getTwitchEmoteLink(long id, qreal &scale);
};

}  // namespace chatterino
<commit_msg>re-add variable I accidentally removed<commit_after>#pragma once

#define GIF_FRAME_LENGTH 33

#include "concurrentmap.hpp"
#include "emojis.hpp"
#include "messages/lazyloadedimage.hpp"
#include "signalvector.hpp"
#include "twitch/emotevalue.hpp"

#include <QMap>
#include <QMutex>
#include <QRegularExpression>
#include <QString>
#include <QTimer>
#include <boost/signals2.hpp>

namespace chatterino {

struct EmoteData {
    EmoteData()
    {
    }

    EmoteData(messages::LazyLoadedImage *_image)
        : image(_image)
    {
    }

    messages::LazyLoadedImage *image = nullptr;
};

typedef ConcurrentMap<QString, EmoteData> EmoteMap;

class EmoteManager
{
    EmoteManager();

public:
    static EmoteManager &getInstance()
    {
        static EmoteManager instance;
        return instance;
    }

    void loadGlobalEmotes();

    void reloadBTTVChannelEmotes(const QString &channelName,
                                 std::weak_ptr<EmoteMap> channelEmoteMap);
    void reloadFFZChannelEmotes(const QString &channelName,
                                std::weak_ptr<EmoteMap> channelEmoteMap);

    ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes();
    EmoteMap &getFFZEmotes();
    EmoteMap &getChatterinoEmotes();
    EmoteMap &getBTTVChannelEmoteFromCaches();
    EmoteMap &getEmojis();
    ConcurrentMap<int, EmoteData> &getFFZChannelEmoteFromCaches();
    ConcurrentMap<long, EmoteData> &getTwitchEmoteFromCache();

    EmoteData getCheerImage(long long int amount, bool animated);

    EmoteData getTwitchEmoteById(long int id, const QString &emoteName);

    int getGeneration()
    {
        return _generation;
    }

    void incGeneration()
    {
        _generation++;
    }

    boost::signals2::signal<void()> &getGifUpdateSignal();

    // Bit badge/emotes?
    ConcurrentMap<QString, messages::LazyLoadedImage *> miscImageCache;

private:
    /// Emojis
    QRegularExpression findShortCodesRegex;

    // shortCodeToEmoji maps strings like "sunglasses" to its emoji
    QMap<QString, EmojiData> emojiShortCodeToEmoji;

    // Maps the first character of the emoji unicode string to a vector of possible emojis
    QMap<QChar, QVector<EmojiData>> emojiFirstByte;

    //            url      Emoji-one image
    EmoteMap emojiCache;
    EmoteMap emojis;

    void loadEmojis();

public:
    void parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords, const QString &text);

    QString replaceShortCodes(const QString &text);

    std::vector<std::string> emojiShortCodes;

    /// Twitch emotes
    void refreshTwitchEmotes(const std::string &roomID);

    struct TwitchAccountEmoteData {
        struct TwitchEmote {
            std::string id;
            std::string code;
        };

        //       emote set
        std::map<std::string, std::vector<TwitchEmote>> emoteSets;

        std::vector<std::string> emoteCodes;

        bool filled = false;
    };

    std::map<std::string, TwitchAccountEmoteData> twitchAccountEmotes;

private:
    //            emote code
    ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;

    //        emote id
    ConcurrentMap<long, EmoteData> _twitchEmoteFromCache;

    /// BTTV emotes
    EmoteMap bttvChannelEmotes;

public:
    ConcurrentMap<QString, EmoteMap> bttvChannels;
    EmoteMap bttvGlobalEmotes;
    SignalVector<std::string> bttvGlobalEmoteCodes;
    //       roomID
    std::map<std::string, SignalVector<std::string>> bttvChannelEmoteCodes;
    EmoteMap _bttvChannelEmoteFromCaches;

private:
    void loadBTTVEmotes();

    /// FFZ emotes
    EmoteMap ffzChannelEmotes;

public:
    ConcurrentMap<QString, EmoteMap> ffzChannels;
    EmoteMap ffzGlobalEmotes;
    SignalVector<std::string> ffzGlobalEmoteCodes;
    std::map<std::string, SignalVector<std::string>> ffzChannelEmoteCodes;

private:
    ConcurrentMap<int, EmoteData> _ffzChannelEmoteFromCaches;

    void loadFFZEmotes();

    /// Chatterino emotes
    EmoteMap _chatterinoEmotes;

    boost::signals2::signal<void()> gifUpdateTimerSignal;
    QTimer gifUpdateTimer;
    bool gifUpdateTimerInitiated = false;

    int _generation = 0;

    // methods
    static QString getTwitchEmoteLink(long id, qreal &scale);
};

}  // namespace chatterino
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkDICOMImageIO2Test.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include <list>
#include <fstream>
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImage.h"
#include "itkRescaleIntensityImageFilter.h"

int itkDICOMImageIO2Test(int ac, char* av[])
{

  if(ac < 3)
  {
    std::cerr << "Usage: " << av[0] << " DicomImage OutputImage\n";
    return EXIT_FAILURE;
  }

  // ATTENTION THIS IS THE PIXEL TYPE FOR
  // THE RESULTING IMAGE
  typedef unsigned short PixelType;

  typedef itk::Image<PixelType, 2> myImage;

  itk::ImageFileReader<myImage>::Pointer reader
                                  = itk::ImageFileReader<myImage>::New();
  // Register on factory capable of creating DicomImage readers
  itk::DICOMImageIO2Factory::RegisterOneFactory();

  reader->SetFileName(av[1]);

  try
  {
    reader->Update();
  }
  catch (itk::ExceptionObject & e)
  {
    std::cerr << "exception in file reader " << std::endl;
    std::cerr << e.GetDescription() << std::endl;
    std::cerr << e.GetLocation() << std::endl;
    return EXIT_FAILURE;
  }

  typedef unsigned char WritePixelType;

  typedef itk::Image< WritePixelType, 2 > WriteImageType;

  typedef itk::RescaleIntensityImageFilter<
               myImage, WriteImageType > RescaleFilterType;

  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

  rescaler->SetOutputMinimum(   0 );
  rescaler->SetOutputMaximum( 255 );

  typedef itk::ImageFileWriter< WriteImageType >  WriterType;

  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName( av[2] );

  // Software Guide : BeginCodeSnippet
  rescaler->SetInput( reader->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );
  writer->Update();
  return EXIT_SUCCESS;

}
<commit_msg>Added include for DICOMImageIO2Factory<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkDICOMImageIO2Test.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include <list>
#include <fstream>
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImage.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkDICOMImageIO2Factory.h"

int itkDICOMImageIO2Test(int ac, char* av[])
{

  if(ac < 3)
  {
    std::cerr << "Usage: " << av[0] << " DicomImage OutputImage\n";
    return EXIT_FAILURE;
  }

  // ATTENTION THIS IS THE PIXEL TYPE FOR
  // THE RESULTING IMAGE
  typedef unsigned short PixelType;

  typedef itk::Image<PixelType, 2> myImage;

  itk::ImageFileReader<myImage>::Pointer reader
                                  = itk::ImageFileReader<myImage>::New();
  // Register on factory capable of creating DicomImage readers
  itk::DICOMImageIO2Factory::RegisterOneFactory();

  reader->SetFileName(av[1]);

  try
  {
    reader->Update();
  }
  catch (itk::ExceptionObject & e)
  {
    std::cerr << "exception in file reader " << std::endl;
    std::cerr << e.GetDescription() << std::endl;
    std::cerr << e.GetLocation() << std::endl;
    return EXIT_FAILURE;
  }

  typedef unsigned char WritePixelType;

  typedef itk::Image< WritePixelType, 2 > WriteImageType;

  typedef itk::RescaleIntensityImageFilter<
               myImage, WriteImageType > RescaleFilterType;

  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

  rescaler->SetOutputMinimum(   0 );
  rescaler->SetOutputMaximum( 255 );

  typedef itk::ImageFileWriter< WriteImageType >  WriterType;

  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName( av[2] );

  // Software Guide : BeginCodeSnippet
  rescaler->SetInput( reader->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );
  writer->Update();
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>/*====================================================================
Copyright(c) 2016 Adam Rankin

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

// Local includes
#include "pch.h"
#include "IGTLinkClient.h"
#include "IGTCommon.h"
#include "TrackedFrameMessage.h"

// IGT includes
#include "igtlCommandMessage.h"
#include "igtlCommon.h"
#include "igtlMessageHeader.h"
#include "igtlOSUtil.h"
#include "igtlStatusMessage.h"

// STD includes
#include <chrono>
#include <regex>

// Windows includes
#include <collection.h>
#include <pplawait.h>
#include <ppltasks.h>
#include <robuffer.h>

using namespace Concurrency;
using namespace Windows::Foundation;
using namespace Platform::Collections;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Data::Xml::Dom;

namespace UWPOpenIGTLink
{

  const int IGTLinkClient::CLIENT_SOCKET_TIMEOUT_MSEC = 500;
  const uint32 IGTLinkClient::MESSAGE_LIST_MAX_SIZE = 200;

  //----------------------------------------------------------------------------
  IGTLinkClient::IGTLinkClient()
    : m_igtlMessageFactory( igtl::MessageFactory::New() )
    , m_clientSocket( igtl::ClientSocket::New() )
  {
    m_igtlMessageFactory->AddMessageType( "TRACKEDFRAME", ( igtl::MessageFactory::PointerToMessageBaseNew )&igtl::TrackedFrameMessage::New );
    this->ServerHost = L"127.0.0.1";
    this->ServerPort = 18944;
    this->ServerIGTLVersion = IGTL_HEADER_VERSION_2;

    this->m_frameSize.assign( 3, 0 );
  }

  //----------------------------------------------------------------------------
  IGTLinkClient::~IGTLinkClient()
  {
    this->Disconnect();
    auto disconnectTask = concurrency::create_task( [this]()
    {
      while ( this->Connected )
      {
        Sleep( 33 );
      }
    } );
    disconnectTask.wait();
  }

  //----------------------------------------------------------------------------
  IAsyncOperation<bool>^ IGTLinkClient::ConnectAsync( double timeoutSec )
  {
    this->Disconnect();

    this->m_cancellationTokenSource = cancellation_token_source();

    return create_async( [ = ]() -> bool
    {
      const int retryDelaySec = 1.0;
      int errorCode = 1;
      auto start = std::chrono::high_resolution_clock::now();
      while ( errorCode != 0 )
      {
        std::wstring wideStr( this->ServerHost->Begin() );
        std::string str( wideStr.begin(), wideStr.end() );
        errorCode = this->m_clientSocket->ConnectToServer( str.c_str(), this->ServerPort );
        std::chrono::duration<double, std::milli> timeDiff = std::chrono::high_resolution_clock::now() - start;
        if ( timeDiff.count() > timeoutSec * 1000 )
        {
          // time is up
          break;
        }
        std::this_thread::sleep_for( std::chrono::seconds( retryDelaySec ) );
      }

      if ( errorCode != 0 )
      {
        return false;
      }

      this->m_clientSocket->SetTimeout( CLIENT_SOCKET_TIMEOUT_MSEC );

      // We're connected, start the data receiver thread
      create_task( [this]( void )
      {
        this->DataReceiverPump( this, m_cancellationTokenSource.get_token() );
      } );

      return true;
    } );
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::Disconnect()
  {
    this->m_cancellationTokenSource.cancel();

    {
      critical_section::scoped_lock lock( this->m_socketMutex );
      this->m_clientSocket->CloseSocket();
    }
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::GetLatestTrackedFrame( TrackedFrame^ frame, double* latestTimestamp )
  {
    igtl::TrackedFrameMessage::Pointer trackedFrameMsg = nullptr;
    {
      // Retrieve the next available tracked frame reply
      Concurrency::critical_section::scoped_lock lock( m_messageListMutex );
      for ( auto replyIter = m_messages.rbegin(); replyIter != m_messages.rend(); ++replyIter )
      {
        if ( typeid( *( *replyIter ) ) == typeid( igtl::TrackedFrameMessage ) )
        {
          trackedFrameMsg = dynamic_cast<igtl::TrackedFrameMessage*>( ( *replyIter ).GetPointer() );
          break;
        }
      }

      // No message found
      return false;
    }

    if ( latestTimestamp != nullptr )
    {
      auto ts = igtl::TimeStamp::New();
      trackedFrameMsg->GetTimeStamp( ts );

      if ( ts->GetTimeStamp() <= *latestTimestamp )
      {
        // No new messages since requested timestamp
        return false;
      }
      else
      {
        *latestTimestamp = ts->GetTimeStamp();
      }
    }

    // Tracking/other related fields
    for ( auto pair : trackedFrameMsg->GetMetaData() )
    {
      std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
      std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
      frame->SetCustomFrameField( keyWideStr, valueWideStr );
    }

    for ( auto pair : trackedFrameMsg->GetCustomFrameFields() )
    {
      std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
      std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
      frame->SetCustomFrameField( keyWideStr, valueWideStr );
    }

    // Image related fields
    auto vec = ref new Vector<uint16>;
    vec->Append( trackedFrameMsg->GetFrameSize()[0] );
    vec->Append( trackedFrameMsg->GetFrameSize()[1] );
    vec->Append( trackedFrameMsg->GetFrameSize()[2] );
    frame->FrameSize = vec->GetView();
    igtl::TimeStamp::Pointer ts = igtl::TimeStamp::New();
    trackedFrameMsg->GetTimeStamp( ts );
    frame->Timestamp = ts->GetTimeStamp();
    frame->ImageSizeBytes = trackedFrameMsg->GetImageSizeInBytes();
    frame->SetImageData( trackedFrameMsg->GetImage() );
    frame->NumberOfComponents = trackedFrameMsg->GetNumberOfComponents();
    frame->ScalarType = trackedFrameMsg->GetScalarType();
    frame->SetEmbeddedImageTransform( trackedFrameMsg->GetEmbeddedImageTransform() );
    frame->ImageType = ( uint16 )trackedFrameMsg->GetImageType();
    frame->ImageOrientation = ( uint16 )trackedFrameMsg->GetImageOrientation();

    return true;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::GetLatestCommand( UWPOpenIGTLink::Command^ cmd, double* latestTimestamp )
  {
    igtl::MessageBase::Pointer igtMessage = nullptr;
    {
      // Retrieve the next available tracked frame reply
      Concurrency::critical_section::scoped_lock lock( m_messageListMutex );
      for ( auto replyIter = m_messages.rbegin(); replyIter != m_messages.rend(); ++replyIter )
      {
        if ( typeid( *( *replyIter ) ) == typeid( igtl::RTSCommandMessage ) )
        {
          igtMessage = *replyIter;
          break;
        }
      }
    }

    if ( igtMessage != nullptr )
    {
      if ( latestTimestamp != nullptr )
      {
        auto ts = igtl::TimeStamp::New();
        igtMessage->GetTimeStamp( ts );

        if ( ts->GetTimeStamp() <= *latestTimestamp )
        {
          // No new messages since requested timestamp
          return false;
        }
        else
        {
          *latestTimestamp = ts->GetTimeStamp();
        }
      }

      auto cmdMsg = dynamic_cast<igtl::RTSCommandMessage*>( igtMessage.GetPointer() );

      cmd->CommandContent = ref new Platform::String( std::wstring( cmdMsg->GetCommandContent().begin(), cmdMsg->GetCommandContent().end() ).c_str() );
      cmd->CommandName = ref new Platform::String( std::wstring( cmdMsg->GetCommandName().begin(), cmdMsg->GetCommandName().end() ).c_str() );
      cmd->OriginalCommandId = cmdMsg->GetCommandId();

      XmlDocument^ doc = ref new XmlDocument();
      doc->LoadXml( cmd->CommandContent );

      for ( IXmlNode^ node : doc->ChildNodes )
      {
        if ( dynamic_cast<Platform::String^>( node->NodeName ) == L"Result" )
        {
          cmd->Result = ( dynamic_cast<Platform::String^>( node->NodeValue ) == L"true" );
          break;
        }
      }

      if ( !cmd->Result )
      {
        bool found( false );
        // Parse for the error string
        for ( IXmlNode^ node : doc->ChildNodes )
        {
          if ( dynamic_cast<Platform::String^>( node->NodeName ) == L"Error" )
          {
            cmd->ErrorString = dynamic_cast<Platform::String^>( node->NodeValue );
            found = true;
            break;
          }
        }

        if ( !found )
        {
          // TODO : quiet error reporting
        }
      }

      for ( auto pair : cmdMsg->GetMetaData() )
      {
        std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
        std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
        cmd->Parameters->Insert( ref new Platform::String( keyWideStr.c_str() ), ref new Platform::String( valueWideStr.c_str() ) );
      }

      return true;
    }

    return false;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::SendMessage( igtl::MessageBase::Pointer packedMessage )
  {
    int success = 0;
    {
      critical_section::scoped_lock lock( m_socketMutex );
      success = this->m_clientSocket->Send( packedMessage->GetBufferPointer(), packedMessage->GetBufferSize() );
    }
    if ( !success )
    {
      std::cerr << "OpenIGTLink client couldn't send message to server." << std::endl;
      return false;
    }
    return true;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::DataReceiverPump( IGTLinkClient^ self, concurrency::cancellation_token token )
  {
    LOG_TRACE( L"IGTLinkClient::DataReceiverPump" );

    while ( !token.is_canceled() )
    {
      auto headerMsg = self->m_igtlMessageFactory->CreateHeaderMessage( IGTL_HEADER_VERSION_1 );

      // Receive generic header from the socket
      int numOfBytesReceived = 0;
      {
        critical_section::scoped_lock lock( self->m_socketMutex );
        if ( !self->m_clientSocket->GetConnected() )
        {
          // We've become disconnected while waiting for the socket, we're done here!
          return;
        }
        numOfBytesReceived = self->m_clientSocket->Receive( headerMsg->GetBufferPointer(), headerMsg->GetBufferSize() );
      }
      if ( numOfBytesReceived == 0 // No message received
           || numOfBytesReceived != headerMsg->GetBufferSize() // Received data is not as we expected
         )
      {
        // Failed to receive data, maybe the socket is disconnected
        std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
        continue;
      }

      int c = headerMsg->Unpack( 1 );
      if ( !( c & igtl::MessageHeader::UNPACK_HEADER ) )
      {
        std::cerr << "Failed to receive reply (invalid header)" << std::endl;
        continue;
      }

      igtl::MessageBase::Pointer bodyMsg = nullptr;
      try
      {
        bodyMsg = self->m_igtlMessageFactory->CreateReceiveMessage( headerMsg );
      }
      catch ( const std::exception& )
      {
        // Message header was not correct, skip this message
        // Will be impossible to tell if the body of this message is in the socket... this is a pretty bad corruption.
        // Force re-connect?
        LOG_TRACE( "Corruption in the message header. Serious error." );
        continue;
      }

      if ( bodyMsg.IsNull() )
      {
        LOG_TRACE( "Unable to create message of type: " << headerMsg->GetMessageType() );
        continue;
      }

      // Accept all messages but status messages, they are used as a keep alive mechanism
      if ( typeid( *bodyMsg ) != typeid( igtl::StatusMessage ) )
      {
        {
          critical_section::scoped_lock lock( self->m_socketMutex );
          if ( !self->m_clientSocket->GetConnected() )
          {
            // We've become disconnected while waiting for the socket, we're done here!
            return;
          }
          self->m_clientSocket->Receive( bodyMsg->GetBufferBodyPointer(), bodyMsg->GetBufferBodySize() );
        }

        int c = bodyMsg->Unpack( 1 );
        if ( !( c & igtl::MessageHeader::UNPACK_BODY ) )
        {
          std::cerr << "Failed to receive reply (invalid body)" << std::endl;
          continue;
        }

        {
          // save reply
          critical_section::scoped_lock lock( self->m_messageListMutex );

          self->m_messages.push_back( bodyMsg );
        }
      }
      else
      {
        critical_section::scoped_lock lock( self->m_socketMutex );

        if ( !self->m_clientSocket->GetConnected() )
        {
          // We've become disconnected while waiting for the socket, we're done here!
          return;
        }
        self->m_clientSocket->Skip( headerMsg->GetBodySizeToRead(), 0 );
      }

      if ( self->m_messages.size() > MESSAGE_LIST_MAX_SIZE )
      {
        critical_section::scoped_lock lock( self->m_messageListMutex );

        // erase the front N results
        uint32 toErase = self->m_messages.size() - MESSAGE_LIST_MAX_SIZE;
        self->m_messages.erase( self->m_messages.begin(), self->m_messages.begin() + toErase );
      }
    }

    return;
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::SocketReceive( void* data, int length )
  {
    critical_section::scoped_lock lock( m_socketMutex );
    return m_clientSocket->Receive( data, length );
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::ServerPort::get()
  {
    return this->m_ServerPort;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerPort::set( int arg )
  {
    this->m_ServerPort = arg;
  }

  //----------------------------------------------------------------------------
  Platform::String^ IGTLinkClient::ServerHost::get()
  {
    return this->m_ServerHost;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerHost::set( Platform::String^ arg )
  {
    this->m_ServerHost = arg;
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::ServerIGTLVersion::get()
  {
    return this->m_ServerIGTLVersion;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerIGTLVersion::set( int arg )
  {
    this->m_ServerIGTLVersion = arg;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::Connected::get()
  {
    return this->m_clientSocket->GetConnected();
  }
}<commit_msg>Correcting tracked frame retrieval<commit_after>/*====================================================================
Copyright(c) 2016 Adam Rankin

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

// Local includes
#include "pch.h"
#include "IGTLinkClient.h"
#include "IGTCommon.h"
#include "TrackedFrameMessage.h"

// IGT includes
#include "igtlCommandMessage.h"
#include "igtlCommon.h"
#include "igtlMessageHeader.h"
#include "igtlOSUtil.h"
#include "igtlStatusMessage.h"

// STD includes
#include <chrono>
#include <regex>

// Windows includes
#include <collection.h>
#include <pplawait.h>
#include <ppltasks.h>
#include <robuffer.h>

using namespace Concurrency;
using namespace Windows::Foundation;
using namespace Platform::Collections;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Data::Xml::Dom;

namespace UWPOpenIGTLink
{

  const int IGTLinkClient::CLIENT_SOCKET_TIMEOUT_MSEC = 500;
  const uint32 IGTLinkClient::MESSAGE_LIST_MAX_SIZE = 200;

  //----------------------------------------------------------------------------
  IGTLinkClient::IGTLinkClient()
    : m_igtlMessageFactory( igtl::MessageFactory::New() )
    , m_clientSocket( igtl::ClientSocket::New() )
  {
    m_igtlMessageFactory->AddMessageType( "TRACKEDFRAME", ( igtl::MessageFactory::PointerToMessageBaseNew )&igtl::TrackedFrameMessage::New );
    this->ServerHost = L"127.0.0.1";
    this->ServerPort = 18944;
    this->ServerIGTLVersion = IGTL_HEADER_VERSION_2;

    this->m_frameSize.assign( 3, 0 );
  }

  //----------------------------------------------------------------------------
  IGTLinkClient::~IGTLinkClient()
  {
    this->Disconnect();
    auto disconnectTask = concurrency::create_task( [this]()
    {
      while ( this->Connected )
      {
        Sleep( 33 );
      }
    } );
    disconnectTask.wait();
  }

  //----------------------------------------------------------------------------
  IAsyncOperation<bool>^ IGTLinkClient::ConnectAsync( double timeoutSec )
  {
    this->Disconnect();

    this->m_cancellationTokenSource = cancellation_token_source();

    return create_async( [ = ]() -> bool
    {
      const int retryDelaySec = 1.0;
      int errorCode = 1;
      auto start = std::chrono::high_resolution_clock::now();
      while ( errorCode != 0 )
      {
        std::wstring wideStr( this->ServerHost->Begin() );
        std::string str( wideStr.begin(), wideStr.end() );
        errorCode = this->m_clientSocket->ConnectToServer( str.c_str(), this->ServerPort );
        std::chrono::duration<double, std::milli> timeDiff = std::chrono::high_resolution_clock::now() - start;
        if ( timeDiff.count() > timeoutSec * 1000 )
        {
          // time is up
          break;
        }
        std::this_thread::sleep_for( std::chrono::seconds( retryDelaySec ) );
      }

      if ( errorCode != 0 )
      {
        return false;
      }

      this->m_clientSocket->SetTimeout( CLIENT_SOCKET_TIMEOUT_MSEC );

      // We're connected, start the data receiver thread
      create_task( [this]( void )
      {
        this->DataReceiverPump( this, m_cancellationTokenSource.get_token() );
      } );

      return true;
    } );
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::Disconnect()
  {
    this->m_cancellationTokenSource.cancel();

    {
      critical_section::scoped_lock lock( this->m_socketMutex );
      this->m_clientSocket->CloseSocket();
    }
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::GetLatestTrackedFrame( TrackedFrame^ frame, double* latestTimestamp )
  {
    igtl::TrackedFrameMessage::Pointer trackedFrameMsg = nullptr;
    {
      // Retrieve the next available tracked frame reply
      Concurrency::critical_section::scoped_lock lock( m_messageListMutex );
      for ( auto replyIter = m_messages.rbegin(); replyIter != m_messages.rend(); ++replyIter )
      {
        if ( typeid( *( *replyIter ) ) == typeid( igtl::TrackedFrameMessage ) )
        {
          trackedFrameMsg = dynamic_cast<igtl::TrackedFrameMessage*>( ( *replyIter ).GetPointer() );
          break;
        }
      }

      if ( trackedFrameMsg == nullptr )
      {
        // No message found
        return false;
      }
    }

    if ( latestTimestamp != nullptr )
    {
      auto ts = igtl::TimeStamp::New();
      trackedFrameMsg->GetTimeStamp( ts );

      if ( ts->GetTimeStamp() <= *latestTimestamp )
      {
        // No new messages since requested timestamp
        return false;
      }
      else
      {
        *latestTimestamp = ts->GetTimeStamp();
      }
    }

    // Tracking/other related fields
    for ( auto pair : trackedFrameMsg->GetMetaData() )
    {
      std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
      std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
      frame->SetCustomFrameField( keyWideStr, valueWideStr );
    }

    for ( auto pair : trackedFrameMsg->GetCustomFrameFields() )
    {
      std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
      std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
      frame->SetCustomFrameField( keyWideStr, valueWideStr );
    }

    // Image related fields
    auto vec = ref new Vector<uint16>;
    vec->Append( trackedFrameMsg->GetFrameSize()[0] );
    vec->Append( trackedFrameMsg->GetFrameSize()[1] );
    vec->Append( trackedFrameMsg->GetFrameSize()[2] );
    frame->FrameSize = vec->GetView();
    igtl::TimeStamp::Pointer ts = igtl::TimeStamp::New();
    trackedFrameMsg->GetTimeStamp( ts );
    frame->Timestamp = ts->GetTimeStamp();
    frame->ImageSizeBytes = trackedFrameMsg->GetImageSizeInBytes();
    frame->SetImageData( trackedFrameMsg->GetImage() );
    frame->NumberOfComponents = trackedFrameMsg->GetNumberOfComponents();
    frame->ScalarType = trackedFrameMsg->GetScalarType();
    frame->SetEmbeddedImageTransform( trackedFrameMsg->GetEmbeddedImageTransform() );
    frame->ImageType = ( uint16 )trackedFrameMsg->GetImageType();
    frame->ImageOrientation = ( uint16 )trackedFrameMsg->GetImageOrientation();

    return true;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::GetLatestCommand( UWPOpenIGTLink::Command^ cmd, double* latestTimestamp )
  {
    igtl::MessageBase::Pointer igtMessage = nullptr;
    {
      // Retrieve the next available tracked frame reply
      Concurrency::critical_section::scoped_lock lock( m_messageListMutex );
      for ( auto replyIter = m_messages.rbegin(); replyIter != m_messages.rend(); ++replyIter )
      {
        if ( typeid( *( *replyIter ) ) == typeid( igtl::RTSCommandMessage ) )
        {
          igtMessage = *replyIter;
          break;
        }
      }
    }

    if ( igtMessage != nullptr )
    {
      if ( latestTimestamp != nullptr )
      {
        auto ts = igtl::TimeStamp::New();
        igtMessage->GetTimeStamp( ts );

        if ( ts->GetTimeStamp() <= *latestTimestamp )
        {
          // No new messages since requested timestamp
          return false;
        }
        else
        {
          *latestTimestamp = ts->GetTimeStamp();
        }
      }

      auto cmdMsg = dynamic_cast<igtl::RTSCommandMessage*>( igtMessage.GetPointer() );

      cmd->CommandContent = ref new Platform::String( std::wstring( cmdMsg->GetCommandContent().begin(), cmdMsg->GetCommandContent().end() ).c_str() );
      cmd->CommandName = ref new Platform::String( std::wstring( cmdMsg->GetCommandName().begin(), cmdMsg->GetCommandName().end() ).c_str() );
      cmd->OriginalCommandId = cmdMsg->GetCommandId();

      XmlDocument^ doc = ref new XmlDocument();
      doc->LoadXml( cmd->CommandContent );

      for ( IXmlNode^ node : doc->ChildNodes )
      {
        if ( dynamic_cast<Platform::String^>( node->NodeName ) == L"Result" )
        {
          cmd->Result = ( dynamic_cast<Platform::String^>( node->NodeValue ) == L"true" );
          break;
        }
      }

      if ( !cmd->Result )
      {
        bool found( false );
        // Parse for the error string
        for ( IXmlNode^ node : doc->ChildNodes )
        {
          if ( dynamic_cast<Platform::String^>( node->NodeName ) == L"Error" )
          {
            cmd->ErrorString = dynamic_cast<Platform::String^>( node->NodeValue );
            found = true;
            break;
          }
        }

        if ( !found )
        {
          // TODO : quiet error reporting
        }
      }

      for ( auto pair : cmdMsg->GetMetaData() )
      {
        std::wstring keyWideStr( pair.first.begin(), pair.first.end() );
        std::wstring valueWideStr( pair.second.begin(), pair.second.end() );
        cmd->Parameters->Insert( ref new Platform::String( keyWideStr.c_str() ), ref new Platform::String( valueWideStr.c_str() ) );
      }

      return true;
    }

    return false;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::SendMessage( igtl::MessageBase::Pointer packedMessage )
  {
    int success = 0;
    {
      critical_section::scoped_lock lock( m_socketMutex );
      success = this->m_clientSocket->Send( packedMessage->GetBufferPointer(), packedMessage->GetBufferSize() );
    }
    if ( !success )
    {
      std::cerr << "OpenIGTLink client couldn't send message to server." << std::endl;
      return false;
    }
    return true;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::DataReceiverPump( IGTLinkClient^ self, concurrency::cancellation_token token )
  {
    LOG_TRACE( L"IGTLinkClient::DataReceiverPump" );

    while ( !token.is_canceled() )
    {
      auto headerMsg = self->m_igtlMessageFactory->CreateHeaderMessage( IGTL_HEADER_VERSION_1 );

      // Receive generic header from the socket
      int numOfBytesReceived = 0;
      {
        critical_section::scoped_lock lock( self->m_socketMutex );
        if ( !self->m_clientSocket->GetConnected() )
        {
          // We've become disconnected while waiting for the socket, we're done here!
          return;
        }
        numOfBytesReceived = self->m_clientSocket->Receive( headerMsg->GetBufferPointer(), headerMsg->GetBufferSize() );
      }
      if ( numOfBytesReceived == 0 // No message received
           || numOfBytesReceived != headerMsg->GetBufferSize() // Received data is not as we expected
         )
      {
        // Failed to receive data, maybe the socket is disconnected
        std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
        continue;
      }

      int c = headerMsg->Unpack( 1 );
      if ( !( c & igtl::MessageHeader::UNPACK_HEADER ) )
      {
        std::cerr << "Failed to receive reply (invalid header)" << std::endl;
        continue;
      }

      igtl::MessageBase::Pointer bodyMsg = nullptr;
      try
      {
        bodyMsg = self->m_igtlMessageFactory->CreateReceiveMessage( headerMsg );
      }
      catch ( const std::exception& )
      {
        // Message header was not correct, skip this message
        // Will be impossible to tell if the body of this message is in the socket... this is a pretty bad corruption.
        // Force re-connect?
        LOG_TRACE( "Corruption in the message header. Serious error." );
        continue;
      }

      if ( bodyMsg.IsNull() )
      {
        LOG_TRACE( "Unable to create message of type: " << headerMsg->GetMessageType() );
        continue;
      }

      // Accept all messages but status messages, they are used as a keep alive mechanism
      if ( typeid( *bodyMsg ) != typeid( igtl::StatusMessage ) )
      {
        {
          critical_section::scoped_lock lock( self->m_socketMutex );
          if ( !self->m_clientSocket->GetConnected() )
          {
            // We've become disconnected while waiting for the socket, we're done here!
            return;
          }
          self->m_clientSocket->Receive( bodyMsg->GetBufferBodyPointer(), bodyMsg->GetBufferBodySize() );
        }

        int c = bodyMsg->Unpack( 1 );
        if ( !( c & igtl::MessageHeader::UNPACK_BODY ) )
        {
          std::cerr << "Failed to receive reply (invalid body)" << std::endl;
          continue;
        }

        {
          // save reply
          critical_section::scoped_lock lock( self->m_messageListMutex );

          self->m_messages.push_back( bodyMsg );
        }
      }
      else
      {
        critical_section::scoped_lock lock( self->m_socketMutex );

        if ( !self->m_clientSocket->GetConnected() )
        {
          // We've become disconnected while waiting for the socket, we're done here!
          return;
        }
        self->m_clientSocket->Skip( headerMsg->GetBodySizeToRead(), 0 );
      }

      if ( self->m_messages.size() > MESSAGE_LIST_MAX_SIZE )
      {
        critical_section::scoped_lock lock( self->m_messageListMutex );

        // erase the front N results
        uint32 toErase = self->m_messages.size() - MESSAGE_LIST_MAX_SIZE;
        self->m_messages.erase( self->m_messages.begin(), self->m_messages.begin() + toErase );
      }
    }

    return;
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::SocketReceive( void* data, int length )
  {
    critical_section::scoped_lock lock( m_socketMutex );
    return m_clientSocket->Receive( data, length );
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::ServerPort::get()
  {
    return this->m_ServerPort;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerPort::set( int arg )
  {
    this->m_ServerPort = arg;
  }

  //----------------------------------------------------------------------------
  Platform::String^ IGTLinkClient::ServerHost::get()
  {
    return this->m_ServerHost;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerHost::set( Platform::String^ arg )
  {
    this->m_ServerHost = arg;
  }

  //----------------------------------------------------------------------------
  int IGTLinkClient::ServerIGTLVersion::get()
  {
    return this->m_ServerIGTLVersion;
  }

  //----------------------------------------------------------------------------
  void IGTLinkClient::ServerIGTLVersion::set( int arg )
  {
    this->m_ServerIGTLVersion = arg;
  }

  //----------------------------------------------------------------------------
  bool IGTLinkClient::Connected::get()
  {
    return this->m_clientSocket->GetConnected();
  }
}<|endoftext|>


<commit_before><commit_msg>vulkan: add missing structure type<commit_after><|endoftext|>