<commit_before>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#pragma once

#include <thrust/detail/config.h>
#include <thrust/pair.h>
#include <thrust/detail/function.h>
#include <thrust/iterator/iterator_traits.h>

namespace thrust
{

namespace system
{

namespace detail
{

namespace generic
{

namespace scalar
{

// XXX generalize these upon implementation of scalar::distance & scalar::advance

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
RandomAccessIterator lower_bound(RandomAccessIterator first, RandomAccessIterator last,
                                 const T &val,
                                 BinaryPredicate comp)
{
  // wrap comp
  thrust::detail::host_device_function<
    BinaryPredicate,
    bool
  > wrapped_comp(comp);

  typedef typename thrust::iterator_difference<RandomAccessIterator>::type difference_type;

  // XXX should read len = distance(first,last)
  difference_type len = last - first;

  while(len > 0)
  {
    difference_type half = len >> 1;
    RandomAccessIterator middle = first;

    // XXX should read advance(middle,half)
    middle += half;

    if(wrapped_comp(*middle, val))
    {
      first = middle;
      ++first;
      len = len - half - 1;
    }
    else
    {
      len = half;
    }
  }

  return first;
}

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
RandomAccessIterator upper_bound(RandomAccessIterator first, RandomAccessIterator last,
                                 const T &val,
                                 BinaryPredicate comp)
{
  // wrap comp
  thrust::detail::host_device_function<
    BinaryPredicate,
    bool
  > wrapped_comp(comp);

  typedef typename thrust::iterator_difference<RandomAccessIterator>::type difference_type;

  // XXX should read len = distance(first,last)
  difference_type len = last - first;

  while(len > 0)
  {
    difference_type half = len >> 1;
    RandomAccessIterator middle = first;

    // XXX should read advance(middle,half)
    middle += half;

    if(wrapped_comp(val, *middle))
    {
      len = half;
    }
    else
    {
      first = middle;
      ++first;
      len = len - half - 1;
    }
  }

  return first;
}

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
  pair<RandomAccessIterator,RandomAccessIterator>
    equal_range(RandomAccessIterator first, RandomAccessIterator last,
                const T &val,
                BinaryPredicate comp)
{
  RandomAccessIterator lb = thrust::system::detail::generic::scalar::lower_bound(first, last, val, comp);
  return thrust::make_pair(lb, thrust::system::detail::generic::scalar::upper_bound(lb, last, val, comp));
}

template<typename RandomAccessIterator, typename T, typename Compare>
__host__ __device__
bool binary_search(RandomAccessIterator first, RandomAccessIterator last, const T &value, Compare comp)
{
  RandomAccessIterator iter = thrust::system::detail::generic::scalar::lower_bound(first,last,value,comp);
  return iter != last && !comp(value, *iter);
}

} // end scalar

} // end generic

} // end detail

} // end system

} // end thrust

#include <thrust/system/detail/generic/scalar/binary_search.inl>

<commit_msg>Use host_device_function to wrap comp inside generic::scalar::binary_search Fixes issue 414<commit_after>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#pragma once

#include <thrust/detail/config.h>
#include <thrust/pair.h>
#include <thrust/detail/function.h>
#include <thrust/iterator/iterator_traits.h>

namespace thrust
{

namespace system
{

namespace detail
{

namespace generic
{

namespace scalar
{

// XXX generalize these upon implementation of scalar::distance & scalar::advance

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
RandomAccessIterator lower_bound(RandomAccessIterator first, RandomAccessIterator last,
                                 const T &val,
                                 BinaryPredicate comp)
{
  // wrap comp
  thrust::detail::host_device_function<
    BinaryPredicate,
    bool
  > wrapped_comp(comp);

  typedef typename thrust::iterator_difference<RandomAccessIterator>::type difference_type;

  // XXX should read len = distance(first,last)
  difference_type len = last - first;

  while(len > 0)
  {
    difference_type half = len >> 1;
    RandomAccessIterator middle = first;

    // XXX should read advance(middle,half)
    middle += half;

    if(wrapped_comp(*middle, val))
    {
      first = middle;
      ++first;
      len = len - half - 1;
    }
    else
    {
      len = half;
    }
  }

  return first;
}

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
RandomAccessIterator upper_bound(RandomAccessIterator first, RandomAccessIterator last,
                                 const T &val,
                                 BinaryPredicate comp)
{
  // wrap comp
  thrust::detail::host_device_function<
    BinaryPredicate,
    bool
  > wrapped_comp(comp);

  typedef typename thrust::iterator_difference<RandomAccessIterator>::type difference_type;

  // XXX should read len = distance(first,last)
  difference_type len = last - first;

  while(len > 0)
  {
    difference_type half = len >> 1;
    RandomAccessIterator middle = first;

    // XXX should read advance(middle,half)
    middle += half;

    if(wrapped_comp(val, *middle))
    {
      len = half;
    }
    else
    {
      first = middle;
      ++first;
      len = len - half - 1;
    }
  }

  return first;
}

template<typename RandomAccessIterator, typename T, typename BinaryPredicate>
__host__ __device__
  pair<RandomAccessIterator,RandomAccessIterator>
    equal_range(RandomAccessIterator first, RandomAccessIterator last,
                const T &val,
                BinaryPredicate comp)
{
  RandomAccessIterator lb = thrust::system::detail::generic::scalar::lower_bound(first, last, val, comp);
  return thrust::make_pair(lb, thrust::system::detail::generic::scalar::upper_bound(lb, last, val, comp));
}

template<typename RandomAccessIterator, typename T, typename Compare>
__host__ __device__
bool binary_search(RandomAccessIterator first, RandomAccessIterator last, const T &value, Compare comp)
{
  RandomAccessIterator iter = thrust::system::detail::internal::scalar::lower_bound(first, last, value, comp);

  // wrap comp
  thrust::detail::host_device_function<
    Compare,
    bool
  > wrapped_comp(comp);

  return iter != last && !wrapped_comp(value,*iter);
}

} // end scalar

} // end generic

} // end detail

} // end system

} // end thrust

#include <thrust/system/detail/generic/scalar/binary_search.inl>

<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <cstdint>
#include <map>
#include <string>
#include <vector>

namespace ouzel
{
    namespace ini
    {
        class Data;

        class Section
        {
            friend Data;
        public:
            Section();
            Section(const std::string& aName);

            const std::string& getName() const { return name; }

            const std::map<std::string, std::string>& getValues() const { return values; }
            bool hasValue(const std::string& key) const;
            const std::string& getValue(const std::string& key);
            std::string getValue(const std::string& key) const;
            const std::string& getValue(const std::string& key, const std::string& defaultValue) const;
            void setValue(const std::string& key, const std::string& value);
            bool deleteValue(const std::string& key);

        private:
            std::string name;
            std::map<std::string, std::string> values;
        };

        class Data
        {
        public:
            Data();
            Data(const std::string& filename);
            Data(const std::vector<uint8_t>& data);

            bool init(const std::string& filename);
            bool init(const std::vector<uint8_t>& data);
            bool save(const std::string& filename);
            bool encode(std::vector<uint8_t>& data);

            const std::map<std::string, Section>& getSections() const { return sections; }
            bool hasSection(const std::string& name) const;
            const Section& getSection(const std::string& name);
            Section getSection(const std::string& name) const;
            void setSection(const std::string& name, const Section& section);
            bool deleteSection(const std::string& name);

        private:
            std::map<std::string, Section> sections;
        };
    }
}
<commit_msg>Add setter for name<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <cstdint>
#include <map>
#include <string>
#include <vector>

namespace ouzel
{
    namespace ini
    {
        class Data;

        class Section
        {
            friend Data;
        public:
            Section();
            Section(const std::string& aName);

            void setName(const std::string& newName) { name = newName; }
            const std::string& getName() const { return name; }

            const std::map<std::string, std::string>& getValues() const { return values; }
            bool hasValue(const std::string& key) const;
            const std::string& getValue(const std::string& key);
            std::string getValue(const std::string& key) const;
            const std::string& getValue(const std::string& key, const std::string& defaultValue) const;
            void setValue(const std::string& key, const std::string& value);
            bool deleteValue(const std::string& key);

        private:
            std::string name;
            std::map<std::string, std::string> values;
        };

        class Data
        {
        public:
            Data();
            Data(const std::string& filename);
            Data(const std::vector<uint8_t>& data);

