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

#ifndef AABB_INCLUDE_ONCE
#define AABB_INCLUDE_ONCE

#include <vlCore/Vector3.hpp>
#include <vlCore/Matrix4.hpp>

namespace vl
{
  //-----------------------------------------------------------------------------
  // AABB
  //-----------------------------------------------------------------------------
  /**
   * The AABB class implements an axis-aligned bounding box using vl::Real precision.
  */
  class AABB
  {
  public:
    AABB();
    AABB( const vec3& center, Real radius );
    AABB( const vec3& pt1, const vec3& pt2, Real displace=0);

    void setNull() { mMin = 1; mMax = -1; }
    bool isNull()  const { return mMin.x() > mMax.x() || mMin.y() > mMax.y() || mMin.z() > mMax.z(); }
    bool isPoint() const { return mMin == mMax; }
    void enlarge(Real displace);
    void addPoint(const vec3& v, Real radius);
    bool intersects(const AABB & bb) const;
    vec3 clip(const vec3& v, bool clipx=true, bool clipy=true, bool clipz=true) const;
    bool isInside(const vec3& v, bool clipx, bool clipy, bool clipz) const;
    bool isInside(const vec3& v) const;
    Real height() const;
    Real width() const;
    Real depth() const;
    AABB operator+(const AABB& aabb) const;
    const AABB& operator+=(const AABB& other)
    {
      *this = *this + other;
      return *this;
    }
    AABB operator+(const vec3& p)
    {
      AABB aabb = *this;
      aabb += p;
      return aabb;
    }
    const AABB& operator+=(const vec3& p)
    {
      addPoint(p);
      return *this;
    }
    vec3 center() const;
    Real area() const
    {
      if (isNull())
        return 0;
      else
        return width()*height()*depth();
    }
    Real longestSideLength() const
    {
      Real side = width();
      if (height() > side)
        side = height();
      if (depth() > side)
        side = depth();
      return side;
    }
    void addPoint(const vec3& v)
    {
      if (isNull())
      {
        mMax = v;
        mMin = v;
        return;
      }

      if ( mMax.x() < v.x() ) mMax.x() = v.x();
      if ( mMax.y() < v.y() ) mMax.y() = v.y();
      if ( mMax.z() < v.z() ) mMax.z() = v.z();
      if ( mMin.x() > v.x() ) mMin.x() = v.x();
      if ( mMin.y() > v.y() ) mMin.y() = v.y();
      if ( mMin.z() > v.z() ) mMin.z() = v.z();
    }
    void transformed(AABB& aabb, const mat4& mat) const
    {
      aabb.setNull();
      if ( !isNull() )
      {
        aabb.addPoint( mat * vec3(minCorner().x(), minCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), maxCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), maxCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), minCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), minCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), maxCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), maxCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), minCorner().y(), maxCorner().z()) );
      }
    }
    AABB transformed(const mat4& mat) const
    {
      AABB aabb;
      transformed(aabb, mat);
      return aabb;
    }
    const vec3& minCorner() const { return mMin; }
    const vec3& maxCorner() const { return mMax; }
    void setMinCorner(Real x, Real y, Real z) { mMin = vec3(x,y,z); }
    void setMinCorner(const vec3& v) { mMin = v; }
    void setMaxCorner(Real x, Real y, Real z) { mMax = vec3(x,y,z); }
    void setMaxCorner(const vec3& v) { mMax = v; }
    Real volume() const { return width() * height() * depth(); }

  protected:
    vec3 mMin;
    vec3 mMax;
  };
}

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

#ifndef AABB_INCLUDE_ONCE
#define AABB_INCLUDE_ONCE

#include <vlCore/Vector3.hpp>
#include <vlCore/Matrix4.hpp>

namespace vl
{
  //-----------------------------------------------------------------------------
  // AABB
  //-----------------------------------------------------------------------------
  /**
   * The AABB class implements an axis-aligned bounding box using vl::Real precision.
  */
  class AABB
  {
  public:
    AABB();

    AABB( const vec3& center, Real radius );

    AABB( const vec3& pt1, const vec3& pt2, Real displace=0);

    void setNull() { mMin = 1; mMax = -1; }

    bool isNull()  const { return mMin.x() > mMax.x() || mMin.y() > mMax.y() || mMin.z() > mMax.z(); }

    bool isPoint() const { return mMin == mMax; }

    void enlarge(Real displace);

    void addPoint(const vec3& v, Real radius);

    bool intersects(const AABB & bb) const;

    vec3 clip(const vec3& v, bool clipx=true, bool clipy=true, bool clipz=true) const;

    bool isInside(const vec3& v, bool clipx, bool clipy, bool clipz) const;

    bool isInside(const vec3& v) const;

    Real height() const;

    Real width() const;

    Real depth() const;

    bool operator==(const AABB& aabb) const
    {
      return mMin == aabb.mMin && mMax == aabb.mMax;
    }

    bool operator!=(const AABB& aabb) const
    {
      return !operator==(aabb);
    }

    AABB operator+(const AABB& aabb) const;

    const AABB& operator+=(const AABB& other)
    {
      *this = *this + other;
      return *this;
    }

    AABB operator+(const vec3& p)
    {
      AABB aabb = *this;
      aabb += p;
      return aabb;
    }

    const AABB& operator+=(const vec3& p)
    {
      addPoint(p);
      return *this;
    }

    vec3 center() const;

    Real area() const
    {
      if (isNull())
        return 0;
      else
        return width()*height()*depth();
    }

    Real longestSideLength() const
    {
      Real side = width();
      if (height() > side)
        side = height();
      if (depth() > side)
        side = depth();
      return side;
    }

    void addPoint(const vec3& v)
    {
      if (isNull())
      {
        mMax = v;
        mMin = v;
        return;
      }

      if ( mMax.x() < v.x() ) mMax.x() = v.x();
      if ( mMax.y() < v.y() ) mMax.y() = v.y();
      if ( mMax.z() < v.z() ) mMax.z() = v.z();
      if ( mMin.x() > v.x() ) mMin.x() = v.x();
      if ( mMin.y() > v.y() ) mMin.y() = v.y();
      if ( mMin.z() > v.z() ) mMin.z() = v.z();
    }

    void transformed(AABB& aabb, const mat4& mat) const
    {
      aabb.setNull();
      if ( !isNull() )
      {
        aabb.addPoint( mat * vec3(minCorner().x(), minCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), maxCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), maxCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), minCorner().y(), minCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), minCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(minCorner().x(), maxCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), maxCorner().y(), maxCorner().z()) );
        aabb.addPoint( mat * vec3(maxCorner().x(), minCorner().y(), maxCorner().z()) );
      }
    }

    AABB transformed(const mat4& mat) const
    {
      AABB aabb;
      transformed(aabb, mat);
      return aabb;
    }
    const vec3& minCorner() const { return mMin; }
    const vec3& maxCorner() const { return mMax; }
    void setMinCorner(Real x, Real y, Real z) { mMin = vec3(x,y,z); }
    void setMinCorner(const vec3& v) { mMin = v; }
    void setMaxCorner(Real x, Real y, Real z) { mMax = vec3(x,y,z); }
    void setMaxCorner(const vec3& v) { mMax = v; }
    Real volume() const { return width() * height() * depth(); }

  protected:
    vec3 mMin;
    vec3 mMax;
  };
}

#endif
<|endoftext|>


<commit_before>//#include "./stdafx.h"

#include "FileContainer.h"
#include "DocxFormat/Rels/File.h"
#include "FileFactory.h"
#include "DocxFormat/ContentTypes/File.h"
#include "DocxFormat/FileType.h"
#include "DocxFormat/FileTypes.h"
#include "DocxFormat/External/Hyperlink.h"
#include "WrapperFile.h"

namespace PPTX
{
	void FileContainer::read(const OOX::CPath& filename)
	{
		//not implement FileContainer.read
	}

	void FileContainer::read(const PPTX::Rels::File& rels, const OOX::CPath& path)
	{
		//not implement FileContainer.read
	}

	void FileContainer::read(const OOX::CPath& filename, FileMap& map, IPPTXEvent* Event)
	{
		PPTX::Rels::File rels(filename);
		OOX::CPath path = filename.GetDirectory();
		read(rels, path, map, Event);
	}

	void FileContainer::read(const PPTX::Rels::File& rels, const OOX::CPath& path, FileMap& map, IPPTXEvent* Event)
	{
		bool bIsSlide = false;
		PPTX::File* pSrcFile = dynamic_cast<PPTX::File*>(this);
		if (NULL != pSrcFile)
			bIsSlide = (pSrcFile->type() == PPTX::FileTypes::Slide) ? true : false;

		size_t nCount = rels.Relations.m_items.size();
		for (size_t i = 0; i < nCount; ++i)
		{
			const PPTX::Rels::RelationShip* pRelation = &(rels.Relations.m_items[i]);
			OOX::CPath normPath = path / pRelation->target();

			CAtlMap<CString, smart_ptr<PPTX::File>>::CPair* pPair = map.find(normPath);

			if (bIsSlide && (pRelation->type() == PPTX::FileTypes::Slide))
			{
				long percent = Event->GetPercent();

				smart_ptr<PPTX::File> file = smart_ptr<PPTX::File>(new PPTX::HyperLink(pRelation->target()));

				bool res = Event->Progress(0, percent + m_lPercent);
				if (res)
				{
					m_bCancelled = true;
					break;
				}

				add(pRelation->rId(), file);
			}
			else
			{
				if (NULL != pPair)
				{
					add(pRelation->rId(), pPair->m_value);
				}
				else
				{
					long percent = Event->GetPercent();

					smart_ptr<PPTX::File> file = PPTX::FileFactory::CreateFilePPTX(path, *pRelation, map);
					bool res = Event->Progress(0, percent + m_lPercent);
					if (res)
					{
						m_bCancelled = true;
						break;
					}

					map.add(normPath, file);
					add(pRelation->rId(), file);

					smart_ptr<FileContainer> pContainer = file.smart_dynamic_cast<FileContainer>();
					if (pContainer.IsInit())
					{
						pContainer->m_lPercent = m_lPercent;
						Event->AddPercent(m_lPercent);

						pContainer->read(normPath, map, Event);
						m_bCancelled = pContainer->m_bCancelled;
					}
				}
			}
		}
	}

