<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Sequence_inl_
#define _Stroika_Foundation_Containers_Sequence_inl_

#include    "../Debug/Assertions.h"

#include    "Concrete/Sequence_Array.h"  // needed for default constructor
#include    "Private/IterableUtils.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {

            /*
             ********************************************************************************
             ********************************* Sequence<T> **********************************
             ********************************************************************************
             */
            template    <typename T>
            Sequence<T>::Sequence ()
                : Iterable<T> (Concrete::Sequence_Array<T> ())
            {
            }
            template    <typename T>
            inline  Sequence<T>::Sequence (const Sequence<T>& s)
                : Iterable<T> (s)
            {
            }
            template    <typename T>
            inline  Sequence<T>::Sequence (const _SharedPtrIRep& rep)
                : Iterable<T> (typename Iterable<T>::_SharedByValueRepType (rep))
            {
                RequireNotNull (rep);
            }
            template    <typename T>
            Sequence<T>::Sequence (const T* start, const T* end)
                : Iterable<T> (Concrete::Sequence_Array<T> (start, end))
            {
            }
            template    <typename T>
            inline  bool    Sequence<T>::Contains (T item) const
            {
                return Private::Contains_ (*this, item);
            }
            template    <typename T>
            inline  int    Sequence<T>::Compare (const Iterable<T>& rhs) const
            {
                return Private::Compare_ (*this, rhs);
            }
            template    <typename T>
            inline  bool    Sequence<T>::Equals (const Iterable<T>& rhs) const
            {
                return Private::Equals_ (*this, rhs);
            }
            template    <typename T>
            inline  void    Sequence<T>::RemoveAll ()
            {
                _GetRep ().Remove (0, this->GetLength ());
            }
            template    <typename T>
            inline  T    Sequence<T>::GetAt (size_t i) const
            {
                return _GetRep ().GetAt (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::SetAt (size_t i, T item)
            {
                _GetRep ().SetAt (i, item);
            }
            template    <typename T>
            inline  T    Sequence<T>::operator[] (size_t i) const
            {
                return _GetRep ().GetAt (i);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (T item) const
            {
#if     qCompilerAndStdLib_Supports_constexpr
                static_assert (Private::kBadIndex == kBadSequenceIndex, "Private::kBadIndex == kBadSequenceIndex");
#else
                Assert (Private::kBadIndex == kBadSequenceIndex);
#endif
                return Private::IndexOf_ (*this, item);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (const Sequence<T>& s) const
            {
#if     qCompilerAndStdLib_Supports_constexpr
                static_assert (Private::kBadIndex == kBadSequenceIndex, "Private::kBadIndex == kBadSequenceIndex");
#else
                Assert (Private::kBadIndex == kBadSequenceIndex);
#endif
                return Private::IndexOf_ (*this, s);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (const Iterator<T>& i) const
            {
                return _GetRep ().IndexOf (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::Insert (size_t index, T item)
            {
                return _GetRep ().Insert (index, &item, &item + 1);
            }
            template    <typename T>
            void    Sequence<T>::Insert (size_t index, const Iterable<T>& items)
            {
                /*
                 *  Inefficient implementation, but cannot use array insert because sequnece<T> might not be Sequence_Array<T>.
                 *  @todo IMPROVE
                 */
                for (T i : items) {
                    Insert (index++, i);
                }
            }
            template    <typename T>
            inline  void    Sequence<T>::Prepend (T item)
            {
                Insert (0, item);
            }
            template    <typename T>
            inline  void    Sequence<T>::Prepend (const Iterable<T>& items)
            {
                Insert (0, items);
            }
            template    <typename T>
            inline  void    Sequence<T>::Append (T item)
            {
                Insert (this->GetLength (), item);
            }
            template    <typename T>
            inline  void    Sequence<T>::Append (const Iterable<T>& items)
            {
                Insert (this->GetLength (), items);
            }
            template    <typename T>
            inline  void    Sequence<T>::Update (const Iterator<T>& i, T newValue)
            {
                _GetRep ().Update (i, newValue);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (size_t i)
            {
                Require (i < this->GetLength ());
                _GetRep ().Remove (i, i + 1);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (size_t start, size_t end)
            {
                Require (start <= end and end <= this->GetLength ());
                _GetRep ().Remove (start, end);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (const Iterator<T>& i)
            {
                _GetRep ().Remove (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::push_back (T item)
            {
                Append (item);
            }
            template    <typename   T>
            template    <typename   CONTAINER_OF_T>
            inline  CONTAINER_OF_T  Sequence<T>:: As () const
            {
                return CONTAINER_OF_T (begin (), end ());
            }
            template    <typename   T>
            template    <typename   CONTAINER_OF_T>
            inline  void    Sequence<T>::As (CONTAINER_OF_T* into) const
            {
                return CONTAINER_OF_T (begin (), end ());
            }
            template    <typename T>
            inline  T    Sequence<T>::back () const
            {
                Require (not this->IsEmpty ());
                return GetAt (this->GetLength () - 1);
            }
            template    <typename T>
            inline  T    Sequence<T>::front () const
            {
                Require (not this->IsEmpty ());
                return GetAt (0);
            }
            template    <typename T>
            inline  void    Sequence<T>::clear ()
            {
                RemoveAll ();
            }
#if 0
            template    <typename T>
            inline  Sequence<T>& Sequence<T>::operator+= (T item)
            {
                Add (item);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator+= (const Bag<T>& items)
            {
                Add (items);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator-= (T item)
            {
                Remove (item);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator-= (const Bag<T>& items)
            {
                Remove (items);
                return (*this);
            }
            template    <typename T>
            inline  void    Bag<T>::Add (T item)
            {
                _GetRep ().Add (item);
                // this-> required for gcc 4.6.3. I don't THINK this is a bug because I think its cuz its an inherite dmethod.
                // I must re-read C++ template docs for clarificaiton...
                //      -- LGP 2012-07-28
                Ensure (not this->IsEmpty ());
            }
            template    <typename T>
            void  Bag<T>::Add (const Bag<T>& items)
            {
                if (&_GetRep () == &items._GetRep ()) {
                    // Copy - so we don't update this while we are copying from it...
                    Bag<T>  copiedItems =   items;
                    for (T i : copiedItems) {
                        _GetRep ().Add (i);
                    }
                }
                else {
                    for (T i : items) {
                        _GetRep ().Add (i);
                    }
                }
            }
            template    <typename T>
            bool  Bag<T>::operator== (const Bag<T>& rhs) const
            {
                if (&this->_GetRep () == &rhs._GetRep ()) {
                    return (true);
                }
                if (this->GetLength () != rhs.GetLength ()) {
                    return (false);
                }

                // n^2 algorithm!!!
                for (T i : *this) {
                    if (this->TallyOf (i) != rhs.TallyOf (i)) {
                        return (false);
                    }
                }
                return (true);
            }
            template    <typename T>
            inline  bool    Bag<T>::operator!= (const Bag<T>& rhs) const
            {
                return (not (*this == rhs));
            }
#endif

#if 0
            /*
             ********************************************************************************
             ************************************ operators *********************************
             ********************************************************************************
             */
            template    <typename T>
            Bag<T>    operator+ (const Bag<T>& lhs, const Bag<T>& rhs)
            {
                Bag<T>  temp    = lhs;
                temp += rhs;
                return (temp);
            }
            template    <typename T>
            Bag<T>    operator- (const Bag<T>& lhs, const Bag<T>& rhs)
            {
                Bag<T>  temp    = lhs;
                temp -= rhs;
                return (temp);
            }
#endif

            /*
             ********************************************************************************
             *************************** Sequence<T>::_IRep *********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  Sequence<T>::_IRep::_IRep ()
            {
            }
            template    <typename T>
            inline  Sequence<T>::_IRep::~_IRep ()
            {
            }
            template    <typename T>
            inline  const typename  Sequence<T>::_IRep&    Sequence<T>::_GetRep () const
            {
                // Unsure - MAY need to use dynamic_cast here - but I think static cast performs better, so try...
                EnsureMember (&Iterable<T>::_GetRep (), Sequence<T>::_IRep);
                return *static_cast<const Sequence<T>::_IRep*> (&Iterable<T>::_GetRep ());
            }
            template    <typename T>
            inline  typename    Sequence<T>::_IRep&  Sequence<T>::_GetRep ()
            {
                // Unsure - MAY need to use dynamic_cast here - but I think static cast performs better, so try...
                EnsureMember (&Iterable<T>::_GetRep (), Sequence<T>::_IRep);
                return *static_cast<Sequence<T>::_IRep*> (&Iterable<T>::_GetRep ());
            }

        }
    }
}

#endif /* _Stroika_Foundation_Containers_Sequence_inl_ */
<commit_msg>fixed type-deduction template bug (vc++ more forgiving)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Sequence_inl_
#define _Stroika_Foundation_Containers_Sequence_inl_

#include    "../Debug/Assertions.h"

#include    "Concrete/Sequence_Array.h"  // needed for default constructor
#include    "Private/IterableUtils.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {

            /*
             ********************************************************************************
             ********************************* Sequence<T> **********************************
             ********************************************************************************
             */
            template    <typename T>
            Sequence<T>::Sequence ()
                : Iterable<T> (Concrete::Sequence_Array<T> ())
            {
            }
            template    <typename T>
            inline  Sequence<T>::Sequence (const Sequence<T>& s)
                : Iterable<T> (s)
            {
            }
            template    <typename T>
            inline  Sequence<T>::Sequence (const _SharedPtrIRep& rep)
                : Iterable<T> (typename Iterable<T>::_SharedByValueRepType (rep))
            {
                RequireNotNull (rep);
            }
            template    <typename T>
            Sequence<T>::Sequence (const T* start, const T* end)
                : Iterable<T> (Concrete::Sequence_Array<T> (start, end))
            {
            }
            template    <typename T>
            inline  bool    Sequence<T>::Contains (T item) const
            {
                return Private::Contains_ (*this, item);
            }
            template    <typename T>
            inline  int    Sequence<T>::Compare (const Iterable<T>& rhs) const
            {
                return Private::Compare_ (*this, rhs);
            }
            template    <typename T>
            inline  bool    Sequence<T>::Equals (const Iterable<T>& rhs) const
            {
                return Private::Equals_ (*this, rhs);
            }
            template    <typename T>
            inline  void    Sequence<T>::RemoveAll ()
            {
                _GetRep ().Remove (0, this->GetLength ());
            }
            template    <typename T>
            inline  T    Sequence<T>::GetAt (size_t i) const
            {
                return _GetRep ().GetAt (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::SetAt (size_t i, T item)
            {
                _GetRep ().SetAt (i, item);
            }
            template    <typename T>
            inline  T    Sequence<T>::operator[] (size_t i) const
            {
                return _GetRep ().GetAt (i);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (T item) const
            {
#if     qCompilerAndStdLib_Supports_constexpr
                static_assert (Private::kBadIndex == kBadSequenceIndex, "Private::kBadIndex == kBadSequenceIndex");
#else
                Assert (Private::kBadIndex == kBadSequenceIndex);
#endif
                return Private::IndexOf_ (*this, item);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (const Sequence<T>& s) const
            {
#if     qCompilerAndStdLib_Supports_constexpr
                static_assert (Private::kBadIndex == kBadSequenceIndex, "Private::kBadIndex == kBadSequenceIndex");
#else
                Assert (Private::kBadIndex == kBadSequenceIndex);
#endif
                return Private::IndexOf_ (*this, s);
            }
            template    <typename T>
            inline  size_t    Sequence<T>::IndexOf (const Iterator<T>& i) const
            {
                return _GetRep ().IndexOf (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::Insert (size_t index, T item)
            {
                return _GetRep ().Insert (index, &item, &item + 1);
            }
            template    <typename T>
            void    Sequence<T>::Insert (size_t index, const Iterable<T>& items)
            {
                /*
                 *  Inefficient implementation, but cannot use array insert because sequnece<T> might not be Sequence_Array<T>.
                 *  @todo IMPROVE
                 */
                for (T i : items) {
                    Insert (index++, i);
                }
            }
            template    <typename T>
            inline  void    Sequence<T>::Prepend (T item)
            {
                Insert (0, item);
            }
            template    <typename T>
            inline  void    Sequence<T>::Prepend (const Iterable<T>& items)
            {
                Insert (0, items);
            }
            template    <typename T>
            inline  void    Sequence<T>::Append (T item)
            {
                Insert (this->GetLength (), item);
            }
            template    <typename T>
            inline  void    Sequence<T>::Append (const Iterable<T>& items)
            {
                Insert (this->GetLength (), items);
            }
            template    <typename T>
            inline  void    Sequence<T>::Update (const Iterator<T>& i, T newValue)
            {
                _GetRep ().Update (i, newValue);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (size_t i)
            {
                Require (i < this->GetLength ());
                _GetRep ().Remove (i, i + 1);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (size_t start, size_t end)
            {
                Require (start <= end and end <= this->GetLength ());
                _GetRep ().Remove (start, end);
            }
            template    <typename T>
            inline  void    Sequence<T>::Remove (const Iterator<T>& i)
            {
                _GetRep ().Remove (i);
            }
            template    <typename T>
            inline  void    Sequence<T>::push_back (T item)
            {
                Append (item);
            }
            template    <typename   T>
            template    <typename   CONTAINER_OF_T>
            inline  CONTAINER_OF_T  Sequence<T>:: As () const
            {
                return CONTAINER_OF_T (this->begin (), this->end ());
            }
            template    <typename   T>
            template    <typename   CONTAINER_OF_T>
            inline  void    Sequence<T>::As (CONTAINER_OF_T* into) const
            {
                return CONTAINER_OF_T (this->begin (), this->end ());
            }
            template    <typename T>
            inline  T    Sequence<T>::back () const
            {
                Require (not this->IsEmpty ());
                return GetAt (this->GetLength () - 1);
            }
            template    <typename T>
            inline  T    Sequence<T>::front () const
            {
                Require (not this->IsEmpty ());
                return GetAt (0);
            }
            template    <typename T>
            inline  void    Sequence<T>::clear ()
            {
                RemoveAll ();
            }
#if 0
            template    <typename T>
            inline  Sequence<T>& Sequence<T>::operator+= (T item)
            {
                Add (item);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator+= (const Bag<T>& items)
            {
                Add (items);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator-= (T item)
            {
                Remove (item);
                return (*this);
            }
            template    <typename T>
            inline  Bag<T>& Bag<T>::operator-= (const Bag<T>& items)
            {
                Remove (items);
                return (*this);
            }
            template    <typename T>
            inline  void    Bag<T>::Add (T item)
            {
                _GetRep ().Add (item);
                // this-> required for gcc 4.6.3. I don't THINK this is a bug because I think its cuz its an inherite dmethod.
                // I must re-read C++ template docs for clarificaiton...
                //      -- LGP 2012-07-28
                Ensure (not this->IsEmpty ());
            }
            template    <typename T>
            void  Bag<T>::Add (const Bag<T>& items)
            {
                if (&_GetRep () == &items._GetRep ()) {
                    // Copy - so we don't update this while we are copying from it...
                    Bag<T>  copiedItems =   items;
                    for (T i : copiedItems) {
                        _GetRep ().Add (i);
                    }
                }
                else {
                    for (T i : items) {
                        _GetRep ().Add (i);
                    }
                }
            }
            template    <typename T>
            bool  Bag<T>::operator== (const Bag<T>& rhs) const
            {
                if (&this->_GetRep () == &rhs._GetRep ()) {
                    return (true);
                }
                if (this->GetLength () != rhs.GetLength ()) {
                    return (false);
                }

                // n^2 algorithm!!!
                for (T i : *this) {
                    if (this->TallyOf (i) != rhs.TallyOf (i)) {
                        return (false);
                    }
                }
                return (true);
            }
            template    <typename T>
            inline  bool    Bag<T>::operator!= (const Bag<T>& rhs) const
            {
                return (not (*this == rhs));
            }
#endif

#if 0
            /*
             ********************************************************************************
             ************************************ operators *********************************
             ********************************************************************************
             */
            template    <typename T>
            Bag<T>    operator+ (const Bag<T>& lhs, const Bag<T>& rhs)
            {
                Bag<T>  temp    = lhs;
                temp += rhs;
                return (temp);
            }
            template    <typename T>
            Bag<T>    operator- (const Bag<T>& lhs, const Bag<T>& rhs)
            {
                Bag<T>  temp    = lhs;
                temp -= rhs;
                return (temp);
            }
#endif

            /*
             ********************************************************************************
             *************************** Sequence<T>::_IRep *********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  Sequence<T>::_IRep::_IRep ()
            {
            }
            template    <typename T>
            inline  Sequence<T>::_IRep::~_IRep ()
            {
            }
            template    <typename T>
            inline  const typename  Sequence<T>::_IRep&    Sequence<T>::_GetRep () const
            {
                // Unsure - MAY need to use dynamic_cast here - but I think static cast performs better, so try...
                EnsureMember (&Iterable<T>::_GetRep (), Sequence<T>::_IRep);
                return *static_cast<const Sequence<T>::_IRep*> (&Iterable<T>::_GetRep ());
            }
            template    <typename T>
            inline  typename    Sequence<T>::_IRep&  Sequence<T>::_GetRep ()
            {
                // Unsure - MAY need to use dynamic_cast here - but I think static cast performs better, so try...
                EnsureMember (&Iterable<T>::_GetRep (), Sequence<T>::_IRep);
                return *static_cast<Sequence<T>::_IRep*> (&Iterable<T>::_GetRep ());
            }

        }
    }
}

#endif /* _Stroika_Foundation_Containers_Sequence_inl_ */
<|endoftext|>


<commit_before>/*
 * Copyright(c) Records For Living, Inc. 2004-2011.  All rights reserved
 */
/*
 * Note - used PUBLIC DOMAIN http://sourceforge.net/projects/libb64/files/libb64/libb64/libb64-1.2.src.zip/download
 * code as a starting point.
 */
#include	"../StroikaPreComp.h"

#include	"../Containers/Common.h"
#include	"../Debug/Assertions.h"
#include	"../Execution/Exceptions.h"
#include	"../Memory/SmallStackBuffer.h"
#include	"../Streams/BadFormatException.h"

#include	"Base64.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Containers;
using	namespace	Stroika::Foundation::Cryptography;
using	namespace	Stroika::Foundation::Memory;

/*
 *	IMPLEMENTATION NOTES:
 *
 *		The public domain (private) code in this file - is designed to operate in a STREAM mode. I've preserved that
 *	internally, evne though my current API doesnt work that way, because we will soon support a STREAM based API here,
 *	and that will fit perfectly.
 *
 *		See also http://libb64.sourceforge.net/ - which explains the design of the routines, and the queer nested loop / switch
 * construct.
 *
 *		-- LGP 2011-06-21
 */

/*
 ********************************************************************************
 *************************** Encoding::DecodeBase64 *****************************
 ********************************************************************************
 */
namespace	{
	enum base64_decodestep_ {
		step_a, step_b, step_c, step_d
	};
	struct base64_decodestate_ {
		base64_decodestep_	step;
		Byte				plainchar;

		base64_decodestate_ ()
			: step (step_a)
			, plainchar ('\0')
			{
			}
	};
	int base64_decode_value_ (char value_in)
		{
			static const char kDecoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
			value_in -= 43;
			if (value_in < 0 || value_in >= NEltsOf (kDecoding)) {
				return -1;
			}
			return kDecoding[(int)value_in];
		}
	size_t base64_decode_block_ (const char* code_in, size_t length_in, Byte* plaintext_out, base64_decodestate_* state)
		{
			const char* codechar	=	code_in;
			Byte*		plainchar	=	plaintext_out;
			char		fragment	=	'\0';

			*plainchar = state->plainchar;

			switch (state->step) {
				while (1)
				{
			case step_a:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_a;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar    = (fragment & 0x03f) << 2;
			case step_b:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_b;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++ |= (fragment & 0x030) >> 4;
					*plainchar    = (fragment & 0x00f) << 4;
			case step_c:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_c;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++ |= (fragment & 0x03c) >> 2;
					*plainchar    = (fragment & 0x003) << 6;
			case step_d:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_d;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++   |= (fragment & 0x03f);
				}
			}
			return plainchar - plaintext_out;
		}
}

vector<Byte>	Cryptography::DecodeBase64 (const string& s)
{
	size_t dataSize1 = s.length ();
	SmallStackBuffer<Byte>	buf1 (dataSize1);	// MUCH more than big enuf
	base64_decodestate_ state;
	size_t r = base64_decode_block_ (Containers::Start (s), s.length (), buf1.begin (), &state);
	Assert (r <= dataSize1);
	return vector<Byte> (buf1.begin (), buf1.begin () + r);
}

/*
 ********************************************************************************
 *********************** Cryptography::EncodeBase64 *****************************
 ********************************************************************************
 */
namespace	{
	enum base64_encodestep {
		step_A, step_B, step_C
	};
	struct base64_encodestate {
		base64_encodestep	step;
		char				result;
		int					stepcount;
		LineBreak			fLineBreak;

		base64_encodestate  (LineBreak lb)
			: step (step_A)
			, result (0)
			, stepcount (0)
			, fLineBreak (lb)
			{
			}
	};

	char base64_encode_value_ (char value_in)
		{
			const char	BASE64_CHARS_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
			Assert  (NEltsOf (BASE64_CHARS_) == (2*26 + 10 + 2 + 1));
			if (value_in > 63) {
				return '=';
			}
			return BASE64_CHARS_[(int)value_in];
		}

	size_t base64_encode_block_ (const Byte* plaintext_in, size_t length_in, char* code_out, base64_encodestate* state)
		{
			const int CHARS_PER_LINE = 76;

			const Byte*			plainchar		=	plaintext_in;
			const Byte* const	plaintextend	=	plaintext_in + length_in;
			char*				codechar		=	code_out;
			char				result			=	state->result;

			char fragment	=	'\0';
			switch (state->step) {
				while (1) {
			case step_A:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_A;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result = (fragment & 0x0fc) >> 2;
					*codechar++ = base64_encode_value_ (result);
					result = (fragment & 0x003) << 4;
			case step_B:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_B;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result |= (fragment & 0x0f0) >> 4;
					*codechar++ = base64_encode_value_ (result);
					result = (fragment & 0x00f) << 2;
			case step_C:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_C;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result |= (fragment & 0x0c0) >> 6;
					*codechar++ = base64_encode_value_ (result);
					result  = (fragment & 0x03f) >> 0;
					*codechar++ = base64_encode_value_ (result);

					++(state->stepcount);
					if (state->stepcount == CHARS_PER_LINE/4) {
						switch (state->fLineBreak) {
							case	eLF_LB:		*codechar++ = '\n';		break;
							case	eCRLF_LB:	*codechar++ = '\r';		*codechar++ = '\n'; break;
						}
						state->stepcount = 0;
					}
				}
			}
			return codechar - code_out;
		}
	inline	size_t	base64_encode_blockend_ (char* code_out, base64_encodestate* state)
		{
			char* codechar = code_out;
			switch (state->step) {
				case step_B:
					*codechar++ = base64_encode_value_ (state->result);
					*codechar++ = '=';
					*codechar++ = '=';
					break;
				case step_C:
					*codechar++ = base64_encode_value_ (state->result);
					*codechar++ = '=';
					break;
				case step_A:
					break;
			}
			return static_cast<size_t> (codechar - code_out);
		}
}

string	Cryptography::EncodeBase64 (const Byte* start, const Byte* end, LineBreak lb)
{
	Require (start == end or start != NULL);
	Require (start == end or end != NULL);

	base64_encodestate state (lb);
	size_t srcLen = end - start;
	size_t bufSize = 4 * srcLen;
	Assert (bufSize > srcLen);	// no overflow!
	SmallStackBuffer<char>	data (bufSize);
	size_t mostBytesCopied = 	 base64_encode_block_ (start, srcLen, data.begin (), &state);
	size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
	size_t totalBytes = mostBytesCopied + extraBytes;
	Assert (totalBytes <= bufSize);
	return string (data.begin (), data.begin () + totalBytes);
}

string	Cryptography::EncodeBase64 (const vector<Byte>& b, LineBreak lb)
{
	return EncodeBase64 (Containers::Start (b), Containers::End (b), lb);
}
<commit_msg>more assertions in Cryptography Base64 code<commit_after>/*
 * Copyright(c) Records For Living, Inc. 2004-2011.  All rights reserved
 */
/*
 * Note - used PUBLIC DOMAIN http://sourceforge.net/projects/libb64/files/libb64/libb64/libb64-1.2.src.zip/download
 * code as a starting point.
 */
#include	"../StroikaPreComp.h"

#include	"../Containers/Common.h"
#include	"../Debug/Assertions.h"
#include	"../Execution/Exceptions.h"
#include	"../Memory/SmallStackBuffer.h"
#include	"../Streams/BadFormatException.h"

#include	"Base64.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Containers;
using	namespace	Stroika::Foundation::Cryptography;
using	namespace	Stroika::Foundation::Memory;

/*
 *	IMPLEMENTATION NOTES:
 *
 *		The public domain (private) code in this file - is designed to operate in a STREAM mode. I've preserved that
 *	internally, evne though my current API doesnt work that way, because we will soon support a STREAM based API here,
 *	and that will fit perfectly.
 *
 *		See also http://libb64.sourceforge.net/ - which explains the design of the routines, and the queer nested loop / switch
 * construct.
 *
 *		-- LGP 2011-06-21
 */

/*
 ********************************************************************************
 *************************** Encoding::DecodeBase64 *****************************
 ********************************************************************************
 */
namespace	{
	enum base64_decodestep_ {
		step_a, step_b, step_c, step_d
	};
	struct base64_decodestate_ {
		base64_decodestep_	step;
		Byte				plainchar;

		base64_decodestate_ ()
			: step (step_a)
			, plainchar ('\0')
			{
			}
	};
	int base64_decode_value_ (char value_in)
		{
			static const char kDecoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
			value_in -= 43;
			if (value_in < 0 || value_in >= NEltsOf (kDecoding)) {
				return -1;
			}
			Assert (0 <= value_in and value_in < NEltsOf (kDecoding));
			return kDecoding[(int)value_in];
		}
	size_t base64_decode_block_ (const char* code_in, size_t length_in, Byte* plaintext_out, base64_decodestate_* state)
		{
			RequireNotNil (code_in);
			RequireNotNil (plaintext_out);

			const char* codechar	=	code_in;
			Byte*		plainchar	=	plaintext_out;
			char		fragment	=	'\0';

			*plainchar = state->plainchar;

			switch (state->step) {
				while (1)
				{
			case step_a:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_a;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar    = (fragment & 0x03f) << 2;
			case step_b:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_b;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++ |= (fragment & 0x030) >> 4;
					*plainchar    = (fragment & 0x00f) << 4;
			case step_c:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_c;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++ |= (fragment & 0x03c) >> 2;
					*plainchar    = (fragment & 0x003) << 6;
			case step_d:
					do {
						if (codechar == code_in + length_in) {
							state->step = step_d;
							state->plainchar = *plainchar;
							return plainchar - plaintext_out;
						}
						fragment = (char)base64_decode_value_ (*codechar++);
					} while (fragment < 0);
					*plainchar++   |= (fragment & 0x03f);
				}
			}
			return plainchar - plaintext_out;
		}
}

vector<Byte>	Cryptography::DecodeBase64 (const string& s)
{
	if (s.empty ()) {
		return vector<Byte> ();
	}
	size_t dataSize1 = s.length ();
	SmallStackBuffer<Byte>	buf1 (dataSize1);	// MUCH more than big enuf
	base64_decodestate_ state;
	size_t r = base64_decode_block_ (Containers::Start (s), s.length (), buf1.begin (), &state);
	Assert (r <= dataSize1);
	return vector<Byte> (buf1.begin (), buf1.begin () + r);
}

/*
 ********************************************************************************
 *********************** Cryptography::EncodeBase64 *****************************
 ********************************************************************************
 */
namespace	{
	enum base64_encodestep {
		step_A, step_B, step_C
	};
	struct base64_encodestate {
		base64_encodestep	step;
		char				result;
		int					stepcount;
		LineBreak			fLineBreak;

		base64_encodestate  (LineBreak lb)
			: step (step_A)
			, result (0)
			, stepcount (0)
			, fLineBreak (lb)
			{
			}
	};

	char base64_encode_value_ (char value_in)
		{
			const char	BASE64_CHARS_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
			Assert  (NEltsOf (BASE64_CHARS_) == (2*26 + 10 + 2 + 1));
			if (value_in > 63) {
				return '=';
			}
			return BASE64_CHARS_[(int)value_in];
		}

	size_t base64_encode_block_ (const Byte* plaintext_in, size_t length_in, char* code_out, base64_encodestate* state)
		{
			const int CHARS_PER_LINE = 76;

			const Byte*			plainchar		=	plaintext_in;
			const Byte* const	plaintextend	=	plaintext_in + length_in;
			char*				codechar		=	code_out;
			char				result			=	state->result;

			char fragment	=	'\0';
			switch (state->step) {
				while (1) {
			case step_A:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_A;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result = (fragment & 0x0fc) >> 2;
					*codechar++ = base64_encode_value_ (result);
					result = (fragment & 0x003) << 4;
			case step_B:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_B;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result |= (fragment & 0x0f0) >> 4;
					*codechar++ = base64_encode_value_ (result);
					result = (fragment & 0x00f) << 2;
			case step_C:
					if (plainchar == plaintextend) {
						state->result = result;
						state->step = step_C;
						return codechar - code_out;
					}
					fragment = *plainchar++;
					result |= (fragment & 0x0c0) >> 6;
					*codechar++ = base64_encode_value_ (result);
					result  = (fragment & 0x03f) >> 0;
					*codechar++ = base64_encode_value_ (result);

					++(state->stepcount);
					if (state->stepcount == CHARS_PER_LINE/4) {
						switch (state->fLineBreak) {
							case	eLF_LB:		*codechar++ = '\n';		break;
							case	eCRLF_LB:	*codechar++ = '\r';		*codechar++ = '\n'; break;
						}
						state->stepcount = 0;
					}
				}
			}
			return codechar - code_out;
		}
	inline	size_t	base64_encode_blockend_ (char* code_out, base64_encodestate* state)
		{
			char* codechar = code_out;
			switch (state->step) {
				case step_B:
					*codechar++ = base64_encode_value_ (state->result);
					*codechar++ = '=';
					*codechar++ = '=';
					break;
				case step_C:
					*codechar++ = base64_encode_value_ (state->result);
					*codechar++ = '=';
					break;
				case step_A:
					break;
			}
			return static_cast<size_t> (codechar - code_out);
		}
}

string	Cryptography::EncodeBase64 (const Byte* start, const Byte* end, LineBreak lb)
{
	Require (start == end or start != NULL);
	Require (start == end or end != NULL);

	base64_encodestate state (lb);
	size_t srcLen = end - start;
	size_t bufSize = 4 * srcLen;
	Assert (bufSize > srcLen);	// no overflow!
	SmallStackBuffer<char>	data (bufSize);
	size_t mostBytesCopied = 	 base64_encode_block_ (start, srcLen, data.begin (), &state);
	size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
	size_t totalBytes = mostBytesCopied + extraBytes;
	Assert (totalBytes <= bufSize);
	return string (data.begin (), data.begin () + totalBytes);
}

string	Cryptography::EncodeBase64 (const vector<Byte>& b, LineBreak lb)
{
	return EncodeBase64 (Containers::Start (b), Containers::End (b), lb);
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program 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 of the License,
or (at your option) any later version.

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

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "ChatRoom.h"

#include "../../zone/objects/player/PlayerCreature.h"
#include "../../zone/objects/creature/CreatureObject.h"

#include "../../zone/ZoneServer.h"

#include "../../zone/packets/chat/ChatRoomList.h"
#include "../../zone/packets/chat/ChatOnDestroyRoom.h"
#include "../../zone/packets/chat/ChatOnLeaveRoom.h"
#include "../../zone/packets/chat/ChatOnEnteredRoom.h"
#include "server/zone/managers/objectcontroller/ObjectController.h"

void ChatRoomImplementation::sendTo(PlayerCreature* player) {
	ChatRoomList* crl = new ChatRoomList();
	crl->addChannel((ChatRoom*) _this);

	crl->insertChannelListCount();
	player->sendMessage(crl);
}

void ChatRoomImplementation::sendDestroyTo(PlayerCreature* player) {
	ChatOnDestroyRoom* msg = new ChatOnDestroyRoom("SWG", server->getServerName(), roomID);
	player->sendMessage(msg);
}

void ChatRoomImplementation::addPlayer(PlayerCreature* player, bool doLock) {
	wlock();

	if (playerList.put(player->getFirstName(), player) == -1) {
		unlock();
		return;
	}

	ChatOnEnteredRoom* coer = new ChatOnEnteredRoom(server->getServerName(), player->getFirstName(), roomID);
	player->sendMessage(coer);

	unlock();

	player->wlock(doLock);

	player->addChatRoom((ChatRoom*) _this);

	player->unlock(doLock);

	/*ChatOnReceiveRoomInvitation* corri = new ChatOnReceiveRoomInvitation(name);
	player->sendMessage(corri);*/

}

void ChatRoomImplementation::removePlayer(PlayerCreature* player, bool doLock) {
	player->wlock(doLock);

	player->removeChatRoom((ChatRoom*) _this);

	player->unlock(doLock);

	wlock();

	playerList.drop(player->getFirstName());

	ChatOnLeaveRoom* msg = new ChatOnLeaveRoom((ChatRoom*) _this, player);
	player->sendMessage(msg);

	unlock();
}

void ChatRoomImplementation::removePlayer(const String& player) {
	// Pre: player unlocked
	wlock();

	PlayerCreature* play = playerList.get(player);
	playerList.drop(player);

	unlock();

	if (play == NULL)
		return;

	try {
		play->wlock();

		play->removeChatRoom((ChatRoom*) _this);

		ChatOnLeaveRoom* msg = new ChatOnLeaveRoom((ChatRoom*) _this, play);
		play->sendMessage(msg);

		play->unlock();
	} catch (...) {
		System::out << "unreported Exception in ChatRoom::removePlayer(const String& player)\n";
		play->unlock();
	}
}

void ChatRoomImplementation::broadcastMessage(BaseMessage* msg) {
	for (int i = 0; i < playerList.size(); ++i) {
		PlayerCreature* player = playerList.get(i);
		player->sendMessage(msg->clone());
	}

	delete msg;
}

void ChatRoomImplementation::removeAllPlayers() {
	wlock();

	for (int i = 0; i < playerList.size(); i++) {
		PlayerCreature* player = playerList.get(i);

		try {
			player->wlock(_this);

			player->removeChatRoom((ChatRoom*) _this);

			player->unlock();
		} catch (...) {
			System::out << "unreported Exception in ChatRoom::removeAllPlayers(Player* lockedPlayer)\n";
			player->unlock();
		}

	}

	playerList.removeAll();
	unlock();
}

String ChatRoomImplementation::getServerName() {
	return server->getServerName();
}
<commit_msg>[fixed] converted ChatRoom to use locker<commit_after>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program 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 of the License,
or (at your option) any later version.

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

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "ChatRoom.h"

#include "../../zone/objects/player/PlayerCreature.h"
#include "../../zone/objects/creature/CreatureObject.h"

#include "../../zone/ZoneServer.h"

#include "../../zone/packets/chat/ChatRoomList.h"
#include "../../zone/packets/chat/ChatOnDestroyRoom.h"
#include "../../zone/packets/chat/ChatOnLeaveRoom.h"
#include "../../zone/packets/chat/ChatOnEnteredRoom.h"
#include "server/zone/managers/objectcontroller/ObjectController.h"

void ChatRoomImplementation::sendTo(PlayerCreature* player) {
	ChatRoomList* crl = new ChatRoomList();
	crl->addChannel((ChatRoom*) _this);

	crl->insertChannelListCount();
	player->sendMessage(crl);
}

void ChatRoomImplementation::sendDestroyTo(PlayerCreature* player) {
	ChatOnDestroyRoom* msg = new ChatOnDestroyRoom("SWG", server->getServerName(), roomID);
	player->sendMessage(msg);
}

void ChatRoomImplementation::addPlayer(PlayerCreature* player, bool doLock) {
	Locker locker(_this);

	if (playerList.put(player->getFirstName(), player) == -1) {
		return;
	}

	ChatOnEnteredRoom* coer = new ChatOnEnteredRoom(server->getServerName(), player->getFirstName(), roomID);
	player->sendMessage(coer);

	locker.release();

	Locker locker2(player);

	player->addChatRoom((ChatRoom*) _this);

	/*ChatOnReceiveRoomInvitation* corri = new ChatOnReceiveRoomInvitation(name);
	player->sendMessage(corri);*/

}

void ChatRoomImplementation::removePlayer(PlayerCreature* player, bool doLock) {
	Locker locker(player);

	player->removeChatRoom((ChatRoom*) _this);

	locker.release();

	Locker locker2(_this);

	playerList.drop(player->getFirstName());

	ChatOnLeaveRoom* msg = new ChatOnLeaveRoom((ChatRoom*) _this, player);
	player->sendMessage(msg);
}

void ChatRoomImplementation::removePlayer(const String& player) {
	// Pre: player unlocked
	Locker locker(_this);

	PlayerCreature* play = playerList.get(player);
	playerList.drop(player);

	locker.release();

	if (play == NULL)
		return;

	try {
		Locker locker2(play);

		play->removeChatRoom((ChatRoom*) _this);

		ChatOnLeaveRoom* msg = new ChatOnLeaveRoom((ChatRoom*) _this, play);
		play->sendMessage(msg);
	} catch (...) {
		System::out << "unreported Exception in ChatRoom::removePlayer(const String& player)\n";
	}
}

void ChatRoomImplementation::broadcastMessage(BaseMessage* msg) {
	for (int i = 0; i < playerList.size(); ++i) {
		PlayerCreature* player = playerList.get(i);
		player->sendMessage(msg->clone());
	}

	delete msg;
}

void ChatRoomImplementation::removeAllPlayers() {
	Locker locker(_this);

	for (int i = 0; i < playerList.size(); i++) {
		PlayerCreature* player = playerList.get(i);

		try {
			Locker clocker(player, _this);

			player->removeChatRoom((ChatRoom*) _this);
		} catch (...) {
			System::out << "unreported Exception in ChatRoom::removeAllPlayers(Player* lockedPlayer)\n";
		}

	}

	playerList.removeAll();
}

String ChatRoomImplementation::getServerName() {
	return server->getServerName();
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program 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 of the License,
or (at your option) any later version.

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

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "GroupManager.h"

#include "../../ZoneServer.h"
#include "../../Zone.h"

#include "../../../chat/room/ChatRoom.h"

#include "../../objects/creature/CreatureObject.h"
#include "../../objects/creature/CreatureObject.h"

#include "../../objects/group/GroupObject.h"
#include "server/chat/StringIdChatParameter.h"
#include "../../managers/object/ObjectManager.h"

GroupManager::GroupManager() {
}

void GroupManager::inviteToGroup(CreatureObject* leader, CreatureObject* player) {
	// Pre: leader locked
	// Post: player invited to leader's group, leader locked

	Locker clocker(player, leader);

	if (player == leader) {
		leader->sendSystemMessage("@group:invite_no_target_self");
		return;
	}

	if (leader->isGrouped()) {
		ManagedReference<GroupObject*> group = leader->getGroup();

		if (group->getLeader() != leader) {
			leader->sendSystemMessage("@group:must_be_leader");
			return;
		}
	}

	if (player->isGrouped()) {
		StringIdChatParameter stringId;
		stringId.setStringId("group", "already_grouped");
		stringId.setTT(player);
		leader->sendSystemMessage(stringId);
		//leader->sendSystemMessage("group", "already_grouped", player->getObjectID());

		return;
	}

	if (player->getGroupInviterID() == leader->getObjectID()) {
		StringIdChatParameter stringId;
		stringId.setStringId("group", "considering_your_group");
		stringId.setTT(player);
		leader->sendSystemMessage(stringId);
		//leader->sendSystemMessage("group", "considering_your_group", player->getObjectID());

		return;
	} else if (player->getGroupInviterID() != 0) {
		StringBuffer msg;
		msg << player->getCreatureName().toString() << " is considering joining another group.";
		leader->sendSystemMessage(msg.toString());

		return;
	}

	player->updateGroupInviterID(leader->getObjectID());

	StringIdChatParameter stringId;
	stringId.setStringId("group", "invite_target");
	stringId.setTT(leader->getDisplayedName());
	player->sendSystemMessage(stringId);

	stringId.setStringId("group", "invite_leader");
	stringId.setTT(player->getDisplayedName());
	leader->sendSystemMessage(stringId);
}

void GroupManager::joinGroup(CreatureObject* player) {
	//Pre: player locked
	//Post: player locked
	uint64 inviterID = player->getGroupInviterID();

	Zone* zone = player->getZone();

	if (zone == NULL)
		return;

	ManagedReference<ZoneServer*> server = zone->getZoneServer();
	ManagedReference<SceneObject*> object = server->getObject(inviterID);

	if (object == NULL || !object->isPlayerCreature() || object == player)
		return;

	CreatureObject* inviter = cast<CreatureObject*>( object.get());
	GroupObject* group = NULL;

	Locker clocker(inviter, player);

	group = inviter->getGroup();

	if (group == NULL) {
		group = createGroup(inviter);

		if (group == NULL)
			return;
	}

	Locker clocker2(group, player);

	if (group->getGroupSize() == 20) {
		clocker.release();

		player->updateGroupInviterID(0);

		player->sendSystemMessage("@group:full");
		return;
	}

	// if invite IS in the group but is not the leader
	if ( group->getLeader() != inviter ){
		player->updateGroupInviterID(0);
		StringIdChatParameter param("group", "prose_leader_changed"); // "%TU has abdicated group leadership to %TT."
		param.setTU( inviter->getDisplayedName() );
		param.setTT( group->getLeader()->getDisplayedName() ) ;
		player->sendSystemMessage(param);

		return;
    }

	player->info("joining group");

	group->addMember(player);
	player->updateGroup(group);
	player->sendSystemMessage("@group:joined_self");

	ManagedReference<ChatRoom*> groupChannel = group->getGroupChannel();

	if (groupChannel != NULL && player->isPlayerCreature()) {
		groupChannel->sendTo(cast<CreatureObject*>(player));
		groupChannel->addPlayer(cast<CreatureObject*>(player), false);
	}

	player->updateGroupInviterID(0);
}

GroupObject* GroupManager::createGroup(CreatureObject* leader) {
	// Pre: leader locked
	// Post: GroupObject is a new group with leader, leader locked.
	Zone* zone = leader->getZone();

	if (zone == NULL)
		return NULL;

	ManagedReference<ZoneServer*> server = leader->getZone()->getZoneServer();

	ManagedReference<GroupObject*> group = cast<GroupObject*>( ObjectManager::instance()->createObject(0x13dcb432, 0, ""));
	group->initializeLeader(leader);
	group->startChatRoom();
	group->setZone(leader->getZone());

	group->sendTo(leader, true);

	leader->updateGroup(group);
	leader->sendSystemMessage("@group:formed_self");

	if (leader->getGroupInviterID() != 0)
		leader->updateGroupInviterID(0);

	return group;
}

void GroupManager::leaveGroup(ManagedReference<GroupObject*> group, CreatureObject* player) {
	// Pre: player locked
	// Post: player locked
	if (group == NULL)
		return;

	try {
		Locker clocker(group, player);

		ChatRoom* groupChannel = group->getGroupChannel();
		if (groupChannel != NULL && player->isPlayerCreature()) {
			CreatureObject* playerCreature = cast<CreatureObject*>( player);
			groupChannel->removePlayer(playerCreature, false);
			groupChannel->sendDestroyTo(playerCreature);

			ChatRoom* room = groupChannel->getParent();
			room->sendDestroyTo(playerCreature);
		}

		player->updateGroup(NULL);

		//if (player != NULL && player->isOnline() && !player->isLoggingOut())
		player->sendSystemMessage("@group:removed");

		player->unlock();

		group->removeMember(player);

		group->sendDestroyTo(player);

		player->info("leaving group");

		if (group->getGroupSize() < 2) {
			group->disband();
		}

	} catch (Exception& e) {
		System::out << e.getMessage();
		e.printStackTrace();

	} catch (...) {
		player->wlock();

		throw;
	}

	player->wlock();
}

void GroupManager::disbandGroup(ManagedReference<GroupObject*> group, CreatureObject* player) {
	//Pre: player locked
	//Post: player locked
	player->unlock();

	try {
		group->wlock();
		//The following should never happen, as a check is made in
		//ObjectControlMessage.cpp and removes the player from the group
		//if he's not the leader. Remove?
		//After Fix 13 feb 2009 - Bankler
		if (group->getLeader() != player) {
			player->sendSystemMessage("@group:must_be_leader");
			group->unlock();
			player->wlock();
			return;
		}

		for (int i = 0; i < group->getGroupSize(); i++) {
			CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

			play->sendSystemMessage("@group:disbanded");
		}

		group->disband();

		group->unlock();
	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	player->wlock();
}

void GroupManager::kickFromGroup(ManagedReference<GroupObject*> group, CreatureObject* player, CreatureObject* playerToKick) {
	// Pre: player is locked, group != NULL
	// Post: playerToKick kicked from group

	player->unlock();

	bool disbanded = false;

	try {
		group->wlock();

		if (!group->hasMember(playerToKick)) {
			group->unlock();
			player->wlock();
			return;
		}

		CreatureObject* leader = cast<CreatureObject*>( group->getLeader());

		if (player != leader) {
			player->sendSystemMessage("@group:must_be_leader");

			group->unlock();

			player->wlock();
			return;
		}

		if (group->getGroupSize() - 1 < 2) {
			for (int i = 0; i < group->getGroupSize(); i++) {
				CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

				play->sendSystemMessage("@group:disbanded");
			}
			group->disband();
			disbanded = true;
		} else {
			group->removeMember(playerToKick);

			playerToKick->sendSystemMessage("@group:removed");

			playerToKick->info("kicking from group");
		}

		group->unlock();

	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	if (!disbanded) {
		try {
			playerToKick->wlock();

			if (playerToKick->isPlayerCreature()) {
				CreatureObject* pl = cast<CreatureObject*>( playerToKick);
				ManagedReference<ChatRoom*> groupChannel = group->getGroupChannel();
				groupChannel->removePlayer(pl, false);
				groupChannel->sendDestroyTo(pl);

				ManagedReference<ChatRoom*> room = groupChannel->getParent();
				room->sendDestroyTo(pl);
			}

			playerToKick->updateGroup(NULL);

			group->sendDestroyTo(playerToKick);

			playerToKick->unlock();
		} catch (...) {
			playerToKick->unlock();

			player->wlock();

			throw;
		}
	}

	player->wlock();
}

void GroupManager::makeLeader(GroupObject* group, CreatureObject* player, CreatureObject* newLeader) {
	// Pre: player locked
	// Post: player locked
	player->unlock();

	try {
		group->wlock();

		if (group->getLeader() != player) {
			player->sendSystemMessage("@group:must_be_leader");
			group->unlock();
			player->wlock();
			return;
		}

		if (!group->hasMember(newLeader)) {
			group->unlock();
			player->wlock();
			return;
		}

		group->makeLeader(newLeader);

		String firstNameLeader;
		firstNameLeader = "[Offline player]";

		if (newLeader->isPlayerCreature()) {
			CreatureObject* playerLeader = cast<CreatureObject*>( newLeader);

			if (playerLeader->isOnline())
				firstNameLeader= playerLeader->getFirstName();
		}

		StringBuffer message;
		message << firstNameLeader << " is now the group leader.\n";

		for (int i = 0; i < group->getGroupSize(); i++) {
			CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

			play->sendSystemMessage(message.toString());
		}

		group->unlock();
	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	player->wlock();
}
<commit_msg>(unstable) [added] patch by Cebot: fixed group invite messages and clearing LFG flag on joining group.<commit_after>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program 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 of the License,
or (at your option) any later version.

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

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "GroupManager.h"

#include "../../ZoneServer.h"
#include "../../Zone.h"

#include "../../../chat/room/ChatRoom.h"

#include "../../objects/creature/CreatureObject.h"
#include "../../objects/creature/CreatureObject.h"
#include "server/zone/objects/player/PlayerObject.h"

#include "../../objects/group/GroupObject.h"
#include "server/chat/StringIdChatParameter.h"
#include "../../managers/object/ObjectManager.h"

GroupManager::GroupManager() {
}

void GroupManager::inviteToGroup(CreatureObject* leader, CreatureObject* player) {
	// Pre: leader locked
	// Post: player invited to leader's group, leader locked

	Locker clocker(player, leader);

	if (player == leader) {
		leader->sendSystemMessage("@group:invite_no_target_self");
		return;
	}

	if (leader->isGrouped()) {
		ManagedReference<GroupObject*> group = leader->getGroup();

		if (group->getLeader() != leader) {
			leader->sendSystemMessage("@group:must_be_leader");
			return;
		}

		// can't invite if the group is full
		if (group->getGroupSize() >= 20) {
			leader->sendSystemMessage("@group:full");
			return;
		}
	}

	if (player->isGrouped()) {
		StringIdChatParameter stringId;
		stringId.setStringId("group", "already_grouped");
		stringId.setTT(player);
		leader->sendSystemMessage(stringId);
		//leader->sendSystemMessage("group", "already_grouped", player->getObjectID());

		return;
	}

	if (player->getGroupInviterID() == leader->getObjectID()) {
		StringIdChatParameter stringId;
		stringId.setStringId("group", "considering_your_group");
		stringId.setTT(player);
		leader->sendSystemMessage(stringId);
		//leader->sendSystemMessage("group", "considering_your_group", player->getObjectID());

		return;
	} else if (player->getGroupInviterID() != 0) {
		StringBuffer msg;
		msg << player->getCreatureName().toString() << " is considering joining another group.";
		leader->sendSystemMessage(msg.toString());

		return;
	}

	player->updateGroupInviterID(leader->getObjectID());

	StringIdChatParameter stringId;
	stringId.setStringId("group", "invite_target");
	stringId.setTT(leader->getDisplayedName());
	player->sendSystemMessage(stringId);

	stringId.setStringId("group", "invite_leader");
	stringId.setTT(player->getDisplayedName());
	leader->sendSystemMessage(stringId);
}

void GroupManager::joinGroup(CreatureObject* player) {
	//Pre: player locked
	//Post: player locked
	uint64 inviterID = player->getGroupInviterID();

	Zone* zone = player->getZone();

	if (zone == NULL)
		return;

	ManagedReference<ZoneServer*> server = zone->getZoneServer();
	ManagedReference<SceneObject*> object = server->getObject(inviterID);

	if (object == NULL || !object->isPlayerCreature() || object == player)
		return;

	CreatureObject* inviter = cast<CreatureObject*>( object.get());
	GroupObject* group = NULL;

	Locker clocker(inviter, player);

	group = inviter->getGroup();

	if (group == NULL) {
		group = createGroup(inviter);

		if (group == NULL)
			return;
	}

	Locker clocker2(group, player);

	if (group->getGroupSize() >= 20) {
		clocker.release();

		player->updateGroupInviterID(0);

		player->sendSystemMessage("The group is full.");
		return;
	}

	// if invite IS in the group but is not the leader
	if ( group->getLeader() != inviter ){
		player->updateGroupInviterID(0);
		StringIdChatParameter param("group", "prose_leader_changed"); // "%TU has abdicated group leadership to %TT."
		param.setTU( inviter->getDisplayedName() );
		param.setTT( group->getLeader()->getDisplayedName() ) ;
		player->sendSystemMessage(param);

		return;
    }

	player->info("joining group");

	group->addMember(player);
	player->updateGroup(group);
	player->sendSystemMessage("@group:joined_self");

	// clear invitee's LFG setting once a group is joined
	PlayerObject* ghost = cast<PlayerObject*>(player->getSlottedObject("ghost"));
	if (ghost != NULL)
		ghost->clearCharacterBit(PlayerObject::LFG, true);

	ManagedReference<ChatRoom*> groupChannel = group->getGroupChannel();

	if (groupChannel != NULL && player->isPlayerCreature()) {
		groupChannel->sendTo(cast<CreatureObject*>(player));
		groupChannel->addPlayer(cast<CreatureObject*>(player), false);
	}

	player->updateGroupInviterID(0);
}

GroupObject* GroupManager::createGroup(CreatureObject* leader) {
	// Pre: leader locked
	// Post: GroupObject is a new group with leader, leader locked.
	Zone* zone = leader->getZone();

	if (zone == NULL)
		return NULL;

	ManagedReference<ZoneServer*> server = leader->getZone()->getZoneServer();

	ManagedReference<GroupObject*> group = cast<GroupObject*>( ObjectManager::instance()->createObject(0x13dcb432, 0, ""));
	group->initializeLeader(leader);
	group->startChatRoom();
	group->setZone(leader->getZone());

	group->sendTo(leader, true);

	leader->updateGroup(group);
	leader->sendSystemMessage("@group:formed_self");

	// clear inviter's LFG setting once a group is created
	PlayerObject* ghost = cast<PlayerObject*>(leader->getSlottedObject("ghost"));
	if (ghost != NULL)
		ghost->clearCharacterBit(PlayerObject::LFG, true);

	if (leader->getGroupInviterID() != 0)
		leader->updateGroupInviterID(0);

	return group;
}

void GroupManager::leaveGroup(ManagedReference<GroupObject*> group, CreatureObject* player) {
	// Pre: player locked
	// Post: player locked
	if (group == NULL)
		return;

	try {
		Locker clocker(group, player);

		ChatRoom* groupChannel = group->getGroupChannel();
		if (groupChannel != NULL && player->isPlayerCreature()) {
			CreatureObject* playerCreature = cast<CreatureObject*>( player);
			groupChannel->removePlayer(playerCreature, false);
			groupChannel->sendDestroyTo(playerCreature);

			ChatRoom* room = groupChannel->getParent();
			room->sendDestroyTo(playerCreature);
		}

		player->updateGroup(NULL);

		//if (player != NULL && player->isOnline() && !player->isLoggingOut())
		player->sendSystemMessage("@group:removed");

		player->unlock();

		group->removeMember(player);

		group->sendDestroyTo(player);

		player->info("leaving group");

		if (group->getGroupSize() < 2) {
			group->disband();
		}

	} catch (Exception& e) {
		System::out << e.getMessage();
		e.printStackTrace();

	} catch (...) {
		player->wlock();

		throw;
	}

	player->wlock();
}

void GroupManager::disbandGroup(ManagedReference<GroupObject*> group, CreatureObject* player) {
	//Pre: player locked
	//Post: player locked
	player->unlock();

	try {
		group->wlock();
		//The following should never happen, as a check is made in
		//ObjectControlMessage.cpp and removes the player from the group
		//if he's not the leader. Remove?
		//After Fix 13 feb 2009 - Bankler
		if (group->getLeader() != player) {
			player->sendSystemMessage("@group:must_be_leader");
			group->unlock();
			player->wlock();
			return;
		}

		for (int i = 0; i < group->getGroupSize(); i++) {
			CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

			play->sendSystemMessage("@group:disbanded");
		}

		group->disband();

		group->unlock();
	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	player->wlock();
}

void GroupManager::kickFromGroup(ManagedReference<GroupObject*> group, CreatureObject* player, CreatureObject* playerToKick) {
	// Pre: player is locked, group != NULL
	// Post: playerToKick kicked from group

	player->unlock();

	bool disbanded = false;

	try {
		group->wlock();

		if (!group->hasMember(playerToKick)) {
			group->unlock();
			player->wlock();
			return;
		}

		CreatureObject* leader = cast<CreatureObject*>( group->getLeader());

		if (player != leader) {
			player->sendSystemMessage("@group:must_be_leader");

			group->unlock();

			player->wlock();
			return;
		}

		if (group->getGroupSize() - 1 < 2) {
			for (int i = 0; i < group->getGroupSize(); i++) {
				CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

				play->sendSystemMessage("@group:disbanded");
			}
			group->disband();
			disbanded = true;
		} else {
			group->removeMember(playerToKick);

			playerToKick->sendSystemMessage("@group:removed");

			playerToKick->info("kicking from group");
		}

		group->unlock();

	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	if (!disbanded) {
		try {
			playerToKick->wlock();

			if (playerToKick->isPlayerCreature()) {
				CreatureObject* pl = cast<CreatureObject*>( playerToKick);
				ManagedReference<ChatRoom*> groupChannel = group->getGroupChannel();
				groupChannel->removePlayer(pl, false);
				groupChannel->sendDestroyTo(pl);

				ManagedReference<ChatRoom*> room = groupChannel->getParent();
				room->sendDestroyTo(pl);
			}

			playerToKick->updateGroup(NULL);

			group->sendDestroyTo(playerToKick);

			playerToKick->unlock();
		} catch (...) {
			playerToKick->unlock();

			player->wlock();

			throw;
		}
	}

	player->wlock();
}

void GroupManager::makeLeader(GroupObject* group, CreatureObject* player, CreatureObject* newLeader) {
	// Pre: player locked
	// Post: player locked
	player->unlock();

	try {
		group->wlock();

		if (group->getLeader() != player) {
			player->sendSystemMessage("@group:must_be_leader");
			group->unlock();
			player->wlock();
			return;
		}

		if (!group->hasMember(newLeader)) {
			group->unlock();
			player->wlock();
			return;
		}

		group->makeLeader(newLeader);

		String firstNameLeader;
		firstNameLeader = "[Offline player]";

		if (newLeader->isPlayerCreature()) {
			CreatureObject* playerLeader = cast<CreatureObject*>( newLeader);

			if (playerLeader->isOnline())
				firstNameLeader= playerLeader->getFirstName();
		}

		StringBuffer message;
		message << firstNameLeader << " is now the group leader.\n";

		for (int i = 0; i < group->getGroupSize(); i++) {
			CreatureObject* play = cast<CreatureObject*>( group->getGroupMember(i));

			play->sendSystemMessage(message.toString());
		}

		group->unlock();
	} catch (...) {
		group->unlock();

		player->wlock();

		throw;
	}

	player->wlock();
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkImageFileWriter.h"
#include "itkPointSetToImageFilter.h"
#include "itkPointSet.h"
#include "itkTestingMacros.h"

int
itkPointSetToImageFilterTest1(int argc, char * argv[])
{
  if (argc != 2)
  {
    std::cerr << "Missing parameters." << std::endl;
    std::cerr << "Usage: " << itkNameOfTestExecutableMacro(argv);
    std::cerr << " outputImageFile" << std::endl;
    return EXIT_FAILURE;
  }

  constexpr unsigned int PointSetDimension = 2;
  constexpr unsigned int ImageDimension = 2;

  using PointSetPointType = float;
  using PixelType = unsigned char;

  using PointSetType = itk::PointSet<PointSetPointType, PointSetDimension>;
  using BinaryImageType = itk::Image<PixelType, ImageDimension>;

  using PointSetType = itk::PointSet<PointSetPointType, PointSetDimension>;

  using PointType = PointSetType::PointType;

  auto pointSet = PointSetType::New();

  // Create a point set describing a circle
  float        radius = 100.0;
  unsigned int count = 0;
  for (float theta = 0; theta < 2.0 * itk::Math::pi; theta += 0.1)
  {
    PointType point;
    point[0] = radius * std::cos(theta);
    point[1] = radius * std::sin(theta);

    pointSet->SetPoint(count, point);
    count++;
  }

  using FilterType = itk::PointSetToImageFilter<PointSetType, BinaryImageType>;
  auto filter = FilterType::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(filter, PointSetToImageFilter, ImageSource);

  BinaryImageType::SpacingType::ValueType spacingValue = 1.0;
  BinaryImageType::SpacingType            spacing;
  spacing.Fill(spacingValue);
  filter->SetSpacing(spacing);
  ITK_TEST_SET_GET_VALUE(spacing, filter->GetSpacing());

  BinaryImageType::PointType origin{ { -125, -125 } };
  filter->SetOrigin(origin);
  ITK_TEST_SET_GET_VALUE(origin, filter->GetOrigin());

  typename BinaryImageType::DirectionType direction;
  direction.SetIdentity();
  filter->SetDirection(direction);
  ITK_TEST_SET_GET_VALUE(direction, filter->GetDirection());

  typename BinaryImageType::ValueType insideValue = itk::NumericTraits<typename BinaryImageType::ValueType>::OneValue();
  filter->SetInsideValue(insideValue);
  ITK_TEST_SET_GET_VALUE(insideValue, filter->GetInsideValue());

  typename BinaryImageType::ValueType outsideValue =
    itk::NumericTraits<typename BinaryImageType::ValueType>::ZeroValue();
  filter->SetOutsideValue(outsideValue);
  ITK_TEST_SET_GET_VALUE(outsideValue, filter->GetOutsideValue());

  typename BinaryImageType::SizeType size = { { 250, 250 } };
  filter->SetSize(size);
  ITK_TEST_SET_GET_VALUE(size, filter->GetSize());

  filter->SetInput(pointSet);
  ITK_TEST_SET_GET_VALUE(pointSet, filter->GetInput());

  unsigned int idx = 0;
  ITK_TEST_SET_GET_VALUE(pointSet, filter->GetInput(idx));

  ITK_TRY_EXPECT_NO_EXCEPTION(filter->Update());

  BinaryImageType::Pointer binaryImage = filter->GetOutput();

  itk::WriteImage(binaryImage, argv[1]);

  std::cout << "Test finished." << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>COMP: Fix missing initialization braces warning<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkImageFileWriter.h"
#include "itkPointSetToImageFilter.h"
#include "itkPointSet.h"
#include "itkTestingMacros.h"

int
itkPointSetToImageFilterTest1(int argc, char * argv[])
{
  if (argc != 2)
  {
    std::cerr << "Missing parameters." << std::endl;
    std::cerr << "Usage: " << itkNameOfTestExecutableMacro(argv);
    std::cerr << " outputImageFile" << std::endl;
    return EXIT_FAILURE;
  }

  constexpr unsigned int PointSetDimension = 2;
  constexpr unsigned int ImageDimension = 2;

  using PointSetPointType = float;
  using PixelType = unsigned char;

  using PointSetType = itk::PointSet<PointSetPointType, PointSetDimension>;
  using BinaryImageType = itk::Image<PixelType, ImageDimension>;

  using PointSetType = itk::PointSet<PointSetPointType, PointSetDimension>;

  using PointType = PointSetType::PointType;

  auto pointSet = PointSetType::New();

  // Create a point set describing a circle
  float        radius = 100.0;
  unsigned int count = 0;
  for (float theta = 0; theta < 2.0 * itk::Math::pi; theta += 0.1)
  {
    PointType point;
    point[0] = radius * std::cos(theta);
    point[1] = radius * std::sin(theta);

    pointSet->SetPoint(count, point);
    count++;
  }

  using FilterType = itk::PointSetToImageFilter<PointSetType, BinaryImageType>;
  auto filter = FilterType::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(filter, PointSetToImageFilter, ImageSource);

  BinaryImageType::SpacingType::ValueType spacingValue = 1.0;
  BinaryImageType::SpacingType            spacing;
  spacing.Fill(spacingValue);
  filter->SetSpacing(spacing);
  ITK_TEST_SET_GET_VALUE(spacing, filter->GetSpacing());

  BinaryImageType::PointType origin{ { { -125, -125 } } };
  filter->SetOrigin(origin);
  ITK_TEST_SET_GET_VALUE(origin, filter->GetOrigin());

  typename BinaryImageType::DirectionType direction;
  direction.SetIdentity();
  filter->SetDirection(direction);
  ITK_TEST_SET_GET_VALUE(direction, filter->GetDirection());

  typename BinaryImageType::ValueType insideValue = itk::NumericTraits<typename BinaryImageType::ValueType>::OneValue();
  filter->SetInsideValue(insideValue);
  ITK_TEST_SET_GET_VALUE(insideValue, filter->GetInsideValue());

  typename BinaryImageType::ValueType outsideValue =
    itk::NumericTraits<typename BinaryImageType::ValueType>::ZeroValue();
  filter->SetOutsideValue(outsideValue);
  ITK_TEST_SET_GET_VALUE(outsideValue, filter->GetOutsideValue());

  typename BinaryImageType::SizeType size = { { 250, 250 } };
  filter->SetSize(size);
  ITK_TEST_SET_GET_VALUE(size, filter->GetSize());

  filter->SetInput(pointSet);
  ITK_TEST_SET_GET_VALUE(pointSet, filter->GetInput());

  unsigned int idx = 0;
  ITK_TEST_SET_GET_VALUE(pointSet, filter->GetInput(idx));

  ITK_TRY_EXPECT_NO_EXCEPTION(filter->Update());

  BinaryImageType::Pointer binaryImage = filter->GetOutput();

  itk::WriteImage(binaryImage, argv[1]);

  std::cout << "Test finished." << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>