            bool init(const std::string& filename);
            bool init(const std::vector<uint8_t>& data);
            bool save(const std::string& filename);
            bool encode(std::vector<uint8_t>& data);

            const std::map<std::string, Section>& getSections() const { return sections; }
            bool hasSection(const std::string& name) const;
            const Section& getSection(const std::string& name);
            Section getSection(const std::string& name) const;
            void setSection(const std::string& name, const Section& section);
            bool deleteSection(const std::string& name);

        private:
            std::map<std::string, Section> sections;
        };
    }
}
<|endoftext|>


<commit_before>/*
 * opencog/atomspace/TypeIndex.cc
 *
 * Copyright (C) 2008 Linas Vepstas <linasvepstas@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "TypeIndex.h"
#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/base/ClassServer.h>

using namespace opencog;

TypeIndex::TypeIndex(void)
{
	resize();
}

void TypeIndex::resize(void)
{
	num_types = classserver().getNumberOfClasses();
	FixedIntegerIndex::resize(num_types + 1);
}

// ================================================================

TypeIndex::iterator TypeIndex::begin(Type t, bool sub) const
{
	iterator it(t, sub);
	it.send = idx.end();

	it.s = idx.begin();
	it.currtype = 0;
	while (it.s != it.send)
	{
		// Find the first type which is a subtype, and start iteration there.
		if ((it.type == it.currtype) ||
		    (sub && (classserver().isA(it.currtype, it.type))))
		{
			it.se = it.s->begin();
			if (it.se != it.s->end()) return it;
		}
		it.currtype++;
		++it.s;
	}

	return it;
}

TypeIndex::iterator TypeIndex::end(void) const
{
	iterator it(num_types, false);
	it.se = idx.at(num_types).end();
	it.s = idx.end();
	it.send = idx.end();
	it.currtype = num_types;
	return it;
}

TypeIndex::iterator::iterator(Type t, bool sub)
{
	type = t;
	subclass = sub;
}

TypeIndex::iterator& TypeIndex::iterator::operator=(iterator v)
{
	s = v.s;
	send = v.send;
	se = v.se;
	currtype = v.currtype;
	type = v.type;
	subclass = v.subclass;
	return *this;
}

Handle TypeIndex::iterator::operator*(void)
{
	if (s == send) return Handle::UNDEFINED;
	return (*se)->getHandle();
}

bool TypeIndex::iterator::operator==(iterator v)
{
	if ((v.s == v.send) && (s == send)) return true;
	return v.se == se;
}

bool TypeIndex::iterator::operator!=(iterator v)
{
	if ((v.s == v.send) && (s != send)) return v.se != se;
	if ((v.s != v.send) && (s == send)) return v.se != se;
	return false;
}

TypeIndex::iterator& TypeIndex::iterator::operator++()
{
	return operator++(1);
}

// XXX this is broken, for i != 1 ... FIXME.
TypeIndex::iterator& TypeIndex::iterator::operator++(int i)
{
	if (s == send) return *this;

	++se;
	if (se == s->end())
	{
		// If we are not subclassing, then we are really really done.
		if (not subclass)
		{
			s = send;
			return *this;
		}
		do
		{
			++s;
			currtype++;

			// Find the first type which is a subtype, and start iteration there.
			if (classserver().isA(currtype, type))
			{
				se = s->begin();
				if (se != s->end()) return *this;
			}
		} while (s != send);
	}

	return *this;
}

// ================================================================
<commit_msg>Optimize the TypeIndex iterator setup<commit_after>/*
 * opencog/atomspace/TypeIndex.cc
 *
 * Copyright (C) 2008 Linas Vepstas <linasvepstas@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "TypeIndex.h"
#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/base/ClassServer.h>

using namespace opencog;

TypeIndex::TypeIndex(void)
{
	resize();
}

void TypeIndex::resize(void)
{
	num_types = classserver().getNumberOfClasses();
	FixedIntegerIndex::resize(num_types + 1);
}

// ================================================================

TypeIndex::iterator TypeIndex::begin(Type t, bool sub) const
{
	iterator it(t, sub);
	it.send = idx.end();

	// A subclass of t is NEVER smaller than t.
	// Thus, we can start our search there.
	it.s = idx.begin();
	it.s += t;
	it.currtype = t;
	it.se = it.s->begin();

	// If its not empty, then go for it.
	if (it.se != it.s->end()) return it;

	// If its the emptyset, and we are not subclassing, then we're done.
	if (not sub)
	{
		it.s = it.send;
		return it;
	}

	// Find the first type which is a subtype, and is not empty.
	it.s++;
	it.currtype++;
	while (it.s != it.send)
	{
		if (classserver().isA(it.currtype, it.type))
		{
			it.se = it.s->begin();
			if (it.se != it.s->end()) return it;
		}
		it.currtype++;
		++it.s;
	}

	return it;
}

TypeIndex::iterator TypeIndex::end(void) const
{
	iterator it(num_types, false);
	it.se = idx.at(num_types).end();
	it.s = idx.end();
	it.send = idx.end();
	it.currtype = num_types;
	return it;
}

TypeIndex::iterator::iterator(Type t, bool sub)
{
	type = t;
	subclass = sub;
}

TypeIndex::iterator& TypeIndex::iterator::operator=(iterator v)
{
	s = v.s;
	send = v.send;
	se = v.se;
	currtype = v.currtype;
	type = v.type;
	subclass = v.subclass;
	return *this;
}

Handle TypeIndex::iterator::operator*(void)
{
	if (s == send) return Handle::UNDEFINED;
	return (*se)->getHandle();
}

bool TypeIndex::iterator::operator==(iterator v)
{
	if ((v.s == v.send) && (s == send)) return true;
	return v.se == se;
}

bool TypeIndex::iterator::operator!=(iterator v)
{
	if ((v.s == v.send) && (s != send)) return v.se != se;
	if ((v.s != v.send) && (s == send)) return v.se != se;
	return false;
}

TypeIndex::iterator& TypeIndex::iterator::operator++()
{
	return operator++(1);
}

// XXX this is broken, for i != 1 ... FIXME.
TypeIndex::iterator& TypeIndex::iterator::operator++(int i)
{
	if (s == send) return *this;

	++se;
	if (se == s->end())
	{
		// If we are not subclassing, then we are really really done.
		if (not subclass)
		{
			s = send;
			return *this;
		}

		// Otherwise, move on to the next type.
		do
		{
			++s;
			currtype++;

			// Find the first type which is a subtype, and start iteration there.
			if (classserver().isA(currtype, type))
			{
				se = s->begin();
				if (se != s->end()) return *this;
			}
		} while (s != send);
	}

	return *this;
}

// ================================================================
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "XML.hpp"
#include "core/Engine.hpp"
#include "Log.hpp"
#include "Utils.hpp"

namespace ouzel
{
    namespace xml
    {
        Node::Node()
        {
        }

        bool Node::parse(const std::vector<uint32_t>& utf32,
                         std::vector<uint32_t>::iterator& iterator)
        {
            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '<')
            {
                ++iterator;

                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == '!') // <!
                {
                    ++iterator;

                    if (iterator == utf32.end())
                    {
                        Log(Log::Level::ERR) << "Unexpected end of file";
                        return false;
                    }

                    if (*iterator == '-') // <!-
                    {
                        ++iterator;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '-') // <!--
                        {
                            Log(Log::Level::ERR) << "Expected a comment";
                            return false;
                        }

                        ++iterator;

                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == '-')
                            {
                                if (iterator + 1 == utf32.end())
                                {
                                    Log(Log::Level::ERR) << "Unexpected end of file";
                                    return false;
                                }

                                if (*(iterator + 1) == '-') // --
                                {
                                    iterator += 2;

                                    if (iterator == utf32.end())
                                    {
                                        Log(Log::Level::ERR) << "Unexpected end of file";
                                        return false;
                                    }

                                    if (*iterator == '>') // -->
                                    {
                                        ++iterator;
                                        break;
                                    }
                                    else
                                    {
                                        Log(Log::Level::ERR) << "Unexpected double-hyphen inside comment";
                                        return false;
                                    }
                                }
                            }

                            value += utf32to8(*iterator);
                            ++iterator;
                        }

                        type = Type::COMMENT;
                    }
                    else if (*iterator == '[') // <![
                    {
                        return true;
                    }
                    else
                    {
                        return true;
                    }
                }
                else if (*iterator == '?') // <?
                {
                    // TODO: parse xml declaration <?xml ... ?>
                    return true;
                }
                else // <
                {
                    ++iterator;

                    if (!parseName(utf32, iterator, value)) return false;

                    for (;;)
                    {
                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator == '/' || *iterator == '>')
                        {
                            break;
                        }

                        std::string attribute;
                        if (!parseName(utf32, iterator, attribute)) return false;

                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '=')
                        {
                            Log(Log::Level::ERR) << "Expected an equal sign";
                            return false;
                        }

                        ++iterator;

                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (!parseString(utf32, iterator, attributes[attribute])) return false;

                        break;
                    }

                    // TODO: parse end of tag
                    // TODO: parse child tags

                    return true;
                }
            }
            else
            {
                for (;;)
                {
                    if (iterator == utf32.end() || // end of a file
                        *iterator == '<') // start of a tag
                    {
                        break;
                    }
                    else
                    {
                        value += utf32to8(*iterator);
                        ++iterator;
                    }
                }

                type = Node::Type::TEXT;

                return true;
            }

            return true;
        }

        bool Node::encode(std::vector<uint8_t>& data) const
        {
            switch (type)
            {
                case Node::Type::COMMENT:
                    data.insert(data.end(), {'<', '!', '-', '-'});
                    data.insert(data.end(), value.begin(), value.end());
                    data.insert(data.end(), {'-', '-', '>'});
                    break;
                case Node::Type::CDATA:
                    break;
                case Node::Type::DOCTYPE_DEFINITION:
                    break;
                case Node::Type::PROCESSING_INSTRUCTION:
                    data.insert(data.end(), {'<', '?'});
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    data.insert(data.end(), {'?', '>'});
                    break;
                case Node::Type::TAG:
                    data.insert(data.end(), '<');
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    if (children.empty())
                    {
                        data.insert(data.end(), {'/', '>'});
                    }
                    else
                    {
                        data.insert(data.end(), '>');

                        for (const Node& node : children)
                        {
                            node.encode(data);
                        }

                        data.insert(data.end(), {'<', '/'});
                        data.insert(data.end(), value.begin(), value.end());
                        data.insert(data.end(), '>');
                    }
                    break;
                case Node::Type::TEXT:
                    data.insert(data.end(), value.begin(), value.end());
                    break;
                default:
                    return false;
            }

            for (const Node& node : children)
            {
                node.encode(data);
            }

            return true;
        }

        bool Node::skipWhitespaces(const std::vector<uint32_t>& utf32,
                                   std::vector<uint32_t>::iterator& iterator)
        {
            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t')
                {
                    ++iterator;
                }
                else
                {
                    break;
                }
            }

            return true;
        }

        bool Node::parseName(const std::vector<uint32_t>& utf32,
                             std::vector<uint32_t>::iterator& iterator,
                             std::string& result)
        {
            result.clear();

            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '-' || *iterator == '.' || // tag name can not start with - or .
                (*iterator >= '0' && *iterator <= '9'))
            {
                Log(Log::Level::ERR) << "Invalid name";
                return false;
            }

            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t' || // whitespace
                    *iterator == '+' || *iterator == '=' || *iterator == '<' || *iterator == '>' || // end of the opening
                    *iterator == '\'' || *iterator == '"') // quotes
                {
                    break;
                }
                else
                {
                    result += utf32to8(*iterator);
                    ++iterator;
                }
            }

            return true;
        }

        bool Node::parseString(const std::vector<uint32_t>& utf32,
                               std::vector<uint32_t>::iterator& iterator,
                               std::string& result)
        {
            result.clear();

            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator != '"' && *iterator != '\'')
            {
                Log(Log::Level::ERR) << "Expected quotes";
                return false;
            }

            char quotes = static_cast<char>(*iterator);

            ++iterator;

            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (quotes == static_cast<char>(*iterator))
                {
                    ++iterator;
                    break;
                }

                result += utf32to8(*iterator);
                ++iterator;
            }

            return true;
        }

        Data::Data()
        {
        }

        Data::Data(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(filename, preserveComments, preserveProcessingInstructions);
        }

        Data::Data(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint8_t> data;

            if (!engine->getFileSystem()->readFile(filename, data))
            {
                return false;
            }

            return init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint32_t> utf32;

            // BOM
            if (data.size() >= 3 &&
                data[0] == 0xEF &&
                data[1] == 0xBB &&
                data[2] == 0xBF)
            {
                bom = true;
                utf32 = utf8to32(std::vector<uint8_t>(data.begin() + 3, data.end()));
            }
            else
            {
                bom = false;
                utf32 = utf8to32(data);
            }

            std::vector<uint32_t>::iterator iterator = utf32.begin();

            while (iterator != utf32.end())
            {
                Node node;
                if (!node.parse(utf32, iterator))
                {
                    return false;
                }

                if ((preserveComments || node.getType() != Node::Type::COMMENT) &&
                    (preserveProcessingInstructions || node.getType() != Node::Type::PROCESSING_INSTRUCTION))
                {
                    children.push_back(node);
                }
            }

            // TODO: check if only single tag is in the children list

            return true;
        }

        bool Data::save(const std::string& filename) const
        {
            std::vector<uint8_t> data;

            if (!encode(data)) return false;

            return engine->getFileSystem()->writeFile(filename, data);
        }

        bool Data::encode(std::vector<uint8_t>& data) const
        {
            data.clear();

            if (bom) data.insert(data.end(), {0xEF, 0xBB, 0xBF});

            for (const Node& node : children)
            {
                if (!node.encode(data)) return false;
            }

            return true;
        }
    } // namespace xml
}
<commit_msg>Parse tag closing<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "XML.hpp"
#include "core/Engine.hpp"
#include "Log.hpp"
#include "Utils.hpp"

namespace ouzel
{
    namespace xml
    {
        Node::Node()
        {
        }

        bool Node::parse(const std::vector<uint32_t>& utf32,
                         std::vector<uint32_t>::iterator& iterator)
        {
            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '<')
            {
                ++iterator;

                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == '!') // <!
                {
                    ++iterator;

                    if (iterator == utf32.end())
                    {
                        Log(Log::Level::ERR) << "Unexpected end of file";
                        return false;
                    }

                    if (*iterator == '-') // <!-
                    {
                        ++iterator;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '-') // <!--
                        {
                            Log(Log::Level::ERR) << "Expected a comment";
                            return false;
                        }

                        ++iterator;

                        for (;;)
                        {
                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator == '-')
                            {
                                if (iterator + 1 == utf32.end())
                                {
                                    Log(Log::Level::ERR) << "Unexpected end of file";
                                    return false;
                                }

                                if (*(iterator + 1) == '-') // --
                                {
                                    iterator += 2;

                                    if (iterator == utf32.end())
                                    {
                                        Log(Log::Level::ERR) << "Unexpected end of file";
                                        return false;
                                    }

                                    if (*iterator == '>') // -->
                                    {
                                        ++iterator;
                                        break;
                                    }
                                    else
                                    {
                                        Log(Log::Level::ERR) << "Unexpected double-hyphen inside comment";
                                        return false;
                                    }
                                }
                            }

                            value += utf32to8(*iterator);
                            ++iterator;
                        }

                        type = Type::COMMENT;
                    }
                    else if (*iterator == '[') // <![
                    {
                        return true;
                    }
                    else
                    {
                        return true;
                    }
                }
                else if (*iterator == '?') // <?
                {
                    // TODO: parse xml declaration <?xml ... ?>
                    return true;
                }
                else // <
                {
                    ++iterator;

                    if (!parseName(utf32, iterator, value)) return false;

                    bool tagClosed = false;

                    for (;;)
                    {
                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator == '>')
                        {
                            ++iterator;
                            break;
                        }
                        else if (*iterator == '/')
                        {
                            ++iterator;

                            if (iterator == utf32.end())
                            {
                                Log(Log::Level::ERR) << "Unexpected end of file";
                                return false;
                            }

                            if (*iterator != '>')
                            {
                                Log(Log::Level::ERR) << "Expected a right angle bracket";
                                return false;
                            }

                            tagClosed = true;
                            ++iterator;
                            break;
                        }

                        std::string attribute;
                        if (!parseName(utf32, iterator, attribute)) return false;

                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (iterator == utf32.end())
                        {
                            Log(Log::Level::ERR) << "Unexpected end of file";
                            return false;
                        }

                        if (*iterator != '=')
                        {
                            Log(Log::Level::ERR) << "Expected an equal sign";
                            return false;
                        }

                        ++iterator;

                        if (!skipWhitespaces(utf32, iterator)) return false;

                        if (!parseString(utf32, iterator, attributes[attribute])) return false;

                        break;
                    }

                    if (!tagClosed)
                    {
                        // TODO: parse child tags
                        // TODO: parse end of tag
                    }

                    return true;
                }
            }
            else
            {
                for (;;)
                {
                    if (iterator == utf32.end() || // end of a file
                        *iterator == '<') // start of a tag
                    {
                        break;
                    }
                    else
                    {
                        value += utf32to8(*iterator);
                        ++iterator;
                    }
                }

                type = Node::Type::TEXT;

                return true;
            }

            return true;
        }

        bool Node::encode(std::vector<uint8_t>& data) const
        {
            switch (type)
            {
                case Node::Type::COMMENT:
                    data.insert(data.end(), {'<', '!', '-', '-'});
                    data.insert(data.end(), value.begin(), value.end());
                    data.insert(data.end(), {'-', '-', '>'});
                    break;
                case Node::Type::CDATA:
                    break;
                case Node::Type::DOCTYPE_DEFINITION:
                    break;
                case Node::Type::PROCESSING_INSTRUCTION:
                    data.insert(data.end(), {'<', '?'});
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    data.insert(data.end(), {'?', '>'});
                    break;
                case Node::Type::TAG:
                    data.insert(data.end(), '<');
                    data.insert(data.end(), value.begin(), value.end());

                    if (attributes.empty())
                    {
                        data.insert(data.end(), ' ');
                    }
                    else
                    {
                        for (const auto& attribute : attributes)
                        {
                            data.insert(data.end(), attribute.first.begin(), attribute.first.end());
                            data.insert(data.end(), {'=', '"'});
                            data.insert(data.end(), attribute.second.begin(), attribute.second.end());
                            data.insert(data.end(), '"');
                        }
                    }

                    if (children.empty())
                    {
                        data.insert(data.end(), {'/', '>'});
                    }
                    else
                    {
                        data.insert(data.end(), '>');

                        for (const Node& node : children)
                        {
                            node.encode(data);
                        }

                        data.insert(data.end(), {'<', '/'});
                        data.insert(data.end(), value.begin(), value.end());
                        data.insert(data.end(), '>');
                    }
                    break;
                case Node::Type::TEXT:
                    data.insert(data.end(), value.begin(), value.end());
                    break;
                default:
                    return false;
            }

            for (const Node& node : children)
            {
                node.encode(data);
            }

            return true;
        }

        bool Node::skipWhitespaces(const std::vector<uint32_t>& utf32,
                                   std::vector<uint32_t>::iterator& iterator)
        {
            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t')
                {
                    ++iterator;
                }
                else
                {
                    break;
                }
            }

            return true;
        }

        bool Node::parseName(const std::vector<uint32_t>& utf32,
                             std::vector<uint32_t>::iterator& iterator,
                             std::string& result)
        {
            result.clear();

            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator == '-' || *iterator == '.' || // tag name can not start with - or .
                (*iterator >= '0' && *iterator <= '9'))
            {
                Log(Log::Level::ERR) << "Invalid name";
                return false;
            }

            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (*iterator == ' ' || *iterator == '\r' || *iterator == '\n' || *iterator == '\t' || // whitespace
                    *iterator == '+' || *iterator == '=' || *iterator == '<' || *iterator == '>' || // end of the opening
                    *iterator == '\'' || *iterator == '"') // quotes
                {
                    break;
                }
                else
                {
                    result += utf32to8(*iterator);
                    ++iterator;
                }
            }

            return true;
        }

        bool Node::parseString(const std::vector<uint32_t>& utf32,
                               std::vector<uint32_t>::iterator& iterator,
                               std::string& result)
        {
            result.clear();

            if (iterator == utf32.end())
            {
                Log(Log::Level::ERR) << "Unexpected end of file";
                return false;
            }

            if (*iterator != '"' && *iterator != '\'')
            {
                Log(Log::Level::ERR) << "Expected quotes";
                return false;
            }

            char quotes = static_cast<char>(*iterator);

            ++iterator;

            for (;;)
            {
                if (iterator == utf32.end())
                {
                    Log(Log::Level::ERR) << "Unexpected end of file";
                    return false;
                }

                if (quotes == static_cast<char>(*iterator))
                {
                    ++iterator;
                    break;
                }

                result += utf32to8(*iterator);
                ++iterator;
            }

            return true;
        }

        Data::Data()
        {
        }

        Data::Data(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(filename, preserveComments, preserveProcessingInstructions);
        }

        Data::Data(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::string& filename, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint8_t> data;

            if (!engine->getFileSystem()->readFile(filename, data))
            {
                return false;
            }

            return init(data, preserveComments, preserveProcessingInstructions);
        }

        bool Data::init(const std::vector<uint8_t>& data, bool preserveComments, bool preserveProcessingInstructions)
        {
            std::vector<uint32_t> utf32;

            // BOM
            if (data.size() >= 3 &&
                data[0] == 0xEF &&
                data[1] == 0xBB &&
                data[2] == 0xBF)
            {
                bom = true;
                utf32 = utf8to32(std::vector<uint8_t>(data.begin() + 3, data.end()));
            }
            else
            {
                bom = false;
                utf32 = utf8to32(data);
            }

            std::vector<uint32_t>::iterator iterator = utf32.begin();

            while (iterator != utf32.end())
            {
                Node node;
                if (!node.parse(utf32, iterator))
                {
                    return false;
                }

                if ((preserveComments || node.getType() != Node::Type::COMMENT) &&
                    (preserveProcessingInstructions || node.getType() != Node::Type::PROCESSING_INSTRUCTION))
                {
                    children.push_back(node);
                }
            }

            // TODO: check if only single tag is in the children list

            return true;
        }

        bool Data::save(const std::string& filename) const
        {
            std::vector<uint8_t> data;

            if (!encode(data)) return false;

            return engine->getFileSystem()->writeFile(filename, data);
        }

        bool Data::encode(std::vector<uint8_t>& data) const
        {
            data.clear();

            if (bom) data.insert(data.end(), {0xEF, 0xBB, 0xBF});

            for (const Node& node : children)
            {
                if (!node.encode(data)) return false;
            }

            return true;
        }
    } // namespace xml
}
<|endoftext|>


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

#include "content/browser/renderer_host/clipboard_message_filter.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "content/common/clipboard_messages.h"
#include "content/public/browser/browser_context.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/size.h"
#include "url/gurl.h"

namespace content {

#if defined(OS_WIN)

namespace {

// The write must be performed on the UI thread because the clipboard object
// from the IO thread cannot create windows so it cannot be the "owner" of the
// clipboard's contents.  // See http://crbug.com/5823.
void WriteObjectsOnUIThread(ui::Clipboard::ObjectMap* objects) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  clipboard->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, *objects);
}

}  // namespace

#endif

ClipboardMessageFilter::ClipboardMessageFilter() {}

void ClipboardMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  // Clipboard writes should always occur on the UI thread due the restrictions
  // of various platform APIs. In general, the clipboard is not thread-safe, so
  // all clipboard calls should be serviced from the UI thread.
  //
  // Windows needs clipboard reads to be serviced from the IO thread because
  // these are sync IPCs which can result in deadlocks with NPAPI plugins if
  // serviced from the UI thread. Note that Windows clipboard calls ARE
  // thread-safe so it is ok for reads and writes to be serviced from different
  // threads.
#if !defined(OS_WIN)
  if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
    *thread = BrowserThread::UI;
#endif

#if defined(OS_WIN)
  if (message.type() == ClipboardHostMsg_ReadImage::ID)
    *thread = BrowserThread::FILE;
#endif
}

bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message,
                                               bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(ClipboardMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsAsync, OnWriteObjectsAsync)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsSync, OnWriteObjectsSync)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_GetSequenceNumber, OnGetSequenceNumber)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_IsFormatAvailable, OnIsFormatAvailable)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_Clear, OnClear)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAvailableTypes,
                        OnReadAvailableTypes)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAsciiText, OnReadAsciiText)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadRTF, OnReadRTF)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadCustomData, OnReadCustomData)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadData, OnReadData)
#if defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync,
                        OnFindPboardWriteString)
#endif
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

ClipboardMessageFilter::~ClipboardMessageFilter() {
}

void ClipboardMessageFilter::OnWriteObjectsSync(
    ui::Clipboard::ObjectMap objects,
    base::SharedMemoryHandle bitmap_handle) {
  DCHECK(base::SharedMemory::IsHandleValid(bitmap_handle))
      << "Bad bitmap handle";
  // Splice the shared memory handle into the clipboard data.
  ui::Clipboard::ReplaceSharedMemHandle(&objects, bitmap_handle, PeerHandle());
#if defined(OS_WIN)
  // We cannot write directly from the IO thread, and cannot service the IPC
  // on the UI thread. We'll copy the relevant data and get a handle to any
  // shared memory so it doesn't go away when we resume the renderer, and post
  // a task to perform the write on the UI thread.
  ui::Clipboard::ObjectMap* long_living_objects = new ui::Clipboard::ObjectMap;
  long_living_objects->swap(objects);

  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&WriteObjectsOnUIThread, base::Owned(long_living_objects)));
#else
  GetClipboard()->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, objects);
#endif
}

void ClipboardMessageFilter::OnWriteObjectsAsync(
    const ui::Clipboard::ObjectMap& objects) {
#if defined(OS_WIN)
  // We cannot write directly from the IO thread, and cannot service the IPC
  // on the UI thread. We'll copy the relevant data and post a task to preform
  // the write on the UI thread.
  ui::Clipboard::ObjectMap* long_living_objects =
      new ui::Clipboard::ObjectMap(objects);

  // This async message doesn't support shared-memory based bitmaps; they must
  // be removed otherwise we might dereference a rubbish pointer.
  long_living_objects->erase(ui::Clipboard::CBF_SMBITMAP);

  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&WriteObjectsOnUIThread, base::Owned(long_living_objects)));
#else
  GetClipboard()->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, objects);
#endif
}

void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type,
                                                 uint64* sequence_number) {
  *sequence_number = GetClipboard()->GetSequenceNumber(type);
}

void ClipboardMessageFilter::OnReadAvailableTypes(ui::ClipboardType type,
                                                  std::vector<string16>* types,
                                                  bool* contains_filenames) {
  GetClipboard()->ReadAvailableTypes(type, types, contains_filenames);
}

void ClipboardMessageFilter::OnIsFormatAvailable(
    const ui::Clipboard::FormatType& format,
    ui::ClipboardType type,
    bool* result) {
  *result = GetClipboard()->IsFormatAvailable(format, type);
}

void ClipboardMessageFilter::OnClear(ui::ClipboardType type) {
  GetClipboard()->Clear(type);
}

void ClipboardMessageFilter::OnReadText(ui::ClipboardType type,
                                        string16* result) {
  GetClipboard()->ReadText(type, result);
}

void ClipboardMessageFilter::OnReadAsciiText(ui::ClipboardType type,
                                             std::string* result) {
  GetClipboard()->ReadAsciiText(type, result);
}

void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type,
                                        string16* markup,
                                        GURL* url,
                                        uint32* fragment_start,
                                        uint32* fragment_end) {
  std::string src_url_str;
  GetClipboard()->ReadHTML(type, markup, &src_url_str, fragment_start,
                           fragment_end);
  *url = GURL(src_url_str);
}

void ClipboardMessageFilter::OnReadRTF(ui::ClipboardType type,
                                       std::string* result) {
  GetClipboard()->ReadRTF(type, result);
}

void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type,
                                         IPC::Message* reply_msg) {
  SkBitmap bitmap = GetClipboard()->ReadImage(type);

#if defined(USE_X11)
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      base::Bind(
          &ClipboardMessageFilter::OnReadImageReply, this, bitmap, reply_msg));
#else
  OnReadImageReply(bitmap, reply_msg);
#endif
}

void ClipboardMessageFilter::OnReadImageReply(
    const SkBitmap& bitmap, IPC::Message* reply_msg) {
  base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle();
  uint32 image_size = 0;
  if (!bitmap.isNull()) {
    std::vector<unsigned char> png_data;
    if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
      base::SharedMemory buffer;
      if (buffer.CreateAndMapAnonymous(png_data.size())) {
        memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size());
        if (buffer.GiveToProcess(PeerHandle(), &image_handle)) {
          image_size = png_data.size();
        }
      }
    }
  }
  ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle,
                                               image_size);
  Send(reply_msg);
}

void ClipboardMessageFilter::OnReadCustomData(ui::ClipboardType clipboard_type,
                                              const string16& type,
                                              string16* result) {
  GetClipboard()->ReadCustomData(clipboard_type, type, result);
}

void ClipboardMessageFilter::OnReadData(const ui::Clipboard::FormatType& format,
                                        std::string* data) {
  GetClipboard()->ReadData(format, data);
}

// static
ui::Clipboard* ClipboardMessageFilter::GetClipboard() {
  // We have a static instance of the clipboard service for use by all message
  // filters.  This instance lives for the life of the browser processes.
  static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  return clipboard;
}

}  // namespace content
<commit_msg>Always erase CBF_SMBITMAP from the clipboard object map for async writes<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/clipboard_message_filter.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "content/common/clipboard_messages.h"
#include "content/public/browser/browser_context.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/size.h"
#include "url/gurl.h"

namespace content {

#if defined(OS_WIN)

namespace {

// The write must be performed on the UI thread because the clipboard object
// from the IO thread cannot create windows so it cannot be the "owner" of the
// clipboard's contents.  // See http://crbug.com/5823.
void WriteObjectsOnUIThread(ui::Clipboard::ObjectMap* objects) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  clipboard->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, *objects);
}

}  // namespace

#endif

ClipboardMessageFilter::ClipboardMessageFilter() {}

void ClipboardMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  // Clipboard writes should always occur on the UI thread due the restrictions
  // of various platform APIs. In general, the clipboard is not thread-safe, so
  // all clipboard calls should be serviced from the UI thread.
  //
  // Windows needs clipboard reads to be serviced from the IO thread because
  // these are sync IPCs which can result in deadlocks with NPAPI plugins if
  // serviced from the UI thread. Note that Windows clipboard calls ARE
  // thread-safe so it is ok for reads and writes to be serviced from different
  // threads.
#if !defined(OS_WIN)
  if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
    *thread = BrowserThread::UI;
#endif

#if defined(OS_WIN)
  if (message.type() == ClipboardHostMsg_ReadImage::ID)
    *thread = BrowserThread::FILE;
#endif
}

bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message,
                                               bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(ClipboardMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsAsync, OnWriteObjectsAsync)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteObjectsSync, OnWriteObjectsSync)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_GetSequenceNumber, OnGetSequenceNumber)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_IsFormatAvailable, OnIsFormatAvailable)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_Clear, OnClear)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAvailableTypes,
                        OnReadAvailableTypes)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAsciiText, OnReadAsciiText)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadRTF, OnReadRTF)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadCustomData, OnReadCustomData)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadData, OnReadData)
#if defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync,
                        OnFindPboardWriteString)
#endif
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

ClipboardMessageFilter::~ClipboardMessageFilter() {
}

void ClipboardMessageFilter::OnWriteObjectsSync(
    ui::Clipboard::ObjectMap objects,
    base::SharedMemoryHandle bitmap_handle) {
  DCHECK(base::SharedMemory::IsHandleValid(bitmap_handle))
      << "Bad bitmap handle";
  // Splice the shared memory handle into the clipboard data.
  ui::Clipboard::ReplaceSharedMemHandle(&objects, bitmap_handle, PeerHandle());
#if defined(OS_WIN)
  // We cannot write directly from the IO thread, and cannot service the IPC
  // on the UI thread. We'll copy the relevant data and get a handle to any
  // shared memory so it doesn't go away when we resume the renderer, and post
  // a task to perform the write on the UI thread.
  ui::Clipboard::ObjectMap* long_living_objects = new ui::Clipboard::ObjectMap;
  long_living_objects->swap(objects);

  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&WriteObjectsOnUIThread, base::Owned(long_living_objects)));
#else
  GetClipboard()->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, objects);
#endif
}

void ClipboardMessageFilter::OnWriteObjectsAsync(
    const ui::Clipboard::ObjectMap& objects) {
  // This async message doesn't support shared-memory based bitmaps; they must
  // be removed otherwise we might dereference a rubbish pointer.
  scoped_ptr<ui::Clipboard::ObjectMap> sanitized_objects(
      new ui::Clipboard::ObjectMap(objects));
  sanitized_objects->erase(ui::Clipboard::CBF_SMBITMAP);

#if defined(OS_WIN)
  // We cannot write directly from the IO thread, and cannot service the IPC
  // on the UI thread. We'll copy the relevant data and post a task to preform
  // the write on the UI thread.
  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(
          &WriteObjectsOnUIThread, base::Owned(sanitized_objects.release())));
#else
  GetClipboard()->WriteObjects(
      ui::CLIPBOARD_TYPE_COPY_PASTE, *sanitized_objects.get());
#endif
}

void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type,
                                                 uint64* sequence_number) {
  *sequence_number = GetClipboard()->GetSequenceNumber(type);
}

void ClipboardMessageFilter::OnReadAvailableTypes(ui::ClipboardType type,
                                                  std::vector<string16>* types,
                                                  bool* contains_filenames) {
  GetClipboard()->ReadAvailableTypes(type, types, contains_filenames);
}

void ClipboardMessageFilter::OnIsFormatAvailable(
    const ui::Clipboard::FormatType& format,
    ui::ClipboardType type,
    bool* result) {
  *result = GetClipboard()->IsFormatAvailable(format, type);
}

void ClipboardMessageFilter::OnClear(ui::ClipboardType type) {
  GetClipboard()->Clear(type);
}

void ClipboardMessageFilter::OnReadText(ui::ClipboardType type,
                                        string16* result) {
  GetClipboard()->ReadText(type, result);
}

void ClipboardMessageFilter::OnReadAsciiText(ui::ClipboardType type,
                                             std::string* result) {
  GetClipboard()->ReadAsciiText(type, result);
}

void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type,
                                        string16* markup,
                                        GURL* url,
                                        uint32* fragment_start,
                                        uint32* fragment_end) {
  std::string src_url_str;
  GetClipboard()->ReadHTML(type, markup, &src_url_str, fragment_start,
                           fragment_end);
  *url = GURL(src_url_str);
}

void ClipboardMessageFilter::OnReadRTF(ui::ClipboardType type,
                                       std::string* result) {
  GetClipboard()->ReadRTF(type, result);
}

void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type,
                                         IPC::Message* reply_msg) {
  SkBitmap bitmap = GetClipboard()->ReadImage(type);

#if defined(USE_X11)
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      base::Bind(
          &ClipboardMessageFilter::OnReadImageReply, this, bitmap, reply_msg));
#else
  OnReadImageReply(bitmap, reply_msg);
#endif
}

void ClipboardMessageFilter::OnReadImageReply(
    const SkBitmap& bitmap, IPC::Message* reply_msg) {
  base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle();
  uint32 image_size = 0;
  if (!bitmap.isNull()) {
    std::vector<unsigned char> png_data;
    if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
      base::SharedMemory buffer;
      if (buffer.CreateAndMapAnonymous(png_data.size())) {
        memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size());
        if (buffer.GiveToProcess(PeerHandle(), &image_handle)) {
          image_size = png_data.size();
        }
      }
    }
  }
  ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle,
                                               image_size);
  Send(reply_msg);
}

void ClipboardMessageFilter::OnReadCustomData(ui::ClipboardType clipboard_type,
                                              const string16& type,
                                              string16* result) {
  GetClipboard()->ReadCustomData(clipboard_type, type, result);
}

void ClipboardMessageFilter::OnReadData(const ui::Clipboard::FormatType& format,
                                        std::string* data) {
  GetClipboard()->ReadData(format, data);
}

// static
ui::Clipboard* ClipboardMessageFilter::GetClipboard() {
  // We have a static instance of the clipboard service for use by all message
  // filters.  This instance lives for the life of the browser processes.
  static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  return clipboard;
}

}  // namespace content
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transliteration_Ignore.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:57:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_
#define _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_

#include <transliteration_commonclass.hxx>
#include <i18nutil/oneToOneMapping.hxx>

typedef sal_Unicode (*TransFunc)(const sal_Unicode);

typedef struct {
    sal_Unicode previousChar;
    sal_Unicode currentChar;
    sal_Unicode replaceChar;
    sal_Bool two2one;
} Mapping;

namespace com { namespace sun { namespace star { namespace i18n {

class transliteration_Ignore : public transliteration_commonclass
{
public:
        virtual rtl::OUString SAL_CALL
        folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, com::sun::star::uno::Sequence< sal_Int32 >& offset)
        throw(com::sun::star::uno::RuntimeException);

        // This method is shared.
        sal_Bool SAL_CALL
        equals( const rtl::OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
            const rtl::OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 )
        throw(com::sun::star::uno::RuntimeException);

        // This method is implemented in sub class if needed. Otherwise, the method implemented in this class will be used.
        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
        transliterateRange( const rtl::OUString& str1, const rtl::OUString& str2 )
        throw(com::sun::star::uno::RuntimeException);

        // Methods which are shared.
        sal_Int16 SAL_CALL getType(  ) throw(com::sun::star::uno::RuntimeException);

        rtl::OUString SAL_CALL
        transliterate( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, com::sun::star::uno::Sequence< sal_Int32 >& offset  )
        throw(com::sun::star::uno::RuntimeException);

        virtual sal_Unicode SAL_CALL
        transliterateChar2Char( sal_Unicode inChar)
        throw(com::sun::star::uno::RuntimeException,
            com::sun::star::i18n::MultipleCharsOutputException);

        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
        transliterateRange( const rtl::OUString& str1, const rtl::OUString& str2, XTransliteration& t1, XTransliteration& t2 )
        throw(com::sun::star::uno::RuntimeException);

protected:
        TransFunc func;
        oneToOneMapping *table;
        Mapping *map;
};

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name ();\
};

#if defined( TRANSLITERATION_BaFa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(BaFa_ja_JP)
#endif
#if defined( TRANSLITERATION_HyuByu_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(HyuByu_ja_JP)
#endif
#if defined( TRANSLITERATION_SeZe_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(SeZe_ja_JP)
#endif
#if defined( TRANSLITERATION_TiJi_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TiJi_ja_JP)
#endif
#if defined( TRANSLITERATION_MiddleDot_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(MiddleDot_ja_JP)
#endif
#if defined( TRANSLITERATION_MinusSign_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(MinusSign_ja_JP)
#endif
#if defined( TRANSLITERATION_Separator_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Separator_ja_JP)
#endif
#if defined( TRANSLITERATION_Space_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Space_ja_JP)
#endif
#if defined( TRANSLITERATION_TraditionalKana_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TraditionalKana_ja_JP)
#endif
#if defined( TRANSLITERATION_TraditionalKanji_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TraditionalKanji_ja_JP)
#endif
#if defined( TRANSLITERATION_ZiZu_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(ZiZu_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name () {\
            func = (TransFunc) 0;\
            table = 0;\
            map = 0;\
            transliterationName = "ignore"#name;\
            implementationName = "com.sun.star.i18n.Transliteration.ignore"#name;\
        };\
        rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, \
                com::sun::star::uno::Sequence< sal_Int32 >& offset) throw(com::sun::star::uno::RuntimeException); \
};

#if defined( TRANSLITERATION_KiKuFollowedBySa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(KiKuFollowedBySa_ja_JP)
#endif
#if defined( TRANSLITERATION_IandEfollowedByYa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(IandEfollowedByYa_ja_JP)
#endif
#if defined( TRANSLITERATION_IterationMark_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(IterationMark_ja_JP)
#endif
#if defined( TRANSLITERATION_ProlongedSoundMark_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(ProlongedSoundMark_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name () {\
            func = (TransFunc) 0;\
            table = 0;\
            map = 0;\
            transliterationName = "ignore"#name;\
            implementationName = "com.sun.star.i18n.Transliteration.ignore"#name;\
        };\
        rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, \
                com::sun::star::uno::Sequence< sal_Int32 >& offset) throw(com::sun::star::uno::RuntimeException); \
        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL transliterateRange( const rtl::OUString& str1, \
                const rtl::OUString& str2 ) throw(com::sun::star::uno::RuntimeException); \
        sal_Unicode SAL_CALL \
        transliterateChar2Char( sal_Unicode inChar) \
        throw(com::sun::star::uno::RuntimeException,\
            com::sun::star::i18n::MultipleCharsOutputException);\
};

#if defined( TRANSLITERATION_Kana ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Kana)
#endif
#if defined( TRANSLITERATION_Width ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Width)
#endif
#if defined( TRANSLITERATION_Size_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Size_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

} } } }

#endif // _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_
<commit_msg>INTEGRATION: CWS warnings01 (1.7.14); FILE MERGED 2005/11/10 10:14:59 pl 1.7.14.1: #i53898# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transliteration_Ignore.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 04:41:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_
#define _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_

#include <transliteration_commonclass.hxx>
#include <i18nutil/oneToOneMapping.hxx>

typedef sal_Unicode (*TransFunc)(const sal_Unicode);

typedef struct {
    sal_Unicode previousChar;
    sal_Unicode currentChar;
    sal_Unicode replaceChar;
    sal_Bool two2one;
} Mapping;

namespace com { namespace sun { namespace star { namespace i18n {

class transliteration_Ignore : public transliteration_commonclass
{
public:
        virtual rtl::OUString SAL_CALL
        folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, com::sun::star::uno::Sequence< sal_Int32 >& offset)
        throw(com::sun::star::uno::RuntimeException);

        // This method is shared.
        sal_Bool SAL_CALL
        equals( const rtl::OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
            const rtl::OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 )
        throw(com::sun::star::uno::RuntimeException);

        // This method is implemented in sub class if needed. Otherwise, the method implemented in this class will be used.
        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
        transliterateRange( const rtl::OUString& str1, const rtl::OUString& str2 )
        throw(com::sun::star::uno::RuntimeException);

        // Methods which are shared.
        sal_Int16 SAL_CALL getType(  ) throw(com::sun::star::uno::RuntimeException);

        rtl::OUString SAL_CALL
        transliterate( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, com::sun::star::uno::Sequence< sal_Int32 >& offset  )
        throw(com::sun::star::uno::RuntimeException);

        virtual sal_Unicode SAL_CALL
        transliterateChar2Char( sal_Unicode inChar)
        throw(com::sun::star::uno::RuntimeException,
            com::sun::star::i18n::MultipleCharsOutputException);

        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
        transliterateRange( const rtl::OUString& str1, const rtl::OUString& str2, XTransliteration& t1, XTransliteration& t2 )
        throw(com::sun::star::uno::RuntimeException);

protected:
        TransFunc func;
        oneToOneMapping *table;
        Mapping *map;
};

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name ();\
};

#if defined( TRANSLITERATION_BaFa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(BaFa_ja_JP)
#endif
#if defined( TRANSLITERATION_HyuByu_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(HyuByu_ja_JP)
#endif
#if defined( TRANSLITERATION_SeZe_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(SeZe_ja_JP)
#endif
#if defined( TRANSLITERATION_TiJi_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TiJi_ja_JP)
#endif
#if defined( TRANSLITERATION_MiddleDot_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(MiddleDot_ja_JP)
#endif
#if defined( TRANSLITERATION_MinusSign_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(MinusSign_ja_JP)
#endif
#if defined( TRANSLITERATION_Separator_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Separator_ja_JP)
#endif
#if defined( TRANSLITERATION_Space_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Space_ja_JP)
#endif
#if defined( TRANSLITERATION_TraditionalKana_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TraditionalKana_ja_JP)
#endif
#if defined( TRANSLITERATION_TraditionalKanji_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(TraditionalKanji_ja_JP)
#endif
#if defined( TRANSLITERATION_ZiZu_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(ZiZu_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name () {\
            func = (TransFunc) 0;\
            table = 0;\
            map = 0;\
            transliterationName = "ignore"#name;\
            implementationName = "com.sun.star.i18n.Transliteration.ignore"#name;\
        };\
        rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, \
                com::sun::star::uno::Sequence< sal_Int32 >& offset) throw(com::sun::star::uno::RuntimeException); \
};

#if defined( TRANSLITERATION_KiKuFollowedBySa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(KiKuFollowedBySa_ja_JP)
#endif
#if defined( TRANSLITERATION_IandEfollowedByYa_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(IandEfollowedByYa_ja_JP)
#endif
#if defined( TRANSLITERATION_IterationMark_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(IterationMark_ja_JP)
#endif
#if defined( TRANSLITERATION_ProlongedSoundMark_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(ProlongedSoundMark_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

#define TRANSLITERATION_IGNORE( name ) \
class ignore##name : public transliteration_Ignore {\
public:\
        ignore##name () {\
            func = (TransFunc) 0;\
            table = 0;\
            map = 0;\
            transliterationName = "ignore"#name;\
            implementationName = "com.sun.star.i18n.Transliteration.ignore"#name;\
        };\
        rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, \
                com::sun::star::uno::Sequence< sal_Int32 >& offset) throw(com::sun::star::uno::RuntimeException); \
        using transliteration_Ignore::transliterateRange;\
        com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL transliterateRange( const rtl::OUString& str1, \
                const rtl::OUString& str2 ) throw(com::sun::star::uno::RuntimeException); \
        sal_Unicode SAL_CALL \
        transliterateChar2Char( sal_Unicode inChar) \
        throw(com::sun::star::uno::RuntimeException,\
            com::sun::star::i18n::MultipleCharsOutputException);\
};

#if defined( TRANSLITERATION_Kana ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Kana)
#endif
#if defined( TRANSLITERATION_Width ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Width)
#endif
#if defined( TRANSLITERATION_Size_ja_JP ) || defined( TRANSLITERATION_ALL )
TRANSLITERATION_IGNORE(Size_ja_JP)
#endif
#undef TRANSLITERATION_IGNORE

} } } }

#endif // _I18N_TRANSLITERATION_TRANSLITERATION_IGNORE_H_
<|endoftext|>


<commit_before>// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_RENDERIMAGE_HPP
#define NAZARA_RENDERIMAGE_HPP

#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <functional>

namespace Nz
{
	class CommandBuffer;
	class CommandBufferBuilder;
	class UploadPool;

	class NAZARA_RENDERER_API RenderImage
	{
		public:
			class Releasable;
			template<typename T> class ReleasableLambda;

			virtual ~RenderImage();

			virtual void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) = 0;

			inline void FlushReleaseQueue();

			virtual UploadPool& GetUploadPool() = 0;

			template<typename F> void PushReleaseCallback(F&& callback);

			virtual void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) = 0;

			virtual void Present() = 0;

		protected:
			RenderImage() = default;
			RenderImage(const RenderImage&) = delete;
			RenderImage(RenderImage&&) = delete;

		private:
			static constexpr std::size_t BlockSize = 4 * 1024;

			using Block = std::vector<UInt8>;

			std::vector<Releasable*> m_releaseQueue;
			std::vector<Block> m_releaseMemoryPool;
	};

	class NAZARA_RENDERER_API RenderImage::Releasable
	{
		public:
			virtual ~Releasable();

			virtual void Release() = 0;
	};

	template<typename T>
	class RenderImage::ReleasableLambda : public Releasable
	{
		public:
			template<typename U> ReleasableLambda(U&& lambda);
			ReleasableLambda(const ReleasableLambda&) = delete;
			ReleasableLambda(ReleasableLambda&&) = delete;
			~ReleasableLambda() = default;

			void Release() override;

			ReleasableLambda& operator=(const ReleasableLambda&) = delete;
			ReleasableLambda& operator=(ReleasableLambda&&) = delete;

		private:
			T m_lambda;
	};
}

#include <Nazara/Renderer/RenderImage.inl>

#endif // NAZARA_RENDERIMAGE_HPP
<commit_msg>Renderer: OCD fix<commit_after>// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_RENDERIMAGE_HPP
#define NAZARA_RENDERIMAGE_HPP

#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <functional>

namespace Nz
{
	class CommandBuffer;
	class CommandBufferBuilder;
	class UploadPool;

	class NAZARA_RENDERER_API RenderImage
	{
		public:
			class Releasable;
			template<typename T> class ReleasableLambda;

			virtual ~RenderImage();

			virtual void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) = 0;

			inline void FlushReleaseQueue();

			virtual UploadPool& GetUploadPool() = 0;

			virtual void Present() = 0;

			template<typename F> void PushReleaseCallback(F&& callback);

			virtual void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) = 0;

		protected:
			RenderImage() = default;
			RenderImage(const RenderImage&) = delete;
			RenderImage(RenderImage&&) = delete;

		private:
			static constexpr std::size_t BlockSize = 4 * 1024;

			using Block = std::vector<UInt8>;

			std::vector<Releasable*> m_releaseQueue;
			std::vector<Block> m_releaseMemoryPool;
	};

	class NAZARA_RENDERER_API RenderImage::Releasable
	{
		public:
			virtual ~Releasable();

			virtual void Release() = 0;
	};

	template<typename T>
	class RenderImage::ReleasableLambda : public Releasable
	{
		public:
			template<typename U> ReleasableLambda(U&& lambda);
			ReleasableLambda(const ReleasableLambda&) = delete;
			ReleasableLambda(ReleasableLambda&&) = delete;
			~ReleasableLambda() = default;

			void Release() override;

			ReleasableLambda& operator=(const ReleasableLambda&) = delete;
			ReleasableLambda& operator=(ReleasableLambda&&) = delete;

		private:
			T m_lambda;
	};
}

#include <Nazara/Renderer/RenderImage.inl>

#endif // NAZARA_RENDERIMAGE_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2013-2018 mogemimi. Distributed under the MIT license.

#pragma once

#include <chrono>

namespace Pomdog {

using Duration = std::chrono::duration<double>;

} // namespace Pomdog
<commit_msg>Add documentation for Duration<commit_after>// Copyright (c) 2013-2018 mogemimi. Distributed under the MIT license.

#pragma once

#include <chrono>

namespace Pomdog {

/// Basic time unit (ms).
using Duration = std::chrono::duration<double>;

} // namespace Pomdog
<|endoftext|>


<commit_before><commit_msg>SomaticReportHelper: Bugfix QBIC file generation<commit_after><|endoftext|>


<commit_before>#include <cppunit/TestFailure.h>
#include <cppunit/TestResultCollector.h>

CPPUNIT_NS_BEGIN

TestResultCollector::TestResultCollector( SynchronizationObject *syncObject )
    : TestSuccessListener( syncObject )
{
  reset();
}

TestResultCollector::~TestResultCollector()
{
}

void
TestResultCollector::freeFailures()
{
  TestFailures::iterator itFailure = m_failures.begin();
  while ( itFailure != m_failures.end() )
    delete *itFailure++;
}

void
TestResultCollector::reset()
{
  TestSuccessListener::reset();

  ExclusiveZone zone( m_syncObject );
  freeFailures();
  m_testErrors = 0;
  m_tests.clear();
  m_failures.clear();
}

void
TestResultCollector::startTest( Test *test )
{
  ExclusiveZone zone (m_syncObject);
  m_tests.push_back( test );
}

void
TestResultCollector::addFailure( const TestFailure &failure )
{
  TestSuccessListener::addFailure( failure );

  ExclusiveZone zone( m_syncObject );
  if ( failure.isError() )
    ++m_testErrors;
  m_failures.push_back( failure.clone() );
}

/// Gets the number of run tests.
int
TestResultCollector::runTests() const
{
  ExclusiveZone zone( m_syncObject );
  return m_tests.size();
}

/// Gets the number of detected errors (uncaught exception).
int
TestResultCollector::testErrors() const
{
  ExclusiveZone zone( m_syncObject );
  return m_testErrors;
}

/// Gets the number of detected failures (failed assertion).
int
TestResultCollector::testFailures() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures.size() - m_testErrors;
}

/// Gets the total number of detected failures.
int
TestResultCollector::testFailuresTotal() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures.size();
}

/// Returns a the list failures (random access collection).
const TestResultCollector::TestFailures &
TestResultCollector::failures() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures;
}

const TestResultCollector::Tests &
TestResultCollector::tests() const
{
  ExclusiveZone zone( m_syncObject );
  return m_tests;
}

CPPUNIT_NS_END

<commit_msg>* src/cppunit/TestResultCollector.cpp: fixed memory leak in destructor.<commit_after>#include <cppunit/TestFailure.h>
#include <cppunit/TestResultCollector.h>

CPPUNIT_NS_BEGIN

TestResultCollector::TestResultCollector( SynchronizationObject *syncObject )
    : TestSuccessListener( syncObject )
{
  reset();
}

TestResultCollector::~TestResultCollector()
{
  freeFailures();
}

void
TestResultCollector::freeFailures()
{
  TestFailures::iterator itFailure = m_failures.begin();
  while ( itFailure != m_failures.end() )
    delete *itFailure++;
  m_failures.clear();
}

void
TestResultCollector::reset()
{
  TestSuccessListener::reset();

  ExclusiveZone zone( m_syncObject );
  freeFailures();
  m_testErrors = 0;
  m_tests.clear();
}

void
TestResultCollector::startTest( Test *test )
{
  ExclusiveZone zone (m_syncObject);
  m_tests.push_back( test );
}

void
TestResultCollector::addFailure( const TestFailure &failure )
{
  TestSuccessListener::addFailure( failure );

  ExclusiveZone zone( m_syncObject );
  if ( failure.isError() )
    ++m_testErrors;
  m_failures.push_back( failure.clone() );
}

/// Gets the number of run tests.
int
TestResultCollector::runTests() const
{
  ExclusiveZone zone( m_syncObject );
  return m_tests.size();
}

/// Gets the number of detected errors (uncaught exception).
int
TestResultCollector::testErrors() const
{
  ExclusiveZone zone( m_syncObject );
  return m_testErrors;
}

/// Gets the number of detected failures (failed assertion).
int
TestResultCollector::testFailures() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures.size() - m_testErrors;
}

/// Gets the total number of detected failures.
int
TestResultCollector::testFailuresTotal() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures.size();
}

/// Returns a the list failures (random access collection).
const TestResultCollector::TestFailures &
TestResultCollector::failures() const
{
  ExclusiveZone zone( m_syncObject );
  return m_failures;
}

const TestResultCollector::Tests &
TestResultCollector::tests() const
{
  ExclusiveZone zone( m_syncObject );
  return m_tests;
}

CPPUNIT_NS_END

<|endoftext|>


<commit_before>// Copyright © 2013 Lénaïc Bagnères, hnc@singularity.fr

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file
 * @brief Provides Boost Serialization for std (std::vector, std::list, ...)
 */