	void FileContainer::write(const OOX::CPath& filename, const OOX::CPath& directory, PPTX::ContentTypes::File& content) const
	{
		PPTX::Rels::File rels;
		OOX::CPath current = filename.GetDirectory();
		write(rels, current, directory, content);
		rels.write(filename);
	}

	void FileContainer::write(PPTX::Rels::File& rels, const OOX::CPath& curdir, const OOX::CPath& directory, PPTX::ContentTypes::File& content) const
	{
		CAtlMap<CString, size_t> namepair;

		POSITION pos = m_container.GetStartPosition();
		while (NULL != pos)
		{
			const CAtlMap<CString, smart_ptr<PPTX::File>>::CPair* pPair = m_container.GetNext(pos);

			smart_ptr<PPTX::File>		pFile	= pPair->m_value;
			smart_ptr<PPTX::External>	pExt	= pFile.smart_dynamic_cast<PPTX::External>();

			if (!pExt.IsInit())
			{
				smart_ptr<PPTX::WrapperFile> file = pFile.smart_dynamic_cast<PPTX::WrapperFile>();

				if (file.IsInit())
				{
					if (file->GetWrittenStatus() == false)
					{
						OOX::CPath defdir	= pFile->DefaultDirectory();
						OOX::CPath name		= pFile->DefaultFileName();

						//name = name + max_name_index(curdir, name.string());

						OOX::CSystemUtility::CreateDirectories(directory / defdir);
						pFile->write(directory / defdir / name, directory, content);
						rels.registration(pPair->m_key, pFile->type(), defdir / name);
					}
					else
					{
						OOX::CPath defdir	= pFile->DefaultDirectory();
						OOX::CPath name		= file->GetWrittenFileName();

						rels.registration(pPair->m_key, pFile->type(), defdir / name);
					}
				}
				else
				{
					OOX::CPath defdir	= pFile->DefaultDirectory();
					OOX::CPath name		= pFile->DefaultFileName();

					OOX::CSystemUtility::CreateDirectories(directory / defdir);
					pFile->write(directory / defdir / name, directory, content);
					rels.registration(pPair->m_key, pFile->type(), defdir / name);
				}
			}
			else
			{
				rels.registration(pPair->m_key, pExt);
			}
		}
	}

	void FileContainer::WrittenSetFalse()
	{
		POSITION pos = m_container.GetStartPosition();
		while (NULL != pos)
		{
			smart_ptr<PPTX::File> pFile = m_container.GetNextValue(pos);

			smart_ptr<PPTX::WrapperFile>	pWrapFile = pFile.smart_dynamic_cast<PPTX::WrapperFile>();
			smart_ptr<PPTX::FileContainer>	pWrapCont = pFile.smart_dynamic_cast<PPTX::FileContainer>();

			if (pWrapFile.is_init() && !pWrapFile->GetWrittenStatus())
			{
				pWrapFile->WrittenSetFalse();

				if (pWrapCont.is_init())
				{
					pWrapCont->WrittenSetFalse();
				}
			}
		}
	}

	void CCommonRels::_read(const PPTX::Rels::File& rels, const OOX::CPath& path)
	{
		size_t nCount = rels.Relations.m_items.size();
		for (size_t i = 0; i < nCount; ++i)
		{
			const PPTX::Rels::RelationShip* pRelation = &(rels.Relations.m_items[i]);

			smart_ptr<PPTX::File> _file = PPTX::FileFactory::CreateFilePPTX_OnlyMedia(path, *pRelation);
			add(pRelation->rId(), _file);
		}
	}

	void CCommonRels::_read(const OOX::CPath& filename)
	{
		PPTX::Rels::File rels(filename);
		OOX::CPath path = filename.GetDirectory();
		_read(rels, path);
	}
} // namespace PPTX<commit_msg>CAtlMap -> std::map<commit_after>//#include "./stdafx.h"

#include "FileContainer.h"
#include "DocxFormat/Rels/File.h"
#include "FileFactory.h"
#include "DocxFormat/ContentTypes/File.h"
#include "DocxFormat/FileType.h"
#include "DocxFormat/FileTypes.h"
#include "DocxFormat/External/Hyperlink.h"
#include "WrapperFile.h"

#include <map>

namespace PPTX
{
	void FileContainer::read(const OOX::CPath& filename)
	{
		//not implement FileContainer.read
	}

	void FileContainer::read(const PPTX::Rels::File& rels, const OOX::CPath& path)
	{
		//not implement FileContainer.read
	}

	void FileContainer::read(const OOX::CPath& filename, FileMap& map, IPPTXEvent* Event)
	{
		PPTX::Rels::File rels(filename);
		OOX::CPath path = filename.GetDirectory();
		read(rels, path, map, Event);
	}

	void FileContainer::read(const PPTX::Rels::File& rels, const OOX::CPath& path, FileMap& map, IPPTXEvent* Event)
	{
		bool bIsSlide = false;
		PPTX::File* pSrcFile = dynamic_cast<PPTX::File*>(this);
		if (NULL != pSrcFile)
			bIsSlide = (pSrcFile->type() == PPTX::FileTypes::Slide) ? true : false;

		size_t nCount = rels.Relations.m_items.size();
		for (size_t i = 0; i < nCount; ++i)
		{
			const PPTX::Rels::RelationShip* pRelation = &(rels.Relations.m_items[i]);
			OOX::CPath normPath = path / pRelation->target();

			CAtlMap<CString, smart_ptr<PPTX::File>>::CPair* pPair = map.find(normPath);

			if (bIsSlide && (pRelation->type() == PPTX::FileTypes::Slide))
			{
				long percent = Event->GetPercent();

				smart_ptr<PPTX::File> file = smart_ptr<PPTX::File>(new PPTX::HyperLink(pRelation->target()));

				bool res = Event->Progress(0, percent + m_lPercent);
				if (res)
				{
					m_bCancelled = true;
					break;
				}

				add(pRelation->rId(), file);
			}
			else
			{
				if (NULL != pPair)
				{
					add(pRelation->rId(), pPair->m_value);
				}
				else
				{
					long percent = Event->GetPercent();

					smart_ptr<PPTX::File> file = PPTX::FileFactory::CreateFilePPTX(path, *pRelation, map);
					bool res = Event->Progress(0, percent + m_lPercent);
					if (res)
					{
						m_bCancelled = true;
						break;
					}

					map.add(normPath, file);
					add(pRelation->rId(), file);

					smart_ptr<FileContainer> pContainer = file.smart_dynamic_cast<FileContainer>();
					if (pContainer.IsInit())
					{
						pContainer->m_lPercent = m_lPercent;
						Event->AddPercent(m_lPercent);

						pContainer->read(normPath, map, Event);
						m_bCancelled = pContainer->m_bCancelled;
					}
				}
			}
		}
	}

	void FileContainer::write(const OOX::CPath& filename, const OOX::CPath& directory, PPTX::ContentTypes::File& content) const
	{
		PPTX::Rels::File rels;
		OOX::CPath current = filename.GetDirectory();
		write(rels, current, directory, content);
		rels.write(filename);
	}

	void FileContainer::write(PPTX::Rels::File& rels, const OOX::CPath& curdir, const OOX::CPath& directory, PPTX::ContentTypes::File& content) const
	{
		std::map<CString, size_t> mNamePair;
		for (std::map<CString, smart_ptr<PPTX::File>>::const_iterator pPair = m_container.begin(); pPair != m_container.end(); ++pPair)
		{
			smart_ptr<PPTX::File>     pFile = pPair->second;
			smart_ptr<PPTX::External> pExt  = pFile.smart_dynamic_cast<PPTX::External>();
			if ( !pExt.IsInit() )
			{
				smart_ptr<PPTX::WrapperFile> file = pFile.smart_dynamic_cast<PPTX::WrapperFile>();

				if (file.IsInit())
				{
					if (file->GetWrittenStatus() == false)
					{
						OOX::CPath defdir	= pFile->DefaultDirectory();
						OOX::CPath name		= pFile->DefaultFileName();

						//name = name + max_name_index(curdir, name.string());

						OOX::CSystemUtility::CreateDirectories(directory / defdir);
						pFile->write(directory / defdir / name, directory, content);
						rels.registration(pPair->first, pFile->type(), defdir / name);
					}
					else
					{
						OOX::CPath defdir	= pFile->DefaultDirectory();
						OOX::CPath name		= file->GetWrittenFileName();

						rels.registration(pPair->first, pFile->type(), defdir / name);
					}
				}
				else
				{
					OOX::CPath defdir	= pFile->DefaultDirectory();
					OOX::CPath name		= pFile->DefaultFileName();

					OOX::CSystemUtility::CreateDirectories(directory / defdir);
					pFile->write(directory / defdir / name, directory, content);
					rels.registration(pPair->first, pFile->type(), defdir / name);
				}
			}
			else
			{
				rels.registration(pPair->first, pExt);
			}
		}
	}

	void FileContainer::WrittenSetFalse()
	{
		for (std::map<CString, smart_ptr<PPTX::File>>::const_iterator pPair = m_container.begin(); pPair != m_container.end(); ++pPair)
		{
			smart_ptr<PPTX::File> pFile = pPair->second;

			smart_ptr<PPTX::WrapperFile>	pWrapFile = pFile.smart_dynamic_cast<PPTX::WrapperFile>();
			smart_ptr<PPTX::FileContainer>	pWrapCont = pFile.smart_dynamic_cast<PPTX::FileContainer>();

			if (pWrapFile.is_init() && !pWrapFile->GetWrittenStatus())
			{
				pWrapFile->WrittenSetFalse();

				if (pWrapCont.is_init())
				{
					pWrapCont->WrittenSetFalse();
				}
			}
		}
	}

	void CCommonRels::_read(const PPTX::Rels::File& rels, const OOX::CPath& path)
	{
		size_t nCount = rels.Relations.m_items.size();
		for (size_t i = 0; i < nCount; ++i)
		{
			const PPTX::Rels::RelationShip* pRelation = &(rels.Relations.m_items[i]);

			smart_ptr<PPTX::File> _file = PPTX::FileFactory::CreateFilePPTX_OnlyMedia(path, *pRelation);
			add(pRelation->rId(), _file);
		}
	}

	void CCommonRels::_read(const OOX::CPath& filename)
	{
		PPTX::Rels::File rels(filename);
		OOX::CPath path = filename.GetDirectory();
		_read(rels, path);
	}
} // namespace PPTX<|endoftext|>


<commit_before>// Copyright 2017 Jacek Wozniak <mech@themech.net>
#include "./k81x.h"
#include <unistd.h>
#include <cstring>
#include <iostream>

using std::cerr;
using std::cout;
using std::endl;

void usage() {
  cout << "Usage: sudo k81x-fkeys [-d device_path] [-v] on|off" << endl;
  cout << "Controls the functions of Logitech K810/K811 Keyboard F-keys" << endl
       << endl;

  cout << "As seen above, this tool needs root privileges to operate. Options:"
       << endl;
  cout << "\t-d device_path\tDevice path of the Logitech keyboard, usually"
       << endl
       << "\t\t\t/dev/hidraw0. Autodetecion is peformed if this" << endl
       << "\t\t\tparameter is omitted." << endl;
  cout << "\t-v\t\tVerbose mode." << endl;
  cout << "\ton|off\t\t\"on\" causes the F-keys to act like standard" << endl
       << "\t\t\tF1-F12 keys, \"off\" enables the enhanced functions." << endl;
}

int main(int argc, char **argv) {
  bool verbose = false, switch_on;
  const char *device_path = NULL;

  // Fetch the command line arguments.
  int opt;
  while ((opt = getopt(argc, argv, "d:v")) != -1) {
    switch (opt) {
      case 'd':
        device_path = optarg;
        break;
      case 'v':
        verbose = true;
        break;
    }
  }
  if (optind >= argc) {
    // No on/off argument.
    usage();
    return 1;
  }
  if (!strcmp("on", argv[optind])) {
    switch_on = true;
  } else if (!strcmp("off", argv[optind])) {
    switch_on = false;
  } else {
    cerr << "Invalid switch value, should be either \"on\" or \"off\"." << endl;
    usage();
    return 1;
  }

  // Check the privileges.
  if (geteuid() != 0) {
    cerr << "Warning: Program not running as root. It will most likely fail."
         << endl;
  }

  // Initialize the device.
  K81x *k81x = NULL;
  if (device_path == NULL) {
    k81x = K81x::FromAutoFind(verbose);
    if (NULL == k81x) {
      cerr << "Error while looking for a Logitech K810/K811 keyboard." << endl;
    }
  } else {
    k81x = K81x::FromDevicePath(device_path, verbose);
    if (NULL == k81x) {
      cerr
          << "Device " << device_path
          << " cannot be recognized as a supported Logitech K810/K811 keyboard."
          << endl;
    }
  }

  int result = 0;
  if (k81x != NULL) {
    // Switch the Kn keys mode.
    if (!k81x->SetFnKeysMode(switch_on)) {
      cerr << "Error while setting the F-keys mode." << endl;
      result = 1;
    }

    delete k81x;
  } else {
    result = 1;
  }
  if (result && !verbose) {
    cerr << "Try running with -v parameter to get more details." << endl;
  }
  return result;
}
<commit_msg>Silent mode<commit_after>// Copyright 2017 Jacek Wozniak <mech@themech.net>
#include "./k81x.h"
#include <unistd.h>
#include <cstring>
#include <iostream>

using std::cerr;
using std::cout;
using std::endl;

void usage() {
  cout << "Usage: sudo k81x-fkeys [-d device_path] [-v] on|off" << endl;
  cout << "Controls the functions of Logitech K810/K811 Keyboard F-keys" << endl
       << endl;

  cout << "As seen above, this tool needs root privileges to operate. Options:"
       << endl;
  cout << "\t-d device_path\tDevice path of the Logitech keyboard, usually"
       << endl
       << "\t\t\t/dev/hidraw0. Autodetecion is peformed if this" << endl
       << "\t\t\tparameter is omitted." << endl;
  cout << "\t-v\t\tVerbose mode." << endl;
  cout << "\ton|off\t\t\"on\" causes the F-keys to act like standard" << endl
       << "\t\t\tF1-F12 keys, \"off\" enables the enhanced functions." << endl;
}

int main(int argc, char **argv) {
  bool verbose = false, switch_on, silent = false;
  int error_return = 1;
  const char *device_path = NULL;

  // Fetch the command line arguments.
  int opt;
  while ((opt = getopt(argc, argv, "d:vs")) != -1) {
    switch (opt) {
      case 'd':
        device_path = optarg;
        break;
      case 'v':
        verbose = true;
        break;
      case 's':
        silent = true;
        error_return = 0;
        break;
      }
  }
  if (optind >= argc) {
    // No on/off argument.
    usage();
    return error_return;
  }
  if (!strcmp("on", argv[optind])) {
    switch_on = true;
  } else if (!strcmp("off", argv[optind])) {
    switch_on = false;
  } else {
    cerr << "Invalid switch value, should be either \"on\" or \"off\"." << endl;
    usage();
    return error_return;
  }

  // Check the privileges.
  if (geteuid() != 0 && !silent) {
    cerr << "Warning: Program not running as root. It will most likely fail."
         << endl;
  }

  // Initialize the device.
  K81x *k81x = NULL;
  if (device_path == NULL) {
    k81x = K81x::FromAutoFind(verbose);
    if (NULL == k81x && !silent) {
      cerr << "Error while looking for a Logitech K810/K811 keyboard." << endl;
    }
  } else {
    k81x = K81x::FromDevicePath(device_path, verbose);
    if (NULL == k81x && !silent) {
      cerr
          << "Device " << device_path
          << " cannot be recognized as a supported Logitech K810/K811 keyboard."
          << endl;
    }
  }

  int result = 0;
  if (k81x != NULL) {
    // Switch the Kn keys mode.
    if (!k81x->SetFnKeysMode(switch_on) && !silent) {
      cerr << "Error while setting the F-keys mode." << endl;
      result = error_return;
    }

    delete k81x;
  } else {
    result = error_return;
  }
  if (result && !verbose && !silent) {
    cerr << "Try running with -v parameter to get more details." << endl;
  }
  return result;
}
<|endoftext|>


<commit_before>/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* enchant
 * Copyright (C) 2003 Dom Lachowicz, Raphael Finkel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * In addition, as a special exception, Dom Lachowicz
 * gives permission to link the code of this program with
 * the non-LGPL Spelling Provider libraries (eg: a MSFT Office
 * spell checker backend) and distribute linked combinations including
 * the two.  You must obey the GNU General Public License in all
 * respects for all of the code used other than said providers.  If you modify
 * this file, you may extend this exception to your version of the
 * file, but you are not obligated to do so.  If you do not wish to
 * do so, delete this exception statement from your version.
 */

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

#include <string>

#include <glib.h>

// #include <sys/file.h> // only needed if we use flock() below

#include "enchant.h"
#include "enchant-provider.h"

#include <uspell/utf8convert.h>
#include <uspell/uniprops.h>
#include <uspell/uspell.h>

static const size_t MAXALTERNATIVE = 20; // we won't return more than this number of suggestions

typedef struct {
	char *personalName; // name of file containing personal dictionary
	uSpell *manager; // my uSpell instance
} uspellData;

static int
uspell_dict_check (EnchantDict * me, const char *const word, size_t len)
{
	uSpell *manager;
	wide_t *curBuf, *otherBuf, *tmpBuf;
	int length;

	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
	curBuf = reinterpret_cast<wide_t *>(calloc(len+1, sizeof(wide_t)));
#ifdef DEBUG
	fprintf(stdout, "Checking [%s]\n", word);
#endif
	length = utf8_wide(curBuf, reinterpret_cast<const utf8_t *>(word), len+1);
	if (manager->isSpelledRight(curBuf, length)) {
		free(curBuf);
		return 0; // correct the first time
	}
	otherBuf = reinterpret_cast<wide_t *>(calloc(len+1, sizeof(wide_t)));
	if (manager->theFlags & uSpell::upperLower) {
		toUpper(otherBuf, curBuf, length);
		if (manager->isSpelledRight(otherBuf, length)) {
			manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
			free(curBuf);
			free(otherBuf);
			return 0; // correct if converted to all upper case
		}
		tmpBuf = curBuf;
		curBuf = otherBuf;
		otherBuf = tmpBuf;
	}
	if (manager->theFlags & uSpell::hasComposition) {
		unPrecompose(otherBuf, &length, curBuf, length);
		if (manager->isSpelledRight(otherBuf, length)) {
			manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
			free(curBuf);
			free(otherBuf);
			return 0; // correct if precomposed characters expanded, all upper
		}
		tmpBuf = curBuf;
		curBuf = otherBuf;
		otherBuf = tmpBuf;
	}
	if (manager->theFlags & uSpell::hasCompounds) {
		if (manager->isSpelledRightMultiple(curBuf, length)) {
			manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
			free(curBuf);
			free(otherBuf);
			return 0; // correct as two words.  Not right for all languages.
		}
	}
	free(curBuf);
	free(otherBuf);
	return 1;
}