#ifndef HNC_BOOST_SERIALIZATION_STD_HPP
#define HNC_BOOST_SERIALIZATION_STD_HPP

#ifndef NO_HNC_Boost_Serialization

	#include <boost/serialization/export.hpp>

	#include <boost/serialization/array.hpp>
	#include <boost/serialization/bitset.hpp>
	#include <boost/serialization/complex.hpp>
	#include <boost/serialization/deque.hpp>
	#include <boost/serialization/list.hpp>
	#include <boost/serialization/map.hpp>
	#include <boost/serialization/factory.hpp>
	#include <boost/serialization/set.hpp>
	#include <boost/serialization/string.hpp>
	#include <boost/serialization/utility.hpp>
	#include <boost/serialization/valarray.hpp>
	#include <boost/serialization/vector.hpp>

#endif

#endif
<commit_msg>Fix boost/serialization/vector.hpp include in boost_serialization_std.hpp<commit_after>// Copyright © 2013 Lénaïc Bagnères, hnc@singularity.fr

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file
 * @brief Provides Boost Serialization for std (std::vector, std::list, ...)
 */

#ifndef HNC_BOOST_SERIALIZATION_STD_HPP
#define HNC_BOOST_SERIALIZATION_STD_HPP

#ifndef NO_HNC_Boost_Serialization

	#include <boost/serialization/export.hpp>

	#include <boost/serialization/array.hpp>
	#include <boost/serialization/bitset.hpp>
	#include <boost/serialization/complex.hpp>
	#include <boost/serialization/deque.hpp>
	#include <boost/serialization/list.hpp>
	#include <boost/serialization/map.hpp>
	#include <boost/serialization/factory.hpp>
	#include <boost/serialization/set.hpp>
	#include <boost/serialization/string.hpp>
	#include <boost/serialization/utility.hpp>
	#include <boost/serialization/valarray.hpp>
	#define STD std
	#include <boost/serialization/vector.hpp>
	#undef STD

#endif

#endif
<|endoftext|>