static char **
uspell_dict_suggest (EnchantDict * me, const char *const word,
		     size_t len, size_t * out_n_suggs)
{
	uSpell *manager;

	char **sugg_arr = NULL;
	const utf8_t *sugg;
	wide_t *curBuf;
	int length, i;
	utf8_t **list;

	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;

	list = reinterpret_cast<utf8_t **>(
					   calloc(sizeof(char *), MAXALTERNATIVE));
	curBuf = reinterpret_cast<wide_t *>(calloc(len+1, sizeof(wide_t)));
	length = utf8_wide(curBuf, reinterpret_cast<const utf8_t *>(word), len+1);
	*out_n_suggs = manager->showAlternatives(curBuf, length,
						 list, MAXALTERNATIVE);

	if (*out_n_suggs)
		{
			sugg_arr = g_new0 (char *, *out_n_suggs + 1);
			for (i = 0; i < *out_n_suggs; i++)
				{
					sugg = list[i];
					if (sugg)
						sugg_arr[i] =
							g_strdup (reinterpret_cast<const gchar *>(sugg));
					free(list[i]);
				}
		}
	free(list);
	free(curBuf);
	return sugg_arr;
}

static void
uspell_dict_add_to_personal (EnchantDict * me,
			     const char *const word, size_t len)
{
	uSpell *manager;
	FILE *personalFile;

	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
	manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
	if (!reinterpret_cast<uspellData *>(me->user_data)->personalName)
			return; // no personal file
	personalFile =
		fopen(reinterpret_cast<uspellData *>(me->user_data)->personalName, "a");
	if (personalFile) {
#if 0 // if we ever want to close the race condition, port flock to win32
		flock(fileno(personalFile), LOCK_EX);
		fseek(personalFile, 0, SEEK_END);  // in case someone else intervened
#endif
		fprintf(personalFile, "%s\n", word);
		fclose(personalFile);
	}
}

static void
uspell_dict_add_to_session (EnchantDict * me,
			    const char *const word, size_t len)
{
	uSpell *manager;

	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
	manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
}

static void
uspell_dict_free_suggestions (EnchantDict * me, char **str_list)
{
	g_strfreev (str_list);
}

typedef struct {
	char * language_tag;
	char * corresponding_uspell_file_name;
	int language_flags;
} Mapping;

static const Mapping mapping [] = {
	{"he",    "hebrew",  0},
	{"he_IL", "hebrew",  0},
	{"yi",    "yiddish", uSpell::hasCompounds | uSpell::hasComposition}
};

static const size_t n_mappings = (sizeof(mapping)/sizeof(mapping[0]));

static uspellData *
uspell_request_dict (const char * base, const char * mapping, const int flags)
{
	char *fileName, *transName, *filePart, *transPart,
		*personalPart, *home_dir, * personalName;

	uspellData * data;
	uSpell *manager;

	if (!base)
		return NULL;

	filePart =  g_strconcat(mapping, ".uspell.dat", NULL);
	transPart =  g_strconcat(mapping, ".uspell.trans", NULL);
	fileName = g_build_filename (base, filePart, NULL);
	transName = g_build_filename (base, transPart, NULL);
	g_free(filePart);
	g_free(transPart);

	try {
		manager = new uSpell(fileName, transName, flags);
		home_dir = enchant_get_user_home_dir ();
		if (home_dir) {
				char * private_dir = g_build_filename (home_dir, ".enchant",
						"uspell", NULL);
				personalPart =  g_strconcat(mapping, ".uspell.personal", NULL);
				personalName = g_build_filename (private_dir, personalPart,
						NULL);
				g_free(personalPart);
				(void) manager->assimilateFile(personalName);
		} else {
				personalName = NULL;
		}
	}
	catch (...) {
		manager = NULL;
	}

	g_free (fileName);
	g_free (transName);

	data = g_new0(uspellData, 1);
	data->manager = manager;
	data->personalName = personalName;

	return data;
}

/* in preparation for using win32 registry keys, if necessary */

static char *
uspell_checker_get_prefix (void)
{
#ifdef ENCHANT_USPELL_DICT_DIR
	return g_strdup (ENCHANT_USPELL_DICT_DIR);
#else
	return NULL;
#endif
}

static uspellData *
uspell_request_manager (const char * private_dir, size_t mapIndex)
{
	char * uspell_prefix;

	uspellData * manager = NULL;

	manager = uspell_request_dict (private_dir,
				       mapping[mapIndex].corresponding_uspell_file_name,
				       mapping[mapIndex].language_flags);

	if (!manager) {
		uspell_prefix = uspell_checker_get_prefix ();

		if (uspell_prefix) {
			manager = uspell_request_dict (uspell_prefix,
						       mapping[mapIndex].corresponding_uspell_file_name,
						       mapping[mapIndex].language_flags);
			g_free (uspell_prefix);
		}
	}

	return manager;
}

static EnchantDict *
uspell_provider_request_dict (EnchantProvider * me, const char *const tag)
{
	EnchantDict *dict = NULL;
	uspellData *manager = NULL;
	int mapIndex;

	char * private_dir = NULL, * home_dir;

	home_dir = enchant_get_user_home_dir ();

	if (home_dir) {
		private_dir = g_build_filename (home_dir, ".enchant",
						"uspell", NULL);
		g_free (home_dir);
	}

	for (mapIndex = 0; mapIndex < n_mappings; mapIndex++) {
		if (!strcmp(tag, mapping[mapIndex].language_tag))
			break;
	}

	if (mapIndex < n_mappings) {
		manager = uspell_request_manager (private_dir, mapIndex);
	}

	if (!manager) {
		// try shortened form: he_IL => he
		std::string shortened_dict (tag);
		size_t uscore_pos;

		if ((uscore_pos = shortened_dict.rfind ('_')) != ((size_t)-1)) {
			shortened_dict = shortened_dict.substr(0, uscore_pos);

			for (mapIndex = 0; mapIndex < n_mappings; mapIndex++) {
				if (!strcmp(shortened_dict.c_str(), mapping[mapIndex].language_tag))
					break;
			}

			if (mapIndex < n_mappings) {
				manager = uspell_request_manager (private_dir, mapIndex);
			}
		}
	}

	g_free (private_dir);

	if (!manager)
		return NULL;

	dict = g_new0 (EnchantDict, 1);
	dict->user_data = manager;
	dict->check = uspell_dict_check;
	dict->suggest = uspell_dict_suggest;
	dict->add_to_personal = uspell_dict_add_to_personal;
	dict->add_to_session = uspell_dict_add_to_session;
	dict->store_replacement = 0;
	dict->free_suggestions = uspell_dict_free_suggestions;

	return dict;
}

EnchantDictStatus uspell_provider_dictionary_status(struct str_enchant_provider * me,
						    const char *const tag)
{
	// TODO: a g_file_exists check on the dictionary associated with the tag
	g_warning ("uspell_provider_dictionary_status stub - unimplemented\n");
	return(EDS_UNKNOWN);
}

static void
uspell_provider_dispose_dict (EnchantProvider * me, EnchantDict * dict)
{
	uSpell *manager;
	uspellData *myUspellData = reinterpret_cast<uspellData *>(dict->user_data);
	delete myUspellData->manager;
	if (myUspellData->personalName)
		g_free (myUspellData->personalName);
	g_free (dict->user_data);
	g_free (dict);
}

static void
uspell_provider_dispose (EnchantProvider * me)
{
	g_free (me);
}

static char *
uspell_provider_identify (EnchantProvider * me)
{
	return "uspell";
}

static char *
uspell_provider_describe (EnchantProvider * me)
{
	return "Uspell Provider";
}

extern "C" {

ENCHANT_MODULE_EXPORT (EnchantProvider *)
init_enchant_provider (void)
{
	EnchantProvider *provider;

	provider = g_new0 (EnchantProvider, 1);
	provider->dispose = uspell_provider_dispose;
	provider->request_dict = uspell_provider_request_dict;
	provider->dispose_dict = uspell_provider_dispose_dict;
	provider->dictionary_status = uspell_provider_dictionary_status;
	provider->identify = uspell_provider_identify;
	provider->describe = uspell_provider_describe;

	return provider;
}

}

<commit_msg>uspell now honors the size arguments<commit_after>/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* enchant
 * Copyright (C) 2003 Dom Lachowicz, Raphael Finkel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * In addition, as a special exception, Dom Lachowicz
 * gives permission to link the code of this program with
 * the non-LGPL Spelling Provider libraries (eg: a MSFT Office
 * spell checker backend) and distribute linked combinations including
 * the two.  You must obey the GNU General Public License in all
 * respects for all of the code used other than said providers.  If you modify
 * this file, you may extend this exception to your version of the
 * file, but you are not obligated to do so.  If you do not wish to
 * do so, delete this exception statement from your version.
 */

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

#include <string>

#include <glib.h>

// #include <sys/file.h> // only needed if we use flock() below

#include "enchant.h"
#include "enchant-provider.h"

#include <uspell/utf8convert.h>
#include <uspell/uniprops.h>
#include <uspell/uspell.h>

static const size_t MAXALTERNATIVE = 20; // we won't return more than this number of suggestions
static const size_t MAXCHARS = 100; // maximum number of bytes of utf8 or chars of UCS4 in a word

typedef struct {
	char *personalName; // name of file containing personal dictionary
	uSpell *manager; // my uSpell instance
} uspellData;

static int
uspell_dict_check (EnchantDict * me, const char *const word, size_t len)
{
	uSpell *manager;
	wide_t buf1[MAXCHARS], buf2[MAXCHARS], *curBuf, *otherBuf, *tmpBuf;
	utf8_t myWord[MAXCHARS];
	int length;

	if (len >= MAXCHARS)
		return 1; // too long; can't be right
	memcpy(reinterpret_cast<char *>(myWord), word, len);
	myWord[len] = 0;
	curBuf = buf1;
	otherBuf = buf2;
	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
#ifdef DEBUG
	fprintf(stdout, "Checking [%s]\n", word);
#endif
	length = utf8_wide(curBuf, myWord, MAXCHARS);
	if (manager->isSpelledRight(curBuf, length)) {
		return 0; // correct the first time
	}
	if (manager->theFlags & uSpell::upperLower) {
		toUpper(otherBuf, curBuf, length);
		if (manager->isSpelledRight(otherBuf, length)) {
			manager->acceptWord(myWord);
			return 0; // correct if converted to all upper case
		}
		tmpBuf = curBuf;
		curBuf = otherBuf;
		otherBuf = tmpBuf;
	}
	if (manager->theFlags & uSpell::hasComposition) {
		unPrecompose(otherBuf, &length, curBuf, length);
		if (manager->isSpelledRight(otherBuf, length)) {
			manager->acceptWord(myWord);
			return 0; // correct if precomposed characters expanded, all upper
		}
		tmpBuf = curBuf;
		curBuf = otherBuf;
		otherBuf = tmpBuf;
	}
	if (manager->theFlags & uSpell::hasCompounds) {
		if (manager->isSpelledRightMultiple(curBuf, length)) {
			manager->acceptWord(myWord);
			return 0; // correct as two words.  Not right for all languages.
		}
	}
	return 1;
}

static char **
uspell_dict_suggest (EnchantDict * me, const char *const word,
		     size_t len, size_t * out_n_suggs)
{
	uSpell *manager;
	utf8_t myWord[MAXCHARS];

	char **sugg_arr = NULL;
	const utf8_t *sugg;
	wide_t buf[MAXCHARS];
	int length, i;
	utf8_t **list;

	if (len >= MAXCHARS) // no suggestions; the word is outlandish
		return g_new0 (char *, 1);
	memcpy(reinterpret_cast<char *>(myWord), word, len);
	myWord[len] = 0;
	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;

	list = reinterpret_cast<utf8_t **>(
					   calloc(sizeof(char *), MAXALTERNATIVE));
	length = utf8_wide(buf, myWord, MAXCHARS);
	*out_n_suggs = manager->showAlternatives(buf, length,
						 list, MAXALTERNATIVE);

	if (*out_n_suggs)
		{
			sugg_arr = g_new0 (char *, *out_n_suggs + 1);
			for (i = 0; i < *out_n_suggs; i++)
				{
					sugg = list[i];
					if (sugg)
						sugg_arr[i] =
							g_strdup (reinterpret_cast<const gchar *>(sugg));
					free(list[i]);
				}
		}
	free(list);
	return sugg_arr;
}

static void
uspell_dict_add_to_personal (EnchantDict * me,
			     const char *const word, size_t len)
{
	uSpell *manager;
	FILE *personalFile;
	utf8_t myWord[MAXCHARS];

	if (len >= MAXCHARS) return; // too long; can't be right
	memcpy(reinterpret_cast<char *>(myWord), word, len);
	myWord[len] = 0;
	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
	manager->acceptWord(myWord);
	if (!reinterpret_cast<uspellData *>(me->user_data)->personalName)
			return; // no personal file
	personalFile =
		fopen(reinterpret_cast<uspellData *>(me->user_data)->personalName, "a");
	if (personalFile) {
#if 0 // if we ever want to close the race condition, port flock to win32
		flock(fileno(personalFile), LOCK_EX);
		fseek(personalFile, 0, SEEK_END);  // in case someone else intervened
#endif
		fprintf(personalFile, "%s\n", myWord);
		fclose(personalFile);
	}
}

static void
uspell_dict_add_to_session (EnchantDict * me,
			    const char *const word, size_t len)
{
	uSpell *manager;

	manager = reinterpret_cast<uspellData *>(me->user_data)->manager;
	manager->acceptWord(reinterpret_cast<const utf8_t *>(word));
}

static void
uspell_dict_free_suggestions (EnchantDict * me, char **str_list)
{
	g_strfreev (str_list);
}

typedef struct {
	char * language_tag;
	char * corresponding_uspell_file_name;
	int language_flags;
} Mapping;

static const Mapping mapping [] = {
	{"he",    "hebrew",  0},
	{"he_IL", "hebrew",  0},
	{"yi",    "yiddish", uSpell::hasCompounds | uSpell::hasComposition}
};

static const size_t n_mappings = (sizeof(mapping)/sizeof(mapping[0]));

static uspellData *
uspell_request_dict (const char * base, const char * mapping, const int flags)
{
	char *fileName, *transName, *filePart, *transPart,
		*personalPart, *home_dir, * personalName;

	uspellData * data;
	uSpell *manager;

	if (!base)
		return NULL;

	filePart =  g_strconcat(mapping, ".uspell.dat", NULL);
	transPart =  g_strconcat(mapping, ".uspell.trans", NULL);
	fileName = g_build_filename (base, filePart, NULL);
	transName = g_build_filename (base, transPart, NULL);
	g_free(filePart);
	g_free(transPart);

	try {
		manager = new uSpell(fileName, transName, flags);
		home_dir = enchant_get_user_home_dir ();
		if (home_dir) {
				char * private_dir = g_build_filename (home_dir, ".enchant",
						"uspell", NULL);
				personalPart =  g_strconcat(mapping, ".uspell.personal", NULL);
				personalName = g_build_filename (private_dir, personalPart,
						NULL);
				g_free(personalPart);
				(void) manager->assimilateFile(personalName);
		} else {
				personalName = NULL;
		}
	}
	catch (...) {
		manager = NULL;
	}

	g_free (fileName);
	g_free (transName);

	data = g_new0(uspellData, 1);
	data->manager = manager;
	data->personalName = personalName;

	return data;
}

/* in preparation for using win32 registry keys, if necessary */

static char *
uspell_checker_get_prefix (void)
{
#ifdef ENCHANT_USPELL_DICT_DIR
	return g_strdup (ENCHANT_USPELL_DICT_DIR);
#else
	return NULL;
#endif
}

static uspellData *
uspell_request_manager (const char * private_dir, size_t mapIndex)
{
	char * uspell_prefix;

	uspellData * manager = NULL;

	manager = uspell_request_dict (private_dir,
				       mapping[mapIndex].corresponding_uspell_file_name,
				       mapping[mapIndex].language_flags);

	if (!manager) {
		uspell_prefix = uspell_checker_get_prefix ();

		if (uspell_prefix) {
			manager = uspell_request_dict (uspell_prefix,
						       mapping[mapIndex].corresponding_uspell_file_name,
						       mapping[mapIndex].language_flags);
			g_free (uspell_prefix);
		}
	}

	return manager;
}

static EnchantDict *
uspell_provider_request_dict (EnchantProvider * me, const char *const tag)
{
	EnchantDict *dict = NULL;
	uspellData *manager = NULL;
	int mapIndex;

	char * private_dir = NULL, * home_dir;

	home_dir = enchant_get_user_home_dir ();

	if (home_dir) {
		private_dir = g_build_filename (home_dir, ".enchant",
						"uspell", NULL);
		g_free (home_dir);
	}

	for (mapIndex = 0; mapIndex < n_mappings; mapIndex++) {
		if (!strcmp(tag, mapping[mapIndex].language_tag))
			break;
	}

	if (mapIndex < n_mappings) {
		manager = uspell_request_manager (private_dir, mapIndex);
	}

	if (!manager) {
		// try shortened form: he_IL => he
		std::string shortened_dict (tag);
		size_t uscore_pos;

		if ((uscore_pos = shortened_dict.rfind ('_')) != ((size_t)-1)) {
			shortened_dict = shortened_dict.substr(0, uscore_pos);

			for (mapIndex = 0; mapIndex < n_mappings; mapIndex++) {
				if (!strcmp(shortened_dict.c_str(), mapping[mapIndex].language_tag))
					break;
			}

			if (mapIndex < n_mappings) {
				manager = uspell_request_manager (private_dir, mapIndex);
			}
		}
	}

	g_free (private_dir);

	if (!manager)
		return NULL;

	dict = g_new0 (EnchantDict, 1);
	dict->user_data = manager;
	dict->check = uspell_dict_check;
	dict->suggest = uspell_dict_suggest;
	dict->add_to_personal = uspell_dict_add_to_personal;
	dict->add_to_session = uspell_dict_add_to_session;
	dict->store_replacement = 0;
	dict->free_suggestions = uspell_dict_free_suggestions;

	return dict;
}

EnchantDictStatus uspell_provider_dictionary_status(struct str_enchant_provider * me,
						    const char *const tag)
{
	// TODO: a g_file_exists check on the dictionary associated with the tag
	g_warning ("uspell_provider_dictionary_status stub - unimplemented\n");
	return(EDS_UNKNOWN);
}

static void
uspell_provider_dispose_dict (EnchantProvider * me, EnchantDict * dict)
{
	uSpell *manager;
	uspellData *myUspellData = reinterpret_cast<uspellData *>(dict->user_data);
	delete myUspellData->manager;
	if (myUspellData->personalName)
		g_free (myUspellData->personalName);
	g_free (dict->user_data);
	g_free (dict);
}

static void
uspell_provider_dispose (EnchantProvider * me)
{
	g_free (me);
}

static char *
uspell_provider_identify (EnchantProvider * me)
{
	return "uspell";
}

static char *
uspell_provider_describe (EnchantProvider * me)
{
	return "Uspell Provider";
}

extern "C" {

ENCHANT_MODULE_EXPORT (EnchantProvider *)
init_enchant_provider (void)
{
	EnchantProvider *provider;

	provider = g_new0 (EnchantProvider, 1);
	provider->dispose = uspell_provider_dispose;
	provider->request_dict = uspell_provider_request_dict;
	provider->dispose_dict = uspell_provider_dispose_dict;
	provider->dictionary_status = uspell_provider_dictionary_status;
	provider->identify = uspell_provider_identify;
	provider->describe = uspell_provider_describe;

	return provider;
}

}

<|endoftext|>


<commit_before><commit_msg>saw at least one of these unused by eye, search for more<commit_after><|endoftext|>


<commit_before>#ifndef RENDERER_TRANSFORM_HPP
#define RENDERER_TRANSFORM_HPP

#include "base.hpp"

namespace renderer {

	template<class V, const int M, const int N>
	class MxN {
	public:
		typedef V ValueType;
		static const int row = M;
		static const int col = N;
		V data[M * N];
	public:
		MxN() {
			memset(data, 0, row * col * sizeof(V));
		}
		MxN(std::initializer_list<V> values) {
			int idx = 0;
			for (auto& value : values) {
				data[idx++] = value;
			}
		}
		const V& operator [] (const int i) { return data[i]; }
	};

	template<class T>
	class Matrix final {
	public:
		T * data;
		typedef typename T::ValueType V;
		typedef MxN<V, T::col, T::row> TransT;
	public:
		Matrix() {
			data = GetPool<T>()->newElement(T());
		}

		Matrix(std::initializer_list<V> values) {
			data = GetPool<T>()->newElement(T(std::forward<std::initializer_list<V>>(values)));
		}

		Matrix(Matrix<T>&& m) {
			data = m.data;
			m.data = nullptr;
		}
		virtual ~Matrix() {
			if (!data)
				return;
			auto pool = GetPool<T>();
			pool->deleteElement(data);
		}

		inline int row() {
			return T::row;
		}

		inline int col() {
			return T::col;
		}

		inline bool isSquare() {
			return row() == col();
		}

		inline bool isSameOrder(Matrix<T>& m) {
			return row() == m.row() && col() == m.col();
		}

		//access only
		inline const V& operator [] (const int i) { return static_cast<V>(*((V*)data + i)); }

		Matrix<T>& operator=(Matrix<T>& m) {
			memcpy(data, m.data, row() * col() * sizeof(V));
			return *this;
		}

		Matrix<T> operator+(Matrix<T>& m) {
			return add(m);
		}

		Matrix<T> operator-(Matrix<T>& m) {
			return minus(m);
		}

		Matrix<T> operator*(V v) {
			return multiply(v);
		}

		Matrix<T> operator*(Matrix<T>& m) {
			return multiply(m);
		}

		Matrix<T> operator/(V v) {
			return divide(v);
		}
		//API
		Matrix<T> clone() {
			Matrix<T> result;
			memcpy(result.data, data, row() * col() * sizeof(V));
			return result;
		}

		Matrix<TransT> transpose() {
			Matrix<TransT> result;
			int rowNum = row(), colNum = col();
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					dataOfResult[j * rowNum + i] = (*this)[i * colNum + j];
				}
			}
			return result;
		}

		Matrix<T> add(Matrix<T>& m) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] + m[idx];
				}
			}
			return result;
		}

		Matrix<T> minus(Matrix<T>& m) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] - m[idx];
				}
			}
			return result;
		}

		template<int M, int N>
		Matrix<T> multiply(Matrix<MxN<V, M, N>>& m) {
			Matrix<MxN<V, T::row, N>> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < m.row(); i++) {
				for (int j = 0; j < m.col(); j++) {
					V total = 0;
					for (int k = 0; k < colNum; k++) {
						total += (*this)[i * colNum + k] * m[k * m.col() + j];
					}
					dataOfResult[i * m.col() + j] = total;
				}
			}
			return result;
		}

		Matrix<T> multiply(V v) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] *v;
				}
			}
			return result;
		}

		Matrix<T> divide(V v) {
			return multiply(V(1.0)/v);
		}

		Matrix<T> power(int pow) {
			Matrix<T> result = clone();
			for (int i = 0; i < pow - 1; i++) {
				result = result.multiply(*this);
			}
			return result;
		}

		//debug
		void debug() {
			int rowNum = row(), colNum = col();
			int idx;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					printf("%.1f\t", (*this)[idx]);
				}
				printf("\n");
			}
			printf("\n");
		}
	};

	typedef MxN<float, 4, 4> Matrix4x4Value;
	typedef Matrix<Matrix4x4Value> Matrix4x4;
}

#endif<commit_msg>no message<commit_after>#ifndef RENDERER_TRANSFORM_HPP
#define RENDERER_TRANSFORM_HPP

#include "base.hpp"

namespace renderer {

	template<class V, const int M, const int N>
	class MxN {
	public:
		typedef V ValueType;
		static const int row = M;
		static const int col = N;
		V data[M * N];
	public:
		MxN() {
			memset(data, 0, row * col * sizeof(V));
		}
		MxN(std::initializer_list<V> values) {
			int idx = 0;
			for (auto& value : values) {
				data[idx++] = value;
			}
		}
		const V& operator [] (const int i) { return data[i]; }
	};

	template<class T>
	class Matrix final {
	public:
		T * data;
		typedef typename T::ValueType V;
		typedef MxN<V, T::col, T::row> TransT;
	public:
		Matrix() {
			data = GetPool<T>()->newElement(T());
		}

		Matrix(std::initializer_list<V> values) {
			data = GetPool<T>()->newElement(T(std::forward<std::initializer_list<V>>(values)));
		}

		Matrix(Matrix<T>& m) {
			data = GetPool<T>()->newElement(T());
			*this = m;
		}

		Matrix(Matrix<T>&& m) {
			data = m.data;
			m.data = nullptr;
		}
		virtual ~Matrix() {
			if (!data)
				return;
			auto pool = GetPool<T>();
			pool->deleteElement(data);
		}

		inline int row() {
			return T::row;
		}

		inline int col() {
			return T::col;
		}

		inline bool isSquare() {
			return row() == col();
		}

		inline bool isSameOrder(Matrix<T>& m) {
			return row() == m.row() && col() == m.col();
		}

		//access only
		inline const V& operator [] (const int i) { return static_cast<V>(*((V*)data + i)); }

		Matrix<T>& operator=(Matrix<T>& m) {
			memcpy(data, m.data, row() * col() * sizeof(V));
			return *this;
		}

		Matrix<T> operator+(Matrix<T>& m) {
			return add(m);
		}

		Matrix<T> operator-(Matrix<T>& m) {
			return minus(m);
		}

		Matrix<T> operator*(V v) {
			return multiply(v);
		}

		Matrix<T> operator*(Matrix<T>& m) {
			return multiply(m);
		}

		Matrix<T> operator/(V v) {
			return divide(v);
		}
		//API
		Matrix<T> clone() {
			Matrix<T> result = *this;
			return result;
		}

		Matrix<TransT> transpose() {
			Matrix<TransT> result;
			int rowNum = row(), colNum = col();
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					dataOfResult[j * rowNum + i] = (*this)[i * colNum + j];
				}
			}
			return result;
		}

		Matrix<T> add(Matrix<T>& m) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] + m[idx];
				}
			}
			return result;
		}

		Matrix<T> minus(Matrix<T>& m) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] - m[idx];
				}
			}
			return result;
		}

		template<int M, int N>
		Matrix<T> multiply(Matrix<MxN<V, M, N>>& m) {
			Matrix<MxN<V, T::row, N>> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < m.row(); i++) {
				for (int j = 0; j < m.col(); j++) {
					V total = 0;
					for (int k = 0; k < colNum; k++) {
						total += (*this)[i * colNum + k] * m[k * m.col() + j];
					}
					dataOfResult[i * m.col() + j] = total;
				}
			}
			return result;
		}

		Matrix<T> multiply(V v) {
			Matrix<T> result;
			int rowNum = row(), colNum = col();
			int idx;
			V* dataOfResult = result.data->data;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					dataOfResult[idx] = (*this)[idx] *v;
				}
			}
			return result;
		}

		Matrix<T> divide(V v) {
			return multiply(V(1.0)/v);
		}

		Matrix<T> power(int pow) {
			Matrix<T> result = clone();
			for (int i = 0; i < pow - 1; i++) {
				result = result.multiply(*this);
			}
			return result;
		}

		//debug
		void debug() {
			int rowNum = row(), colNum = col();
			int idx;
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					idx = i * colNum + j;
					printf("%.1f\t", (*this)[idx]);
				}
				printf("\n");
			}
			printf("\n");
		}
	};

	typedef MxN<float, 4, 4> Matrix4x4Value;
	typedef Matrix<Matrix4x4Value> Matrix4x4;
}

#endif<|endoftext|>


<commit_before>#ifndef UTIL_TASK_HPP
#define UTIL_TASK_HPP

#include <atomic>
#include <deque>

namespace Util {
	struct task {

		/** Initializes any resources deferred from constructor
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void init(std::atomic_bool& alive) =0;
		/** Polls for changes
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void poll(std::atomic_bool &alive) =0;
		/** Runs a given task
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void run(std::atomic_bool& alive) =0;
		virtual ~task(void) {}

		/** Initializes any resources deferred from constructor
 		 * @param alive Shared status; false signals shutdown
 		 * @param t The task to initialize */
		static void init(std::atomic_bool &alive, task *t) {
			t -> init(alive);
		}
		static void poll(std::atomic_bool &alive, task *t) {
			t -> poll(alive);
		}
		/** Runs a given task
 		 * @param alive Shared status; false signals shutdown
 		 * @param t The task to run
 		 */
		static void run(std::atomic_bool &alive, task *t) {
			t -> run(alive);
		}
	};

	struct supertask : public virtual task {
		std::deque<task*> tasks;
		void init(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> init(alive);
			}
		}
		void poll(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> poll(alive);
			}
		}
		void run(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> run(alive);
			}
		}
		virtual ~supertask(void) {}
	};

	struct worker : public virtual task {
		std::function<void (std::atomic_bool &)>
			m_init, m_poll, m_run;
		//void (*m_run)(std::atomic_bool &);
		void init(std::atomic_bool &alive) {
			m_init(alive);
		}
		void poll(std::atomic_bool &alive) {
			m_poll(alive);
		}
		void run(std::atomic_bool &alive) {
			m_run(alive);
		}
		worker(std::function<void (std::atomic_bool &)> m_init,
				std::function<void (std::atomic_bool &)> m_poll,
				std::function<void (std::atomic_bool &)> m_run):
			m_init(m_init), m_poll(m_poll), m_run(m_run) {}
		virtual ~worker(void) {}
	};
}

#endif
<commit_msg>Added documentation<commit_after>#ifndef UTIL_TASK_HPP
#define UTIL_TASK_HPP

#include <atomic>
#include <deque>

namespace Util {
	struct task {

		/** Initializes any resources deferred from constructor
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void init(std::atomic_bool& alive) =0;
		/** Polls for changes since init or last poll
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void poll(std::atomic_bool &alive) =0;
		/** Runs a given task
 		 * @param alive Shared status; false signals shutdown
 		 */
		virtual void run(std::atomic_bool& alive) =0;
		virtual ~task(void) {}

		/** Initializes any resources deferred from constructor
 		 * @param alive Shared status; false signals shutdown
 		 * @param t The task to initialize
 		 */
		static void init(std::atomic_bool &alive, task *t) {
			t -> init(alive);
		}
		/** Polls for changes since init or last poll
 		 * @param alive Shared status; false signals shutdown
 		 * @param t The task to poll
 		 */
		static void poll(std::atomic_bool &alive, task *t) {
			t -> poll(alive);
		}
		/** Runs a given task
 		 * @param alive Shared status; false signals shutdown
 		 * @param t The task to run
 		 */
		static void run(std::atomic_bool &alive, task *t) {
			t -> run(alive);
		}
	};

	struct supertask : public virtual task {
		std::deque<task*> tasks;
		void init(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> init(alive);
			}
		}
		void poll(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> poll(alive);
			}
		}
		void run(std::atomic_bool& alive) {
			for(auto t : tasks) {
				t -> run(alive);
			}
		}
		virtual ~supertask(void) {}
	};

	struct worker : public virtual task {
		std::function<void (std::atomic_bool &)>
			m_init, m_poll, m_run;
		//void (*m_run)(std::atomic_bool &);
		void init(std::atomic_bool &alive) {
			m_init(alive);
		}
		void poll(std::atomic_bool &alive) {
			m_poll(alive);
		}
		void run(std::atomic_bool &alive) {
			m_run(alive);
		}
		worker(std::function<void (std::atomic_bool &)> m_init,
				std::function<void (std::atomic_bool &)> m_poll,
				std::function<void (std::atomic_bool &)> m_run):
			m_init(m_init), m_poll(m_poll), m_run(m_run) {}
		virtual ~worker(void) {}
	};
}

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/error_code.hpp"

#include <string>

namespace libtorrent
{
	std::string make_magnet_uri(torrent_handle const& handle)
	{
		if (!handle.is_valid()) return "";

		char ret[1024];
		sha1_hash const& ih = handle.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char const*)&ih[0], 20)).c_str());

		std::string name = handle.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::string tracker;
		torrent_status st = handle.status();
		if (!st.current_tracker.empty())
		{
			tracker = st.current_tracker;
		}
		else
		{
			std::vector<announce_entry> const& tr = handle.trackers();
			if (!tr.empty()) tracker = tr[0].url;
		}
		if (!tracker.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tracker.c_str(), tracker.size()).c_str());

		return ret;
	}

	std::string make_magnet_uri(torrent_info const& info)
	{
		char ret[1024];
		sha1_hash const& ih = info.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char*)&ih[0], 20)).c_str());

		std::string const& name = info.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::vector<announce_entry> const& tr = info.trackers();
		if (!tr.empty())
		{
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tr[0].url.c_str(), tr[0].url.length()).c_str());
		}

		return ret;
	}

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_EXCEPTIONS
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p)
	{
		error_code ec;
		torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
		if (ec) throw libtorrent_exception(ec);
		return ret;
	}
#endif // BOOST_NO_EXCEPTIONS

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		parse_magnet_uri(uri, p, ec);
		if (ec) return torrent_handle();
		return ses.add_torrent(p, ec);
	}

#endif // TORRENT_NO_DEPRECATE

	void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec)
	{
		std::string name;
		std::string tracker;

		error_code e;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), e);

		// parse trackers out of the magnet link
		std::string::size_type pos = std::string::npos;
		std::string url = url_has_argument(uri, "tr", &pos);
		while (pos != std::string::npos)
		{
			error_code e;
			url = unescape_string(url, e);
			if (e) continue;
			p.trackers.push_back(url);
			pos = uri.find("&tr=", pos);
			if (pos == std::string::npos) break;
			pos += 4;
			url = uri.substr(pos, uri.find('&', pos) - pos);
		}

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty())
		{
			ec = errors::missing_info_hash_in_uri;
			return;
		}

		if (btih.compare(0, 9, "urn:btih:") != 0)
		{
			ec = errors::missing_info_hash_in_uri;
			return;
		}

#ifndef TORRENT_DISABLE_DHT
		std::string::size_type node_pos = std::string::npos;
		std::string node = url_has_argument(uri, "dht", &node_pos);
		while (!node.empty())
		{
			std::string::size_type divider = node.find_last_of(':');
			if (divider != std::string::npos)
			{
				int port = atoi(node.c_str()+divider+1);
				if (port != 0)
					p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port));
			}

			node_pos = uri.find("&dht=", node_pos);
			if (node_pos == std::string::npos) break;
			node_pos += 5;
			node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos);
		}
#endif

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		p.info_hash = info_hash;
		if (!name.empty()) p.name = name;
	}
}

<commit_msg>include all trackers in magnet links<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/error_code.hpp"

#include <string>

namespace libtorrent
{
	std::string make_magnet_uri(torrent_handle const& handle)
	{
		if (!handle.is_valid()) return "";

		char ret[1024];
		sha1_hash const& ih = handle.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char const*)&ih[0], 20)).c_str());

		std::string name = handle.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::vector<announce_entry> const& tr = handle.trackers();

		for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
		{
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(i->url.c_str(), i->url.length()).c_str());
		}

		return ret;
	}

	std::string make_magnet_uri(torrent_info const& info)
	{
		char ret[1024];
		sha1_hash const& ih = info.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char*)&ih[0], 20)).c_str());

		std::string const& name = info.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::vector<announce_entry> const& tr = info.trackers();
		for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
		{
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(i->url.c_str(), i->url.length()).c_str());
		}

		return ret;
	}

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_EXCEPTIONS
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p)
	{
		error_code ec;
		torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
		if (ec) throw libtorrent_exception(ec);
		return ret;
	}
#endif // BOOST_NO_EXCEPTIONS

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		parse_magnet_uri(uri, p, ec);
		if (ec) return torrent_handle();
		return ses.add_torrent(p, ec);
	}

#endif // TORRENT_NO_DEPRECATE

	void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec)
	{
		std::string name;
		std::string tracker;

		error_code e;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), e);

		// parse trackers out of the magnet link
		std::string::size_type pos = std::string::npos;
		std::string url = url_has_argument(uri, "tr", &pos);
		while (pos != std::string::npos)
		{
			error_code e;
			url = unescape_string(url, e);
			if (e) continue;
			p.trackers.push_back(url);
			pos = uri.find("&tr=", pos);
			if (pos == std::string::npos) break;
			pos += 4;
			url = uri.substr(pos, uri.find('&', pos) - pos);
		}

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty())
		{
			ec = errors::missing_info_hash_in_uri;
			return;
		}

		if (btih.compare(0, 9, "urn:btih:") != 0)
		{
			ec = errors::missing_info_hash_in_uri;
			return;
		}

#ifndef TORRENT_DISABLE_DHT
		std::string::size_type node_pos = std::string::npos;
		std::string node = url_has_argument(uri, "dht", &node_pos);
		while (!node.empty())
		{
			std::string::size_type divider = node.find_last_of(':');
			if (divider != std::string::npos)
			{
				int port = atoi(node.c_str()+divider+1);
				if (port != 0)
					p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port));
			}

			node_pos = uri.find("&dht=", node_pos);
			if (node_pos == std::string::npos) break;
			node_pos += 5;
			node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos);
		}
#endif

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		p.info_hash = info_hash;
		if (!name.empty()) p.name = name;
	}
}

<|endoftext|>


<commit_before>#include "main/spine.hpp"

Spine::Spine() {
	this->__info.name = "Spine";
	this->__info.author = "mainline";
	std::cout << "[Spine] Spine Open" << std::endl;
}

Spine::~Spine() {
	int position = 0;
	std::string closeMessage;
	for (auto& modName : this->loadedModules) {
		closeMessage = modName + " close";
		this->sendMessage(SocketType::PUB, closeMessage);
		this->threads.at(position)->join();
		delete this->threads[position];
		position += 1;
	}
	this->closeSockets();
	std::cout << "[Spine] Closed" << std::endl;
}

std::string Spine::name() {
	return this->__info.name;
}

std::vector<std::string> Spine::listModules(std::string directory) {
	std::vector<std::string> moduleFiles;

	try {
		boost::filesystem::directory_iterator startd(directory), endd;
		auto files = boost::make_iterator_range(startd, endd);

		for(boost::filesystem::path p : files){
			if (p.extension() == this->moduleFileExtension) {
				moduleFiles.push_back(p.string());
			}
		}
	} catch(boost::filesystem::filesystem_error e) {
		std::cerr << "[Spine] WARNING! Could not load modules!" << std::endl;
		std::cerr << "    - " << e.what() << std::endl;
	}

	return moduleFiles;
}

int Spine::openModuleFile(std::string moduleFile, SpineModule& spineModule) {
	spineModule.module_so = dlopen(moduleFile.c_str(), RTLD_NOW | RTLD_GLOBAL);
	if (!spineModule.module_so) {
		std::cerr << dlerror() << std::endl;
		return 1;
	}
	return 0;
}

int Spine::resolveModuleFunctions(SpineModule& spineModule) {
	spineModule.loadModule = (Module_loader*)dlsym(spineModule.module_so, "loadModule");
	if (!spineModule.loadModule) {
		 return 1;
	}

	spineModule.unloadModule = (Module_unloader*)dlsym(spineModule.module_so, "unloadModule");
	if (!spineModule.unloadModule) {
		return 2;
	}

	return 0;
}

bool Spine::loadModules(std::string directory) {
	std::vector<std::string> moduleFiles = this->listModules(directory);

	for (auto filename : moduleFiles)
	{
		std::thread* moduleThread = new std::thread([this, filename]() {
			int failure = 0;
			SpineModule spineModule;

			failure = this->openModuleFile(filename, spineModule);
			if (failure != 0) {
				exit(EXIT_FAILURE);
			}

			failure = this->resolveModuleFunctions(spineModule);
			if (failure != 0) {
				exit(EXIT_FAILURE);
			}

			spineModule.module = spineModule.loadModule();
			std::string moduleName = spineModule.module->name();

			spineModule.module->setSocketContext(this->inp_context);
			spineModule.module->openSockets();

			spineModule.module->subscribe(moduleName);
			spineModule.module->notify(SocketType::PUB, "Spine");
			spineModule.module->notify(SocketType::MGM_OUT, "Spine");

			std::string regMessage = "register " + moduleName;
			spineModule.module->sendMessage(SocketType::MGM_OUT, regMessage);

			std::string moduleLoaded = spineModule.module->recvMessage(SocketType::MGM_OUT, [&](const std::string& regReply) -> std::string {
				return regReply;
			}, 3000);

			if (moduleLoaded == "success") {
				spineModule.module->run();
			}
			spineModule.unloadModule(spineModule.module);
			if (dlclose(spineModule.module_so) != 0) {
				exit(EXIT_FAILURE);
			}
		});
		if (this->registerModule()) {
			this->threads.push_back(moduleThread);
		} else {
			moduleThread->join();
			std::cerr << "[Spine] Failed to register module: " << filename << std::endl;
		}
	}

	return true;
}

bool Spine::registerModule() {
	std::string regMessage = this->recvMessage(SocketType::MGM_IN, [&](const std::string& regReply) -> std::string {
		return regReply;
	});
	if (regMessage != "__NULL_RECV_FAILED__") {
		std::vector<std::string> tokens;
		boost::split(tokens, regMessage, boost::is_any_of(" "));
		if (tokens.at(0) == "register") {
			if (tokens.at(1) != "") {
				this->loadedModules.push_back(tokens.at(1));
				this->notify(SocketType::PUB, tokens.at(1));
				this->sendMessage(SocketType::MGM_IN, "success");
				return true;
			}
		}
	}
	return false;
}

void Spine::run() {
	for (int count = 0;count<3;count++) {
		std::cout << "Sleeping..." << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(2));
	}
	// Dummy close to make sure our subscription is correct
	this->sendMessage(SocketType::PUB, "Module close");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}

<commit_msg>Moved some logic inside callbacks as we have no fear of tailcalling.<commit_after>#include "main/spine.hpp"

Spine::Spine() {
	this->__info.name = "Spine";
	this->__info.author = "mainline";
	std::cout << "[Spine] Spine Open" << std::endl;
}

Spine::~Spine() {
	int position = 0;
	std::string closeMessage;
	// Here the Spine sends a message out on it's publish socket
	// Each message directs a 'close' message to a module registered
	//  in the Spine as 'loaded'
	// It then waits for the module to join. It relies on the module closing
	//  cleanly else it will lock up waiting.
	for (auto& modName : this->loadedModules) {
		closeMessage = modName + " close";
		this->sendMessage(SocketType::PUB, closeMessage);
		this->threads.at(position)->join();
		delete this->threads[position];
		position += 1;
	}
	// After all modules are closed we don't need our sockets
	//  so we should close them before exit, to be nice
	this->closeSockets();
	std::cout << "[Spine] Closed" << std::endl;
}

std::string Spine::name() {
	return this->__info.name;
}

std::vector<std::string> Spine::listModules(std::string directory) {
	std::vector<std::string> moduleFiles;

	// Here we list a directory and built a vector of files that match
	//  our platform specific dynamic lib extension (e.g., .so)
	try {
		boost::filesystem::directory_iterator startd(directory), endd;
		auto files = boost::make_iterator_range(startd, endd);

		for(boost::filesystem::path p : files){
			if (p.extension() == this->moduleFileExtension) {
				moduleFiles.push_back(p.string());
			}
		}
	} catch(boost::filesystem::filesystem_error e) {
		std::cerr << "[Spine] WARNING! Could not load modules!" << std::endl;
		std::cerr << "    - " << e.what() << std::endl;
	}

	return moduleFiles;
}

int Spine::openModuleFile(std::string moduleFile, SpineModule& spineModule) {
	// Here we use dlopen to load the dynamic library (that is, a compiled module)
	spineModule.module_so = dlopen(moduleFile.c_str(), RTLD_NOW | RTLD_GLOBAL);
	if (!spineModule.module_so) {
		std::cerr << dlerror() << std::endl;
		return 1;
	}
	return 0;
}

int Spine::resolveModuleFunctions(SpineModule& spineModule) {
	spineModule.loadModule = (Module_loader*)dlsym(spineModule.module_so, "loadModule");
	if (!spineModule.loadModule) {
		 return 1;
	}

	spineModule.unloadModule = (Module_unloader*)dlsym(spineModule.module_so, "unloadModule");
	if (!spineModule.unloadModule) {
		return 2;
	}

	return 0;
}

bool Spine::loadModules(std::string directory) {
	std::vector<std::string> moduleFiles = this->listModules(directory);

	for (auto filename : moduleFiles)
	{
		std::thread* moduleThread = new std::thread([this, filename]() {
			int failure = 0;
			SpineModule spineModule;

			failure = this->openModuleFile(filename, spineModule);
			if (failure != 0) {
				exit(EXIT_FAILURE);
			}

			failure = this->resolveModuleFunctions(spineModule);
			if (failure != 0) {
				exit(EXIT_FAILURE);
			}

			spineModule.module = spineModule.loadModule();
			std::string moduleName = spineModule.module->name();

			spineModule.module->setSocketContext(this->inp_context);
			spineModule.module->openSockets();

			spineModule.module->subscribe(moduleName);
			spineModule.module->notify(SocketType::PUB, "Spine");
			spineModule.module->notify(SocketType::MGM_OUT, "Spine");

			std::string regMessage = "register " + moduleName;
			spineModule.module->sendMessage(SocketType::MGM_OUT, regMessage);

			std::string moduleRun = spineModule.module->recvMessage(SocketType::MGM_OUT, [&](const std::string& regReply) -> std::string {
				if (regReply == "success") {
					spineModule.module->run();
				}
				return regReply;
			}, 3000);

			spineModule.unloadModule(spineModule.module);
			if (dlclose(spineModule.module_so) != 0) {
				exit(EXIT_FAILURE);
			}
		});
		if (this->registerModule()) {
			this->threads.push_back(moduleThread);
		} else {
			moduleThread->join();
			std::cerr << "[Spine] Failed to register module: " << filename << std::endl;
		}
	}

	return true;
}

bool Spine::registerModule() {
	std::string regReturn = this->recvMessage(SocketType::MGM_IN, [&](const std::string& regReply) -> std::string {
		if (regReply != "__NULL_RECV_FAILED__") {
			std::vector<std::string> tokens;
			boost::split(tokens, regReply, boost::is_any_of(" "));
			if (tokens.at(0) == "register") {
				if (tokens.at(1) != "") {
					this->loadedModules.push_back(tokens.at(1));
					this->notify(SocketType::PUB, tokens.at(1));
					this->sendMessage(SocketType::MGM_IN, "success");
					return "true";
				}
			}
		}
		return "false";
	});
	return (regReturn == "true") ? true : false;
}

void Spine::run() {
	for (int count = 0;count<3;count++) {
		std::cout << "Sleeping..." << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(2));
	}
	// Dummy close to make sure our subscription is correct
	this->sendMessage(SocketType::PUB, "Module close");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}

<|endoftext|>