<commit_before>#ifndef ITERBASE_HPP_
#define ITERBASE_HPP_

// This file consists of utilities used for the generic nature of the
// iterable wrapper classes.  As such, the contents of this file should be
// considered UNDOCUMENTED and is subject to change without warning.  This
// also applies to the name of the file.  No user code should include
// this file directly.

#include <utility>
#include <iterator>
#include <functional>
#include <memory>
#include <type_traits>
#include <cstddef>

namespace iter {
    template <typename T>
    struct type_is {
        using type = T;
    };

    // gcc CWG 1558
    template <typename...>
    struct void_t_help {
        using type = void;
    };
    template <typename... Ts>
    using void_t = typename void_t_help<Ts...>::type;

    // iterator_type<C> is the type of C's iterator
    template <typename Container>
    using iterator_type =
        decltype(std::begin(std::declval<Container&>()));

    // iterator_deref<C> is the type obtained by dereferencing an iterator
    // to an object of type C
    template <typename Container>
    using iterator_deref =
        decltype(*std::declval<iterator_type<Container>&>());

    // const_iteator_deref is the type obtained through dereferencing
    // a const iterator& (note: not a const_iterator).  ie: the result
    // of Container::iterator::operator*() const
    template <typename Container>
    using const_iterator_deref =
        decltype(*std::declval<const iterator_type<Container>&>());

    template <typename Container>
    using iterator_traits_deref =
        typename std::remove_reference<iterator_deref<Container>>::type;

    // iterator_type<C> is the type of C's iterator
    template <typename Container>
    using reverse_iterator_type =
        decltype(std::declval<Container&>().rbegin());

    // iterator_deref<C> is the type obtained by dereferencing an iterator
    // to an object of type C
    template <typename Container>
    using reverse_iterator_deref =
        decltype(*std::declval<reverse_iterator_type<Container>&>());

    namespace detail {
    template <typename T, typename =void>
    struct ArrowHelper {
        using type = void;
    };

    template <typename T>
    struct ArrowHelper<T*, void> {
        using type = T*;
        constexpr type operator()(T* t) const noexcept {
            return t;
        }
    };

    template <typename T>
    struct ArrowHelper<T, void_t<decltype(std::declval<T&>().operator->())>> {
        using type = decltype(std::declval<T&>().operator->());
        type operator()(T& t) const {
            return t.operator->();
        }
    };

    template <typename T>
    using arrow = typename detail::ArrowHelper<T>::type;

    }

    // type of C::iterator::operator->, also works with pointers
    // void if the iterator has no operator->
    template <typename C>
    using iterator_arrow = detail::arrow<iterator_type<C>>;

    // applys the -> operator to an object, if the object is a pointer,
    // it returns the pointer
    template <typename T>
    detail::arrow<T> apply_arrow(T& t) {
        return detail::ArrowHelper<T>{}(t);
    }

    template <typename, typename =void>
    struct is_random_access_iter : std::false_type { };

    template <typename T>
    struct is_random_access_iter<T,
        typename std::enable_if<
             std::is_same<
                 typename std::iterator_traits<T>::iterator_category,
              std::random_access_iterator_tag>::value,
          void>::type> : std::true_type { };

    template <typename T>
    using has_random_access_iter = is_random_access_iter<iterator_type<T>>;
    // because std::advance assumes a lot and is actually smart, I need a dumb

    // version that will work with most things
    template <typename InputIt, typename Distance =std::size_t>
    void dumb_advance(InputIt& iter, Distance distance=1) {
        for (Distance i(0); i < distance; ++i) {
            ++iter;
        }
    }

    template <typename Iter, typename Distance>
    void dumb_advance_impl(Iter& iter, const Iter& end,
            Distance distance, std::false_type) {
        for (Distance i(0); i < distance && iter != end; ++i) {
            ++iter;
        }
    }

    template <typename Iter, typename Distance>
    void dumb_advance_impl(Iter& iter, const Iter& end,
            Distance distance, std::true_type) {
        if (static_cast<Distance>(end - iter) < distance) {
            iter = end;
        } else {
            iter += distance;
        }
    }

    // iter will not be incremented past end
    template <typename Iter, typename Distance =std::size_t>
    void dumb_advance(Iter& iter, const Iter& end, Distance distance=1) {
        dumb_advance_impl(iter, end, distance, is_random_access_iter<Iter>{});
    }

    template <typename ForwardIt, typename Distance =std::size_t>
    ForwardIt dumb_next(ForwardIt it, Distance distance=1) {
        dumb_advance(it, distance);
        return it;
    }

    template <typename ForwardIt, typename Distance =std::size_t>
    ForwardIt dumb_next(
            ForwardIt it, const ForwardIt& end, Distance distance=1) {
        dumb_advance(it, end, distance);
        return it;
    }

    template <typename Container, typename Distance =std::size_t>
    Distance dumb_size(Container&& container) {
        Distance d{0};
        for (auto it = std::begin(container), end = std::end(container);
                it != end;
                ++it) {
            ++d;
        }
        return d;
    }

    template <typename... Ts>
    struct are_same : std::true_type { };

    template <typename T, typename U, typename... Ts>
    struct are_same<T, U, Ts...>
        : std::integral_constant<bool,
            std::is_same<T, U>::value && are_same<T, Ts...>::value> { };

    // DerefHolder holds the value gotten from an iterator dereference
    // if the iterate dereferences to an lvalue references, a pointer to the
    //     element is stored
    // if it does not, a value is stored instead
    // get() returns a reference to the held item
    // get_ptr() returns a pointer to the held item
    // reset() replaces the currently held item

    template <typename T, typename =void>
    class DerefHolder {
        private:
            static_assert(!std::is_lvalue_reference<T>::value,
                    "Non-lvalue-ref specialization used for lvalue ref type");
            // it could still be an rvalue reference
            using TPlain = typename std::remove_reference<T>::type;

            std::unique_ptr<TPlain> item_p;

        public:
            using reference = TPlain&;
            using pointer = TPlain*;

            DerefHolder() = default;

            DerefHolder(const DerefHolder& other)
                : item_p{other.item_p ? new TPlain(*other.item_p) : nullptr}
            { }

            DerefHolder& operator=(const DerefHolder& other) {
                this->item_p.reset(other.item_p
                        ? new TPlain(*other.item_p) : nullptr);
                return *this;
            }

            DerefHolder(DerefHolder&&) = default;
            DerefHolder& operator=(DerefHolder&&) = default;
            ~DerefHolder() = default;

            reference get() {
                return *this->item_p;
            }

            pointer get_ptr() {
                return this->item_p.get();
            }

            void reset(T&& item) {
                item_p.reset(new TPlain(std::move(item)));
            }

            explicit operator bool() const {
                return this->item_p;
            }
    };

    // Specialization for when T is an lvalue ref.  Keep this in mind
    // wherever a T appears.
    template <typename T>
    class DerefHolder<T,
        typename std::enable_if<std::is_lvalue_reference<T>::value>::type>
    {
        public:
            using reference = T;
            using pointer = typename std::remove_reference<T>::type*;

        private:
            pointer item_p{};

        public:
            DerefHolder() = default;

            reference get() {
                return *this->item_p;
            }

            pointer get_ptr() {
                return this->item_p;
            }

            void reset(T item) {
                this->item_p = &item;
            }

            explicit operator bool() const {
                return this->item_p != nullptr;
            }
    };

}

#endif
<commit_msg>adds arrow proxy to provide -> interface<commit_after>#ifndef ITERBASE_HPP_
#define ITERBASE_HPP_

// This file consists of utilities used for the generic nature of the
// iterable wrapper classes.  As such, the contents of this file should be
// considered UNDOCUMENTED and is subject to change without warning.  This
// also applies to the name of the file.  No user code should include
// this file directly.

#include <utility>
#include <iterator>
#include <functional>
#include <memory>
#include <type_traits>
#include <cstddef>

namespace iter {
    template <typename T>
    struct type_is {
        using type = T;
    };

    // gcc CWG 1558
    template <typename...>
    struct void_t_help {
        using type = void;
    };
    template <typename... Ts>
    using void_t = typename void_t_help<Ts...>::type;

    // iterator_type<C> is the type of C's iterator
    template <typename Container>
    using iterator_type =
        decltype(std::begin(std::declval<Container&>()));

    // iterator_deref<C> is the type obtained by dereferencing an iterator
    // to an object of type C
    template <typename Container>
    using iterator_deref =
        decltype(*std::declval<iterator_type<Container>&>());

    // const_iteator_deref is the type obtained through dereferencing
    // a const iterator& (note: not a const_iterator).  ie: the result
    // of Container::iterator::operator*() const
    template <typename Container>
    using const_iterator_deref =
        decltype(*std::declval<const iterator_type<Container>&>());

    template <typename Container>
    using iterator_traits_deref =
        typename std::remove_reference<iterator_deref<Container>>::type;

    // iterator_type<C> is the type of C's iterator
    template <typename Container>
    using reverse_iterator_type =
        decltype(std::declval<Container&>().rbegin());

    // iterator_deref<C> is the type obtained by dereferencing an iterator
    // to an object of type C
    template <typename Container>
    using reverse_iterator_deref =
        decltype(*std::declval<reverse_iterator_type<Container>&>());

    namespace detail {
    template <typename T, typename =void>
    struct ArrowHelper {
        using type = void;
    };

    template <typename T>
    struct ArrowHelper<T*, void> {
        using type = T*;
        constexpr type operator()(T* t) const noexcept {
            return t;
        }
    };

    template <typename T>
    struct ArrowHelper<T, void_t<decltype(std::declval<T&>().operator->())>> {
        using type = decltype(std::declval<T&>().operator->());
        type operator()(T& t) const {
            return t.operator->();
        }
    };

    template <typename T>
    using arrow = typename detail::ArrowHelper<T>::type;

    }

    // type of C::iterator::operator->, also works with pointers
    // void if the iterator has no operator->
    template <typename C>
    using iterator_arrow = detail::arrow<iterator_type<C>>;

    // applys the -> operator to an object, if the object is a pointer,
    // it returns the pointer
    template <typename T>
    detail::arrow<T> apply_arrow(T& t) {
        return detail::ArrowHelper<T>{}(t);
    }

    // For iterators that have an operator* which returns a value
    // they can return this type from their operator-> instead, which will
    // wrap an object and allow it to be used with arrow
    template <typename T>
    class ArrowProxy {
        private:
            T obj;
        public:
            ArrowProxy(T&& in_obj)
                : obj(std::move(in_obj))
            { }

            T *operator->() {
                return &obj;
            }
    };

    template <typename, typename =void>
    struct is_random_access_iter : std::false_type { };

    template <typename T>
    struct is_random_access_iter<T,
        typename std::enable_if<
             std::is_same<
                 typename std::iterator_traits<T>::iterator_category,
              std::random_access_iterator_tag>::value,
          void>::type> : std::true_type { };

    template <typename T>
    using has_random_access_iter = is_random_access_iter<iterator_type<T>>;
    // because std::advance assumes a lot and is actually smart, I need a dumb

    // version that will work with most things
    template <typename InputIt, typename Distance =std::size_t>
    void dumb_advance(InputIt& iter, Distance distance=1) {
        for (Distance i(0); i < distance; ++i) {
            ++iter;
        }
    }

    template <typename Iter, typename Distance>
    void dumb_advance_impl(Iter& iter, const Iter& end,
            Distance distance, std::false_type) {
        for (Distance i(0); i < distance && iter != end; ++i) {
            ++iter;
        }
    }

    template <typename Iter, typename Distance>
    void dumb_advance_impl(Iter& iter, const Iter& end,
            Distance distance, std::true_type) {
        if (static_cast<Distance>(end - iter) < distance) {
            iter = end;
        } else {
            iter += distance;
        }
    }

    // iter will not be incremented past end
    template <typename Iter, typename Distance =std::size_t>
    void dumb_advance(Iter& iter, const Iter& end, Distance distance=1) {
        dumb_advance_impl(iter, end, distance, is_random_access_iter<Iter>{});
    }

    template <typename ForwardIt, typename Distance =std::size_t>
    ForwardIt dumb_next(ForwardIt it, Distance distance=1) {
        dumb_advance(it, distance);
        return it;
    }

    template <typename ForwardIt, typename Distance =std::size_t>
    ForwardIt dumb_next(
            ForwardIt it, const ForwardIt& end, Distance distance=1) {
        dumb_advance(it, end, distance);
        return it;
    }

    template <typename Container, typename Distance =std::size_t>
    Distance dumb_size(Container&& container) {
        Distance d{0};
        for (auto it = std::begin(container), end = std::end(container);
                it != end;
                ++it) {
            ++d;
        }
        return d;
    }

    template <typename... Ts>
    struct are_same : std::true_type { };

    template <typename T, typename U, typename... Ts>
    struct are_same<T, U, Ts...>
        : std::integral_constant<bool,
            std::is_same<T, U>::value && are_same<T, Ts...>::value> { };

    // DerefHolder holds the value gotten from an iterator dereference
    // if the iterate dereferences to an lvalue references, a pointer to the
    //     element is stored
    // if it does not, a value is stored instead
    // get() returns a reference to the held item
    // get_ptr() returns a pointer to the held item
    // reset() replaces the currently held item

    template <typename T, typename =void>
    class DerefHolder {
        private:
            static_assert(!std::is_lvalue_reference<T>::value,
                    "Non-lvalue-ref specialization used for lvalue ref type");
            // it could still be an rvalue reference
            using TPlain = typename std::remove_reference<T>::type;

            std::unique_ptr<TPlain> item_p;

        public:
            using reference = TPlain&;
            using pointer = TPlain*;

            DerefHolder() = default;

            DerefHolder(const DerefHolder& other)
                : item_p{other.item_p ? new TPlain(*other.item_p) : nullptr}
            { }

            DerefHolder& operator=(const DerefHolder& other) {
                this->item_p.reset(other.item_p
                        ? new TPlain(*other.item_p) : nullptr);
                return *this;
            }

            DerefHolder(DerefHolder&&) = default;
            DerefHolder& operator=(DerefHolder&&) = default;
            ~DerefHolder() = default;

            reference get() {
                return *this->item_p;
            }

            pointer get_ptr() {
                return this->item_p.get();
            }

            void reset(T&& item) {
                item_p.reset(new TPlain(std::move(item)));
            }

            explicit operator bool() const {
                return this->item_p;
            }
    };

    // Specialization for when T is an lvalue ref.  Keep this in mind
    // wherever a T appears.
    template <typename T>
    class DerefHolder<T,
        typename std::enable_if<std::is_lvalue_reference<T>::value>::type>
    {
        public:
            using reference = T;
            using pointer = typename std::remove_reference<T>::type*;

        private:
            pointer item_p{};

        public:
            DerefHolder() = default;

            reference get() {
                return *this->item_p;
            }

            pointer get_ptr() {
                return this->item_p;
            }

            void reset(T item) {
                this->item_p = &item;
            }

            explicit operator bool() const {
                return this->item_p != nullptr;
            }
    };

}

#endif
<|endoftext|>


<commit_before>//******************************************************************************
//
// File Name:     Card.cpp
//
// File Overview: Represents a Card containing a number and a suit

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

//******************************************************************************
// File scope (static) variable definitions
//******************************************************************************

// None

//******************************************************************************
// Function : constructor
// Process  : Initialize data members to invalid values
// Notes    : Not the recommended constructor
//             Need to set the number and suit afterwards
//******************************************************************************
Card::Card()
{
   number=0;
   suit=0;
} // end Card::Card

//******************************************************************************
// Function : constructor
// Process  : Initializes data members to input suit and number
// Notes    : Recommended constructor
//******************************************************************************
Card::Card(int number, int suit)
{
   this->number=number;
   this->suit=suit;
} // end Card::Card

void Card::setNum(int number)
{
   this->number = number;
} // end Card::setNum

//***************************************************************************
// Function : setSuit
// Process  : Mutator for suit
// Notes    : None
//***************************************************************************
void Card::setSuit(int suit)
{
   this->suit = suit;
} // end Card::setSuit

//***************************************************************************
// Function : getNum
// Process  : Accessor for number
// Notes    : None
//***************************************************************************
int Card::getNum()
{
   return this->number;
} // end Card::getNumber

//***************************************************************************
// Function : getSuit
// Process  : Accessor for suit
// Notes    : None
//***************************************************************************
int Card::getSuit()
{
   return this->suit;
} // end Card::getSuit

//***************************************************************************
// Function : printCard
// Process  : Print the card number and suit
//             Call printNumber
//             Call printSuit
// Notes    : None
//***************************************************************************
void Card::printCard()
{
   this->printNumber();
   this->printSuit();
} // end Card::printCard

//***************************************************************************
// Function : printNumber
// Process  : print the card number
//             11 - J for Jack
//             12 - Q for Queen
//             13 - K for King
//             14 - A for Ace
// Notes    : None
//***************************************************************************
void Card::printNumber()
{
   int number = this->getNum(); // Obtain the card's number

   if (number > 1 && number < 11)
   	  {
         cout << number;
      }
   	  else if (number == 11)
      {
         cout << "J";
      }
   	  else if (number == 12)
      {
         cout << "Q";
      }
   	  else if (number == 13)
      {
         cout << "K";
      }
   	  else if (number == 14)
      {
         cout << "A";
      }
   	  else
   	  {
   	     cout << " Invalid number ";
   	  }
} // end Card::printNumber

//***************************************************************************
// Function : printSuit
// Process  : Print the card suit
// Notes    : None
//***************************************************************************
void Card::printSuit()
{
	int suit = this->getSuit(); // Obtain the card's suit

	if(suit == 1)
	{
	 cout << "s" << " ";
	}
	else if(suit == 2)
	{
	 cout << "h" << " ";
	}
	else if(suit == 3)
	{
	 cout << "d" << " ";
	}
	else if(suit == 4)
	{
	 cout << "c" << " ";
	}
	else
	{
	 cout << "Invalid suit" << " ";
	}
} // end Card::printSuit

<commit_msg>Delete Card.cpp<commit_after><|endoftext|>


<commit_before>#include "hooks.h"
#include "undocumented.h"
#include "ssdt.h"
#include "hider.h"
#include "misc.h"
#include "pe.h"
#include "log.h"
#include "debugport.h"

static HOOK hNtQueryInformationProcess = 0;
static HOOK hNtQueryObject = 0;
static HOOK hNtQuerySystemInformation = 0;
static HOOK hNtClose = 0;
static HOOK hNtSetInformationThread = 0;
static HOOK hNtSetContextThread = 0;
static HOOK hNtSystemDebugControl = 0;
static FAST_MUTEX gDebugPortMutex;

static NTSTATUS NTAPI HookNtSetInformationThread(
    IN HANDLE ThreadHandle,
    IN THREADINFOCLASS ThreadInformationClass,
    IN PVOID ThreadInformation,
    IN ULONG ThreadInformationLength)
{
    //Bug found by Aguila, thanks!
    if(ThreadInformationClass == ThreadHideFromDebugger && !ThreadInformationLength)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        if(Hider::IsHidden(pid, HideThreadHideFromDebugger))
        {
            Log("[TITANHIDE] ThreadHideFromDebugger by %d\r\n", pid);
            PETHREAD Thread;
            NTSTATUS status;
#if NTDDI_VERSION >= NTDDI_WIN8
            status = ObReferenceObjectByHandleWithTag(ThreadHandle,
                     THREAD_SET_INFORMATION,
                     *PsThreadType,
                     ExGetPreviousMode(),
                     'yQsP', // special 'PsQuery' tag used in many Windows 8/8.1/10 NtXX/ZwXX functions
                     (PVOID*)&Thread,
                     NULL);
#else // Vista and XP don't have ObReferenceObjectByHandleWithTag; 7 has it but doesn't use it in NtSetInformationThread
            status = ObReferenceObjectByHandle(ThreadHandle,
                                               THREAD_SET_INFORMATION,
                                               *PsThreadType,
                                               ExGetPreviousMode(),
                                               (PVOID*)&Thread,
                                               NULL);
#endif
            if(NT_SUCCESS(status))
            {
#if NTDDI_VERSION >= NTDDI_WIN8
                ObfDereferenceObjectWithTag(Thread, 'yQsP');
#else
                ObDereferenceObject(Thread);
#endif
            }
            return status;
        }
    }
    return Undocumented::NtSetInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
}

static NTSTATUS NTAPI HookNtClose(
    IN HANDLE Handle)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    NTSTATUS ret;
    if(Hider::IsHidden(pid, HideNtClose))
    {
        //NCC Group Security Advisory
        ExAcquireFastMutex(&gDebugPortMutex);
        PVOID OldDebugPort = DebugPort::Set(PsGetCurrentProcess(), 0);
        ret = Undocumented::NtClose(Handle);
        DebugPort::Set(PsGetCurrentProcess(), OldDebugPort);
        ExReleaseFastMutex(&gDebugPortMutex);
        if(!NT_SUCCESS(ret))
            Log("[TITANHIDE] NtClose(0x%p) by %d\r\n", Handle, pid);
    }
    else
        ret = Undocumented::NtClose(Handle);
    return ret;
}

static NTSTATUS NTAPI HookNtQuerySystemInformation(
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength OPTIONAL)
{
    NTSTATUS ret = Undocumented::NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) && SystemInformation)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        if(SystemInformationClass == SystemKernelDebuggerInformation)
        {
            if(Hider::IsHidden(pid, HideSystemDebuggerInformation))
            {
                Log("[TITANHIDE] SystemKernelDebuggerInformation by %d\r\n", pid);
                typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
                {
                    BOOLEAN DebuggerEnabled;
                    BOOLEAN DebuggerNotPresent;
                } SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
                SYSTEM_KERNEL_DEBUGGER_INFORMATION* DebuggerInfo = (SYSTEM_KERNEL_DEBUGGER_INFORMATION*)SystemInformation;
                __try
                {
                    DebuggerInfo->DebuggerEnabled = false;
                    DebuggerInfo->DebuggerNotPresent = true;
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtQueryObject(
    IN HANDLE Handle OPTIONAL,
    IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
    OUT PVOID ObjectInformation OPTIONAL,
    IN ULONG ObjectInformationLength,
    OUT PULONG ReturnLength OPTIONAL)
{
    NTSTATUS ret = Undocumented::NtQueryObject(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) && ObjectInformation)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        UNICODE_STRING DebugObject;
        RtlInitUnicodeString(&DebugObject, L"DebugObject");
        if(ObjectInformationClass == ObjectTypeInformation && Hider::IsHidden(pid, HideDebugObject))
        {
            __try
            {
                OBJECT_TYPE_INFORMATION* type = (OBJECT_TYPE_INFORMATION*)ObjectInformation;
                ProbeForRead(type->TypeName.Buffer, 1, 1);
                if(RtlEqualUnicodeString(&type->TypeName, &DebugObject, FALSE)) //DebugObject
                {
                    Log("[TITANHIDE] DebugObject by %d\r\n", pid);
                    type->TotalNumberOfObjects = 0;
                    type->TotalNumberOfHandles = 0;
                }
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                ret = GetExceptionCode();
            }
        }
        else if(ObjectInformationClass == ObjectTypesInformation && Hider::IsHidden(pid, HideDebugObject))
        {
            //NCC Group Security Advisory
            __try
            {
                OBJECT_ALL_INFORMATION* pObjectAllInfo = (OBJECT_ALL_INFORMATION*)ObjectInformation;
                unsigned char* pObjInfoLocation = (unsigned char*)pObjectAllInfo->ObjectTypeInformation;
                unsigned int TotalObjects = pObjectAllInfo->NumberOfObjects;
                for(unsigned int i = 0; i < TotalObjects; i++)
                {
                    OBJECT_TYPE_INFORMATION* pObjectTypeInfo = (OBJECT_TYPE_INFORMATION*)pObjInfoLocation;
                    ProbeForRead(pObjectTypeInfo, 1, 1);
                    ProbeForRead(pObjectTypeInfo->TypeName.Buffer, 1, 1);
                    if(RtlEqualUnicodeString(&pObjectTypeInfo->TypeName, &DebugObject, FALSE)) //DebugObject
                    {
                        Log("[TITANHIDE] DebugObject by %d\r\n", pid);
                        pObjectTypeInfo->TotalNumberOfObjects = 0;
                        //Bug found by Aguila, thanks!
                        pObjectTypeInfo->TotalNumberOfHandles = 0;
                    }
                    pObjInfoLocation = (unsigned char*)pObjectTypeInfo->TypeName.Buffer;
                    pObjInfoLocation += pObjectTypeInfo->TypeName.MaximumLength;
                    ULONG_PTR tmp = ((ULONG_PTR)pObjInfoLocation) & -(LONG_PTR)sizeof(void*);
                    if((ULONG_PTR)tmp != (ULONG_PTR)pObjInfoLocation)
                        tmp += sizeof(void*);
                    pObjInfoLocation = ((unsigned char*)tmp);
                }
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                ret = GetExceptionCode();
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtQueryInformationProcess(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength)
{
    NTSTATUS ret = Undocumented::NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) &&
            ProcessInformation &&
            ProcessInformationClass != ProcessBasicInformation) //prevent stack overflow
    {
        ULONG pid = Misc::GetProcessIDFromProcessHandle(ProcessHandle);

        if(ProcessInformationClass == ProcessDebugFlags)
        {
            if(Hider::IsHidden(pid, HideProcessDebugFlags))
            {
                Log("[TITANHIDE] ProcessDebugFlags by %d\r\n", pid);
                __try
                {
                    *(unsigned int*)ProcessInformation = TRUE;
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
        else if(ProcessInformationClass == ProcessDebugPort)
        {
            if(Hider::IsHidden(pid, HideProcessDebugPort))
            {
                Log("[TITANHIDE] ProcessDebugPort by %d\r\n", pid);
                __try
                {
                    *(ULONG_PTR*)ProcessInformation = 0;
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
        else if(ProcessInformationClass == ProcessDebugObjectHandle)
        {
            if(Hider::IsHidden(pid, HideProcessDebugObjectHandle))
            {
                Log("[TITANHIDE] ProcessDebugObjectHandle by %d\r\n", pid);
                __try
                {
                    *(ULONG_PTR*)ProcessInformation = 0;
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
                //Taken from: http://newgre.net/idastealth
                ret = STATUS_PORT_NOT_SET;
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtSetContextThread(
    IN HANDLE ThreadHandle,
    IN PCONTEXT Context)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    bool IsHidden = Hider::IsHidden(pid, HideNtSetContextThread);
    ULONG OriginalContextFlags = 0;
    if(IsHidden)
    {
        //http://lifeinhex.com/dont-touch-this-writing-good-drivers-is-really-hard
        //http://lifeinhex.com/when-software-is-good-enough
        Log("[TITANHIDE] NtSetContextThread by %d\r\n", pid);
        __try
        {
            ProbeForRead(&Context->ContextFlags, sizeof(ULONG), 1);
            OriginalContextFlags = Context->ContextFlags;
            ULONG NewContextFlags = OriginalContextFlags & ~0x10; //CONTEXT_DEBUG_REGISTERS ^ CONTEXT_AMD64/CONTEXT_i386
            RtlSuperCopyMemory(&Context->ContextFlags, &NewContextFlags, sizeof(ULONG));
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return Undocumented::NtSetContextThread(ThreadHandle, Context);
        }
    }
    NTSTATUS ret = Undocumented::NtSetContextThread(ThreadHandle, Context);
    if(IsHidden)
    {
        __try
        {
            ProbeForRead(&Context->ContextFlags, sizeof(ULONG), 1);
            RtlSuperCopyMemory(&Context->ContextFlags, &OriginalContextFlags, sizeof(ULONG));
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtSystemDebugControl(
    IN SYSDBG_COMMAND Command,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength,
    OUT PULONG ReturnLength)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    if(Hider::IsHidden(pid, HideNtSystemDebugControl))
    {
        Log("[TITANHIDE] NtSystemDebugControl by %d\r\n", pid);
        if(Command == SysDbgGetTriageDump)
            return STATUS_INFO_LENGTH_MISMATCH;
        return STATUS_DEBUGGER_INACTIVE;
    }
    return Undocumented::NtSystemDebugControl(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength);
}

int Hooks::Initialize()
{
    ExInitializeFastMutex(&gDebugPortMutex);
    int hook_count = 0;
    hNtQueryInformationProcess = SSDT::Hook("NtQueryInformationProcess", (void*)HookNtQueryInformationProcess);
    if(hNtQueryInformationProcess)
        hook_count++;
    hNtQueryObject = SSDT::Hook("NtQueryObject", (void*)HookNtQueryObject);
    if(hNtQueryObject)
        hook_count++;
    hNtQuerySystemInformation = SSDT::Hook("NtQuerySystemInformation", (void*)HookNtQuerySystemInformation);
    if(hNtQuerySystemInformation)
        hook_count++;
    hNtSetInformationThread = SSDT::Hook("NtSetInformationThread", (void*)HookNtSetInformationThread);
    if(hNtSetInformationThread)
        hook_count++;
    hNtClose = SSDT::Hook("NtClose", (void*)HookNtClose);
    if(hNtClose)
        hook_count++;
    hNtSetContextThread = SSDT::Hook("NtSetContextThread", (void*)HookNtSetContextThread);
    if(hNtSetContextThread)
        hook_count++;
    hNtSystemDebugControl = SSDT::Hook("NtSystemDebugControl", (void*)HookNtSystemDebugControl);
    if(hNtSystemDebugControl)
        hook_count++;
    return hook_count;
}

void Hooks::Deinitialize()
{
    SSDT::Unhook(hNtQueryInformationProcess, true);
    SSDT::Unhook(hNtQueryObject, true);
    SSDT::Unhook(hNtQuerySystemInformation, true);
    SSDT::Unhook(hNtSetInformationThread, true);
    SSDT::Unhook(hNtClose, true);
    SSDT::Unhook(hNtSetContextThread, true);
    SSDT::Unhook(hNtSystemDebugControl, true);
}
<commit_msg>Restore ReturnLength in query hooks<commit_after>#include "hooks.h"
#include "undocumented.h"
#include "ssdt.h"
#include "hider.h"
#include "misc.h"
#include "pe.h"
#include "log.h"
#include "debugport.h"

static HOOK hNtQueryInformationProcess = 0;
static HOOK hNtQueryObject = 0;
static HOOK hNtQuerySystemInformation = 0;
static HOOK hNtClose = 0;
static HOOK hNtSetInformationThread = 0;
static HOOK hNtSetContextThread = 0;
static HOOK hNtSystemDebugControl = 0;
static FAST_MUTEX gDebugPortMutex;

//https://forum.tuts4you.com/topic/40011-debugme-vmprotect-312-build-886-anti-debug-method-improved/#comment-192824
//https://github.com/x64dbg/ScyllaHide/issues/47
//https://github.com/mrexodia/TitanHide/issues/27
#define BACKUP_RETURNLENGTH() \
    ULONG TempReturnLength = 0; \
    if(ARGUMENT_PRESENT(ReturnLength)) \
        TempReturnLength = *ReturnLength

#define RESTORE_RETURNLENGTH() \
    if(ARGUMENT_PRESENT(ReturnLength)) \
        *ReturnLength = TempReturnLength

static NTSTATUS NTAPI HookNtSetInformationThread(
    IN HANDLE ThreadHandle,
    IN THREADINFOCLASS ThreadInformationClass,
    IN PVOID ThreadInformation,
    IN ULONG ThreadInformationLength)
{
    //Bug found by Aguila, thanks!
    if(ThreadInformationClass == ThreadHideFromDebugger && !ThreadInformationLength)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        if(Hider::IsHidden(pid, HideThreadHideFromDebugger))
        {
            Log("[TITANHIDE] ThreadHideFromDebugger by %d\r\n", pid);
            PETHREAD Thread;
            NTSTATUS status;
#if NTDDI_VERSION >= NTDDI_WIN8
            status = ObReferenceObjectByHandleWithTag(ThreadHandle,
                     THREAD_SET_INFORMATION,
                     *PsThreadType,
                     ExGetPreviousMode(),
                     'yQsP', // special 'PsQuery' tag used in many Windows 8/8.1/10 NtXX/ZwXX functions
                     (PVOID*)&Thread,
                     NULL);
#else // Vista and XP don't have ObReferenceObjectByHandleWithTag; 7 has it but doesn't use it in NtSetInformationThread
            status = ObReferenceObjectByHandle(ThreadHandle,
                                               THREAD_SET_INFORMATION,
                                               *PsThreadType,
                                               ExGetPreviousMode(),
                                               (PVOID*)&Thread,
                                               NULL);
#endif
            if(NT_SUCCESS(status))
            {
#if NTDDI_VERSION >= NTDDI_WIN8
                ObfDereferenceObjectWithTag(Thread, 'yQsP');
#else
                ObDereferenceObject(Thread);
#endif
            }
            return status;
        }
    }
    return Undocumented::NtSetInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
}

static NTSTATUS NTAPI HookNtClose(
    IN HANDLE Handle)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    NTSTATUS ret;
    if(Hider::IsHidden(pid, HideNtClose))
    {
        //NCC Group Security Advisory
        ExAcquireFastMutex(&gDebugPortMutex);
        PVOID OldDebugPort = DebugPort::Set(PsGetCurrentProcess(), 0);
        ret = Undocumented::NtClose(Handle);
        DebugPort::Set(PsGetCurrentProcess(), OldDebugPort);
        ExReleaseFastMutex(&gDebugPortMutex);
        if(!NT_SUCCESS(ret))
            Log("[TITANHIDE] NtClose(0x%p) by %d\r\n", Handle, pid);
    }
    else
        ret = Undocumented::NtClose(Handle);
    return ret;
}

static NTSTATUS NTAPI HookNtQuerySystemInformation(
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength OPTIONAL)
{
    NTSTATUS ret = Undocumented::NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) && SystemInformation)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        if(SystemInformationClass == SystemKernelDebuggerInformation)
        {
            if(Hider::IsHidden(pid, HideSystemDebuggerInformation))
            {
                Log("[TITANHIDE] SystemKernelDebuggerInformation by %d\r\n", pid);
                typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
                {
                    BOOLEAN DebuggerEnabled;
                    BOOLEAN DebuggerNotPresent;
                } SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
                SYSTEM_KERNEL_DEBUGGER_INFORMATION* DebuggerInfo = (SYSTEM_KERNEL_DEBUGGER_INFORMATION*)SystemInformation;
                __try
                {
                    BACKUP_RETURNLENGTH();

                    DebuggerInfo->DebuggerEnabled = false;
                    DebuggerInfo->DebuggerNotPresent = true;

                    RESTORE_RETURNLENGTH();
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtQueryObject(
    IN HANDLE Handle OPTIONAL,
    IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
    OUT PVOID ObjectInformation OPTIONAL,
    IN ULONG ObjectInformationLength,
    OUT PULONG ReturnLength OPTIONAL)
{
    NTSTATUS ret = Undocumented::NtQueryObject(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) && ObjectInformation)
    {
        ULONG pid = (ULONG)PsGetCurrentProcessId();
        UNICODE_STRING DebugObject;
        RtlInitUnicodeString(&DebugObject, L"DebugObject");
        if(ObjectInformationClass == ObjectTypeInformation && Hider::IsHidden(pid, HideDebugObject))
        {
            __try
            {
                BACKUP_RETURNLENGTH();

                OBJECT_TYPE_INFORMATION* type = (OBJECT_TYPE_INFORMATION*)ObjectInformation;
                ProbeForRead(type->TypeName.Buffer, 1, 1);
                if(RtlEqualUnicodeString(&type->TypeName, &DebugObject, FALSE)) //DebugObject
                {
                    Log("[TITANHIDE] DebugObject by %d\r\n", pid);
                    type->TotalNumberOfObjects = 0;
                    type->TotalNumberOfHandles = 0;
                }

                RESTORE_RETURNLENGTH();
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                ret = GetExceptionCode();
            }
        }
        else if(ObjectInformationClass == ObjectTypesInformation && Hider::IsHidden(pid, HideDebugObject))
        {
            //NCC Group Security Advisory
            __try
            {
                BACKUP_RETURNLENGTH();

                OBJECT_ALL_INFORMATION* pObjectAllInfo = (OBJECT_ALL_INFORMATION*)ObjectInformation;
                unsigned char* pObjInfoLocation = (unsigned char*)pObjectAllInfo->ObjectTypeInformation;
                unsigned int TotalObjects = pObjectAllInfo->NumberOfObjects;
                for(unsigned int i = 0; i < TotalObjects; i++)
                {
                    OBJECT_TYPE_INFORMATION* pObjectTypeInfo = (OBJECT_TYPE_INFORMATION*)pObjInfoLocation;
                    ProbeForRead(pObjectTypeInfo, 1, 1);
                    ProbeForRead(pObjectTypeInfo->TypeName.Buffer, 1, 1);
                    if(RtlEqualUnicodeString(&pObjectTypeInfo->TypeName, &DebugObject, FALSE)) //DebugObject
                    {
                        Log("[TITANHIDE] DebugObject by %d\r\n", pid);
                        pObjectTypeInfo->TotalNumberOfObjects = 0;
                        //Bug found by Aguila, thanks!
                        pObjectTypeInfo->TotalNumberOfHandles = 0;
                    }
                    pObjInfoLocation = (unsigned char*)pObjectTypeInfo->TypeName.Buffer;
                    pObjInfoLocation += pObjectTypeInfo->TypeName.MaximumLength;
                    ULONG_PTR tmp = ((ULONG_PTR)pObjInfoLocation) & -(LONG_PTR)sizeof(void*);
                    if((ULONG_PTR)tmp != (ULONG_PTR)pObjInfoLocation)
                        tmp += sizeof(void*);
                    pObjInfoLocation = ((unsigned char*)tmp);
                }

                RESTORE_RETURNLENGTH();
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                ret = GetExceptionCode();
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtQueryInformationProcess(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength)
{
    NTSTATUS ret = Undocumented::NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
    if(NT_SUCCESS(ret) &&
            ProcessInformation &&
            ProcessInformationClass != ProcessBasicInformation) //prevent stack overflow
    {
        ULONG pid = Misc::GetProcessIDFromProcessHandle(ProcessHandle);

        if(ProcessInformationClass == ProcessDebugFlags)
        {
            if(Hider::IsHidden(pid, HideProcessDebugFlags))
            {
                Log("[TITANHIDE] ProcessDebugFlags by %d\r\n", pid);
                __try
                {
                    BACKUP_RETURNLENGTH();

                    *(unsigned int*)ProcessInformation = TRUE;

                    RESTORE_RETURNLENGTH();
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
        else if(ProcessInformationClass == ProcessDebugPort)
        {
            if(Hider::IsHidden(pid, HideProcessDebugPort))
            {
                Log("[TITANHIDE] ProcessDebugPort by %d\r\n", pid);
                __try
                {
                    BACKUP_RETURNLENGTH();

                    *(ULONG_PTR*)ProcessInformation = 0;

                    RESTORE_RETURNLENGTH();
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
            }
        }
        else if(ProcessInformationClass == ProcessDebugObjectHandle)
        {
            if(Hider::IsHidden(pid, HideProcessDebugObjectHandle))
            {
                Log("[TITANHIDE] ProcessDebugObjectHandle by %d\r\n", pid);
                __try
                {
                    BACKUP_RETURNLENGTH();

                    *(ULONG_PTR*)ProcessInformation = 0;

                    RESTORE_RETURNLENGTH();
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    ret = GetExceptionCode();
                }
                //Taken from: http://newgre.net/idastealth
                ret = STATUS_PORT_NOT_SET;
            }
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtSetContextThread(
    IN HANDLE ThreadHandle,
    IN PCONTEXT Context)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    bool IsHidden = Hider::IsHidden(pid, HideNtSetContextThread);
    ULONG OriginalContextFlags = 0;
    if(IsHidden)
    {
        //http://lifeinhex.com/dont-touch-this-writing-good-drivers-is-really-hard
        //http://lifeinhex.com/when-software-is-good-enough
        Log("[TITANHIDE] NtSetContextThread by %d\r\n", pid);
        __try
        {
            ProbeForRead(&Context->ContextFlags, sizeof(ULONG), 1);
            OriginalContextFlags = Context->ContextFlags;
            ULONG NewContextFlags = OriginalContextFlags & ~0x10; //CONTEXT_DEBUG_REGISTERS ^ CONTEXT_AMD64/CONTEXT_i386
            RtlSuperCopyMemory(&Context->ContextFlags, &NewContextFlags, sizeof(ULONG));
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return Undocumented::NtSetContextThread(ThreadHandle, Context);
        }
    }
    NTSTATUS ret = Undocumented::NtSetContextThread(ThreadHandle, Context);
    if(IsHidden)
    {
        __try
        {
            ProbeForRead(&Context->ContextFlags, sizeof(ULONG), 1);
            RtlSuperCopyMemory(&Context->ContextFlags, &OriginalContextFlags, sizeof(ULONG));
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }
    }
    return ret;
}

static NTSTATUS NTAPI HookNtSystemDebugControl(
    IN SYSDBG_COMMAND Command,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength,
    OUT PULONG ReturnLength)
{
    ULONG pid = (ULONG)PsGetCurrentProcessId();
    if(Hider::IsHidden(pid, HideNtSystemDebugControl))
    {
        Log("[TITANHIDE] NtSystemDebugControl by %d\r\n", pid);
        if(Command == SysDbgGetTriageDump)
            return STATUS_INFO_LENGTH_MISMATCH;
        return STATUS_DEBUGGER_INACTIVE;
    }
    return Undocumented::NtSystemDebugControl(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength);
}

int Hooks::Initialize()
{
    ExInitializeFastMutex(&gDebugPortMutex);
    int hook_count = 0;
    hNtQueryInformationProcess = SSDT::Hook("NtQueryInformationProcess", (void*)HookNtQueryInformationProcess);
    if(hNtQueryInformationProcess)
        hook_count++;
    hNtQueryObject = SSDT::Hook("NtQueryObject", (void*)HookNtQueryObject);
    if(hNtQueryObject)
        hook_count++;
    hNtQuerySystemInformation = SSDT::Hook("NtQuerySystemInformation", (void*)HookNtQuerySystemInformation);
    if(hNtQuerySystemInformation)
        hook_count++;
    hNtSetInformationThread = SSDT::Hook("NtSetInformationThread", (void*)HookNtSetInformationThread);
    if(hNtSetInformationThread)
        hook_count++;
    hNtClose = SSDT::Hook("NtClose", (void*)HookNtClose);
    if(hNtClose)
        hook_count++;
    hNtSetContextThread = SSDT::Hook("NtSetContextThread", (void*)HookNtSetContextThread);
    if(hNtSetContextThread)
        hook_count++;
    hNtSystemDebugControl = SSDT::Hook("NtSystemDebugControl", (void*)HookNtSystemDebugControl);
    if(hNtSystemDebugControl)
        hook_count++;
    return hook_count;
}

void Hooks::Deinitialize()
{
    SSDT::Unhook(hNtQueryInformationProcess, true);
    SSDT::Unhook(hNtQueryObject, true);
    SSDT::Unhook(hNtQuerySystemInformation, true);
    SSDT::Unhook(hNtSetInformationThread, true);
    SSDT::Unhook(hNtClose, true);
    SSDT::Unhook(hNtSetContextThread, true);
    SSDT::Unhook(hNtSystemDebugControl, true);
}
<|endoftext|>


<commit_before><commit_msg>Use more intuitive variable for interpolated orientation inside the filter.<commit_after><|endoftext|>


<commit_before>#include "lua_netfoxpack.hpp"
#include "../LuaFunction.hpp"
#include<stdlib.h>
#include<string.h>

#define Key_Value   "ABcde34gdbbddddd"
const unsigned int  g_dwDelta = 0xA55AA55A;
#define SOCKET_VER 0x66

//Decrypt
static void DecryptTEA(unsigned int *dwFirstChunk,unsigned int *dwSecondChunk)
{
	const unsigned int *dwXorKey = (unsigned int*)Key_Value;
	unsigned int sum = 0;
	unsigned int  y = *dwFirstChunk;
	unsigned int  z = *dwSecondChunk;
	unsigned int  dwDelta = g_dwDelta;
	short i;

	sum = dwDelta << 5;

	for (i = 0; i < 32; i++)
	{
		z -= (y << 4) + dwXorKey[2] ^ y + sum ^ (y >> 5) + dwXorKey[3];
		y -= (z << 4) + dwXorKey[0] ^ z + sum ^ (z >> 5) + dwXorKey[1];
		sum -= dwDelta;
	}

	*dwFirstChunk = y;
	*dwSecondChunk = z;
}

//Encrypt
static void EncryptTEA(unsigned int *dwFirstChunk, unsigned int *dwSecondChunk)
{
#if __GNUC__ >= 5
	rand();
#endif
	unsigned int y = *dwFirstChunk;
	unsigned int z = *dwSecondChunk;
	unsigned int sum = 0;
	int i;

	unsigned int *key = (unsigned int *)"ABcde34gdbbddddd";

	unsigned int dwDelta = 0xA55AA55A;

	for (i = 0; i < 32; i++)
	{
		sum += dwDelta;
		y += ((z << 4) + key[0]) ^ (z + sum) ^ ((z >> 5) + key[1]);
		z += ((y << 4) + key[2]) ^ (y + sum) ^ ((y >> 5) + key[3]);
	}

	*dwSecondChunk = z;
	*dwFirstChunk = y;
}

//Decrypt
static void DecryptBuffer(unsigned char* pBuffer, unsigned short wDataSize)
{
	unsigned char *p = pBuffer;
	while (p < pBuffer + wDataSize)
	{
		DecryptTEA((unsigned int *)p, (unsigned int *)(p + sizeof(unsigned int)));
		p += sizeof(unsigned int) * 2;
	}
}

//Encrypt
static void EncryptBuffer(unsigned char* pBuffer, unsigned short wDataSize)
{
	unsigned char *p = pBuffer;

	while (p < pBuffer + wDataSize)
	{
		EncryptTEA((unsigned int *)p, (unsigned int *)(p + sizeof(unsigned int)));
		p += sizeof(unsigned int) * 2;
	}
}

#define CodecMETA  "netfoxCodec"

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct CMD_Info
{
	unsigned char cbVersion;
	unsigned char cbCheckCode;
	unsigned short wPacketSize;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Info;
#else
CMD_Info;
#pragma pack()
#endif

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct CMD_Command
{
	unsigned short							wMainCmdID;
	unsigned short							wSubCmdID;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Command;
#else
CMD_Command;
#pragma pack()
#endif

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct  _CMD_Head{
	struct CMD_Info CmdInfo;
	struct CMD_Command CommandInfo;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Head;
#else
CMD_Head;
#pragma pack()
#endif

typedef struct _CodecData {
  int _readStep;
  int _currentReadSize;
  int mainID;
  int subID;
  int _needReadTotalSize;
  int _receiveSeqNum;
  char* _readBuffer;
}CodecData;

static inline CodecData** toCodecp(lua_State* L){
    return (CodecData**)luaL_checkudata(L, 1, CodecMETA);
}

CodecData* toCodec(lua_State* L) {
    auto w = toCodecp(L);
    if (*w == NULL)
        luaL_error(L, "Param already closed");
    return *w;
}

void CodecData_reset(CodecData* data) {
  data->_readStep = 0,
  data->_currentReadSize = 0,
  data->mainID = 0,
  data->subID = 0,
  data->_receiveSeqNum = 0;
  data->_needReadTotalSize = sizeof(CMD_Head);
}

void CodecData_init(CodecData* data) {
  CodecData_reset(data);
  data->_readBuffer = (char*)malloc(data->_needReadTotalSize);
}

void CodecData_destroy(CodecData* data) {
  if(data->_readBuffer)
    free(data->_readBuffer);
  data->_readBuffer = NULL;
}

static int _read_head_ok(CodecData* self){
	CMD_Head* header = (CMD_Head*)self->_readBuffer;
	DecryptBuffer((unsigned char*)header, sizeof(CMD_Head));
	//printf("receive main id is %d ,sub id is %d body size is %d,\r\n", header->CommandInfo.wMainCmdID, header->CommandInfo.wSubCmdID, header->CmdInfo.wPacketSize);
	if (header->CmdInfo.cbCheckCode != 0x02 || header->CmdInfo.cbVersion != SOCKET_VER){
		printf("header->CmdInfo.wPacketSize %d \r\n",header->CmdInfo.wPacketSize);
		printf("header->CmdInfo.cbCheckCode %d \r\n",header->CmdInfo.cbCheckCode);
		printf("header->CmdInfo.cbVersion %d \r\n",header->CmdInfo.cbVersion);
		printf("error on DecryptBuffer \r\n");
		return 0;
	}

	self->_needReadTotalSize = header->CmdInfo.wPacketSize - sizeof(CMD_Head);
	self->_receiveSeqNum ++;
	self->_readStep = 1;
	self->_currentReadSize = 0;
	self->mainID = header->CommandInfo.wMainCmdID;
	self->subID = header->CommandInfo.wSubCmdID;

	free(self->_readBuffer);
	self->_readBuffer = (char*)malloc(self->_needReadTotalSize);

	return 1;
}

static void _read_body_ok(CodecData* self,const LuaFunction& onMessage){
	int packageSize = 0;
	char* tmpBuffer = (char*)malloc(self->_needReadTotalSize + 100);
	memcpy(tmpBuffer, self->_readBuffer, self->_needReadTotalSize);
	packageSize = self->_needReadTotalSize;

  const char* package = (const char*)tmpBuffer;
  Data data;
  data.buf = package;
  data.len = packageSize;

	onMessage(data,packageSize,self->mainID,self->subID);
	free(tmpBuffer);

	// read head again
	free(self->_readBuffer);
	self->_readBuffer = (char*)malloc(sizeof(CMD_Head));
	self->_readStep = 0;
	self->_needReadTotalSize = sizeof(CMD_Head);
	self->_currentReadSize = 0;
}

static int netfox_process(lua_State* L){
  CodecData* self = toCodec(L);
  size_t nread;
  const char* buf = lua_tolstring(L,2,&nread);
  LuaFunction onMessage(L,3);
  LuaFunction onError(L,4);

	int end = 0;
	int big = 0;
	int readSize = 0;
	int ok = 0;
	int read_bytes = nread;
	int total_size = 0;
	int headIsOk = 0;
_retry:
	end = self->_currentReadSize + read_bytes;
	big = 0;
	ok = 0;
	if(end >= self->_needReadTotalSize){
		big = end - self->_needReadTotalSize;
		ok = 1;
	}
	readSize = read_bytes - big;
	memcpy(self->_readBuffer + self->_currentReadSize,buf + total_size,readSize);
	total_size += readSize;
	self->_currentReadSize += readSize;

	switch(self->_readStep){
	case 0:
		if(ok){
			headIsOk = _read_head_ok(self);
			if(headIsOk != 1){
				onError();
				return 0;
			}
		}
		break;

	case 1:
		if(ok){
			_read_body_ok(self,onMessage);
		}
		break;
	}

	if(big > 0){
		read_bytes = big;
		goto _retry;
	}

  return 0;
}

static int netfox_createPackage(lua_State* L) {
  size_t size;
  const char* data = lua_tolstring(L,1,&size);
	if(size > 65535)
		printf("the package is to big than unsigned short range");

  char* buffer = (char*)malloc(sizeof(CMD_Head) + size + 100);
  CMD_Head* pHeader = (CMD_Head*)buffer;

  char* write_data = (char*)buffer;
  pHeader->CommandInfo.wMainCmdID = 99;
  pHeader->CommandInfo.wSubCmdID = 99;
  pHeader->CmdInfo.cbVersion = SOCKET_VER;
  pHeader->CmdInfo.wPacketSize = sizeof(CMD_Head) + size;
  pHeader->CmdInfo.cbCheckCode = 0x02;

// printf("pre size is %d\r\n",pHeader->CmdInfo.wPacketSize);
 EncryptBuffer((unsigned char*)pHeader, sizeof(CMD_Head));
// printf("encrypt pre size is %d\r\n",pHeader->CmdInfo.wPacketSize);
// DecryptBuffer((unsigned char*)pHeader, sizeof(CMD_Head));
// printf("post size is %d\r\n",pHeader->CmdInfo.wPacketSize);

  if (size > 0)
  {
  	memcpy(&write_data[sizeof(CMD_Head)], data, size);
  }

  int wSendSize = sizeof(CMD_Head) + size;
  lua_pushlstring(L,buffer,wSendSize);
  DecryptBuffer((unsigned char*)pHeader,sizeof(CMD_Head));

  free(buffer);

  return 1;
}

static int Codec_create(lua_State* L)
{
    CodecData** w = (CodecData**)lua_newuserdata(L, sizeof(*w));
    *w = new CodecData();
    CodecData_init(*w);
    luaL_getmetatable(L, CodecMETA);
    lua_setmetatable(L, -2);

    return 1;
}

static int Codec_gc(lua_State* L)
{
    auto w = toCodecp(L);

    printf("finalizing LUA object (%s)\n", CodecMETA);

    if (!*w)
        return 0;

    CodecData_destroy(*w);
    delete *w;
    *w = nullptr; // mark as closed
    return 0;
}

static luaL_Reg methods[] = {
    { "__gc", Codec_gc },
    { NULL, NULL },
};

static luaL_Reg api[] = {
    { "CodecData", Codec_create },
    { "process", netfox_process},
    { "createPackage", netfox_createPackage},
    { NULL, NULL },
};

int luaopen_netfoxpack(lua_State* L)
{
  luaL_newmetatable(L, CodecMETA);
  lua_pushvalue(L, -1);
  lua_setfield(L, -2, "__index");
  luaL_register(L, NULL, methods);
  lua_pop(L, 1);

  // register the net api
  lua_newtable(L);
  luaL_register(L, NULL, api);

  return 1;
}
<commit_msg>fixed bugs<commit_after>#include "lua_netfoxpack.hpp"
#include "../LuaFunction.hpp"
#include<stdlib.h>
#include<string.h>

#define Key_Value   "ABcde34gdbbddddd"
const unsigned int  g_dwDelta = 0xA55AA55A;
#define SOCKET_VER 0x66

//Decrypt
static void DecryptTEA(unsigned int *dwFirstChunk,unsigned int *dwSecondChunk)
{
	const unsigned int *dwXorKey = (unsigned int*)Key_Value;
	unsigned int sum = 0;
	unsigned int  y = *dwFirstChunk;
	unsigned int  z = *dwSecondChunk;
	unsigned int  dwDelta = g_dwDelta;
	short i;

	sum = dwDelta << 5;

	for (i = 0; i < 32; i++)
	{
		z -= (y << 4) + dwXorKey[2] ^ y + sum ^ (y >> 5) + dwXorKey[3];
		y -= (z << 4) + dwXorKey[0] ^ z + sum ^ (z >> 5) + dwXorKey[1];
		sum -= dwDelta;
	}

	*dwFirstChunk = y;
	*dwSecondChunk = z;
}

//Encrypt
static void EncryptTEA(unsigned int *dwFirstChunk, unsigned int *dwSecondChunk)
{
#if __GNUC__ >= 5
	rand();
#endif
	unsigned int y = *dwFirstChunk;
	unsigned int z = *dwSecondChunk;
	unsigned int sum = 0;
	int i;

	unsigned int *key = (unsigned int *)"ABcde34gdbbddddd";

	unsigned int dwDelta = 0xA55AA55A;

	for (i = 0; i < 32; i++)
	{
		sum += dwDelta;
		y += ((z << 4) + key[0]) ^ (z + sum) ^ ((z >> 5) + key[1]);
		z += ((y << 4) + key[2]) ^ (y + sum) ^ ((y >> 5) + key[3]);
	}

	*dwSecondChunk = z;
	*dwFirstChunk = y;
}

//Decrypt
static void DecryptBuffer(unsigned char* pBuffer, unsigned short wDataSize)
{
	unsigned char *p = pBuffer;
	while (p < pBuffer + wDataSize)
	{
		DecryptTEA((unsigned int *)p, (unsigned int *)(p + sizeof(unsigned int)));
		p += sizeof(unsigned int) * 2;
	}
}

//Encrypt
static void EncryptBuffer(unsigned char* pBuffer, unsigned short wDataSize)
{
	unsigned char *p = pBuffer;

	while (p < pBuffer + wDataSize)
	{
		EncryptTEA((unsigned int *)p, (unsigned int *)(p + sizeof(unsigned int)));
		p += sizeof(unsigned int) * 2;
	}
}

#define CodecMETA  "netfoxCodec"

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct CMD_Info
{
	unsigned char cbVersion;
	unsigned char cbCheckCode;
	unsigned short wPacketSize;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Info;
#else
CMD_Info;
#pragma pack()
#endif

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct CMD_Command
{
	unsigned short							wMainCmdID;
	unsigned short							wSubCmdID;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Command;
#else
CMD_Command;
#pragma pack()
#endif

#ifdef WIN32
#pragma pack(1)
#endif
typedef struct  _CMD_Head{
	struct CMD_Info CmdInfo;
	struct CMD_Command CommandInfo;
}
#ifndef WIN32
__attribute__((packed, aligned(1))) CMD_Head;
#else
CMD_Head;
#pragma pack()
#endif

typedef struct _CodecData {
  int _readStep;
  int _currentReadSize;
  int mainID;
  int subID;
  int _needReadTotalSize;
  int _receiveSeqNum;
  char* _readBuffer;
}CodecData;

static inline CodecData** toCodecp(lua_State* L){
    return (CodecData**)luaL_checkudata(L, 1, CodecMETA);
}

CodecData* toCodec(lua_State* L) {
    auto w = toCodecp(L);
    if (*w == NULL)
        luaL_error(L, "Param already closed");
    return *w;
}

void CodecData_reset(CodecData* data) {
  data->_readStep = 0,
  data->_currentReadSize = 0,
  data->mainID = 0,
  data->subID = 0,
  data->_receiveSeqNum = 0;
  data->_needReadTotalSize = sizeof(CMD_Head);
}

void CodecData_init(CodecData* data) {
  CodecData_reset(data);
  data->_readBuffer = (char*)malloc(data->_needReadTotalSize);
}

void CodecData_destroy(CodecData* data) {
  if(data->_readBuffer)
    free(data->_readBuffer);
  data->_readBuffer = NULL;
}

static int _read_head_ok(CodecData* self){
	CMD_Head* header = (CMD_Head*)self->_readBuffer;
	DecryptBuffer((unsigned char*)header, sizeof(CMD_Head));
	//printf("receive main id is %d ,sub id is %d body size is %d,\r\n", header->CommandInfo.wMainCmdID, header->CommandInfo.wSubCmdID, header->CmdInfo.wPacketSize);
	if (header->CmdInfo.cbCheckCode != 0x02 || header->CmdInfo.cbVersion != SOCKET_VER){
		printf("header->CmdInfo.wPacketSize %d \r\n",header->CmdInfo.wPacketSize);
		printf("header->CmdInfo.cbCheckCode %d \r\n",header->CmdInfo.cbCheckCode);
		printf("header->CmdInfo.cbVersion %d \r\n",header->CmdInfo.cbVersion);
		printf("error on DecryptBuffer \r\n");
		return 0;
	}

	self->_needReadTotalSize = header->CmdInfo.wPacketSize - sizeof(CMD_Head);
	self->_receiveSeqNum ++;
	self->_readStep = 1;
	self->_currentReadSize = 0;
	self->mainID = header->CommandInfo.wMainCmdID;
	self->subID = header->CommandInfo.wSubCmdID;

	free(self->_readBuffer);
	self->_readBuffer = (char*)malloc(self->_needReadTotalSize);

	return 1;
}

static void _read_body_ok(CodecData* self,const LuaFunction& onMessage){
	int packageSize = 0;
	char* tmpBuffer = (char*)malloc(self->_needReadTotalSize + 100);
	memcpy(tmpBuffer, self->_readBuffer, self->_needReadTotalSize);
	packageSize = self->_needReadTotalSize;

  const char* package = (const char*)tmpBuffer;
  Data data;
  data.buf = package;
  data.len = packageSize;

	onMessage(data,packageSize,self->mainID,self->subID);
	free(tmpBuffer);

	// read head again
	free(self->_readBuffer);
	self->_readBuffer = (char*)malloc(sizeof(CMD_Head));
	self->_readStep = 0;
	self->_needReadTotalSize = sizeof(CMD_Head);
	self->_currentReadSize = 0;
}

static int netfox_process(lua_State* L){
  CodecData* self = toCodec(L);
  size_t nread;
  const char* buf = lua_tolstring(L,2,&nread);
  LuaFunction onMessage(L,3);
  LuaFunction onError(L,4);

	int end = 0;
	int big = 0;
	int readSize = 0;
	int ok = 0;
	int read_bytes = nread;
	int total_size = 0;
	int headIsOk = 0;
_retry:
	end = self->_currentReadSize + read_bytes;
	big = 0;
	ok = 0;
	if(end >= self->_needReadTotalSize){
		big = end - self->_needReadTotalSize;
		ok = 1;
	}
	readSize = read_bytes - big;
	memcpy(self->_readBuffer + self->_currentReadSize,buf + total_size,readSize);
	total_size += readSize;
	self->_currentReadSize += readSize;

	switch(self->_readStep){
	case 0:
		if(ok){
			headIsOk = _read_head_ok(self);
			if(headIsOk != 1){
				onError();
				return 0;
			}
		}
		break;

	case 1:
		if(ok){
			_read_body_ok(self,onMessage);
		}
		break;
	}

	if(big > 0){
		read_bytes = big;
		goto _retry;
	}

  return 0;
}

static int netfox_createPackage(lua_State* L) {
  size_t size;
  const char* data = lua_tolstring(L,1,&size);
	if(size > 65535)
		printf("the package is to big than unsigned short range %s \r\n",data);

  char* buffer = (char*)malloc(sizeof(CMD_Head) + size + 100);
  CMD_Head* pHeader = (CMD_Head*)buffer;

  char* write_data = (char*)buffer;
  pHeader->CommandInfo.wMainCmdID = 99;
  pHeader->CommandInfo.wSubCmdID = 99;
  pHeader->CmdInfo.cbVersion = SOCKET_VER;
  pHeader->CmdInfo.wPacketSize = sizeof(CMD_Head) + size;
  pHeader->CmdInfo.cbCheckCode = 0x02;

// printf("pre size is %d\r\n",pHeader->CmdInfo.wPacketSize);
 EncryptBuffer((unsigned char*)pHeader, sizeof(CMD_Head));
// printf("encrypt pre size is %d\r\n",pHeader->CmdInfo.wPacketSize);
// DecryptBuffer((unsigned char*)pHeader, sizeof(CMD_Head));
// printf("post size is %d\r\n",pHeader->CmdInfo.wPacketSize);

  if (size > 0)
  {
  	memcpy(&write_data[sizeof(CMD_Head)], data, size);
  }

  int wSendSize = sizeof(CMD_Head) + size;
  lua_pushlstring(L,buffer,wSendSize);
  DecryptBuffer((unsigned char*)pHeader,sizeof(CMD_Head));

  free(buffer);

  return 1;
}

static int Codec_create(lua_State* L)
{
    CodecData** w = (CodecData**)lua_newuserdata(L, sizeof(*w));
    *w = new CodecData();
    CodecData_init(*w);
    luaL_getmetatable(L, CodecMETA);
    lua_setmetatable(L, -2);

    return 1;
}

static int Codec_gc(lua_State* L)
{
    auto w = toCodecp(L);

    printf("finalizing LUA object (%s)\n", CodecMETA);

    if (!*w)
        return 0;

    CodecData_destroy(*w);
    delete *w;
    *w = nullptr; // mark as closed
    return 0;
}

static luaL_Reg methods[] = {
    { "__gc", Codec_gc },
    { NULL, NULL },
};

static luaL_Reg api[] = {
    { "CodecData", Codec_create },
    { "process", netfox_process},
    { "createPackage", netfox_createPackage},
    { NULL, NULL },
};

int luaopen_netfoxpack(lua_State* L)
{
  luaL_newmetatable(L, CodecMETA);
  lua_pushvalue(L, -1);
  lua_setfield(L, -2, "__index");
  luaL_register(L, NULL, methods);
  lua_pop(L, 1);

  // register the net api
  lua_newtable(L);
  luaL_register(L, NULL, api);

  return 1;
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013 rajendrauppal

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <iostream>

#include "Exceptions.h"

using std::cout;
using std::cin;
using std::endl;

#define uint unsigned int
#define cuint const unsigned int

cuint MAX_SIZE = 10;

/*
* Iterative binary search function

* Input: integer array, items, size of the array, size, key to search, key
* Output: returns 0-based index of the integer found, -1 if not found

* Throws InvalidArrayException (defined in BinarySearch.h) in case NULL is passed
* Throws InvalidSizeException (defined in BinarySearch.h) in case size <= 0 OR size > MAX_SIZE
*/
int BinarySearch_Iterative(int * items, cuint size, int key)
{
	if ( !items ) throw InvalidArrayException();
	if ( (size <= 0) || (size > MAX_SIZE) ) throw InvalidSizeException();

	uint start = 0;
	uint end = size - 1;

	while ( start <= end ) {
		uint mid = ( start + end ) >> 1;
		int miditem = items[mid];
		if ( key == miditem ) {
			return mid;
		} else if ( key < miditem ) {
			end = mid - 1;
		} else {
			start = mid + 1;
		}
	}

	return -1;
}

/*
* Recursive binary search function

* Input: integer array, items, start index, end index, key to search, key
* Output: returns 0-based index of the integer found, -1 if not found

* Throws InvalidArrayException (defined in BinarySearch.h) in case NULL is passed
* Throws InvalidSizeException (defined in BinarySearch.h) in case start < 0 OR (end + 1) > MAX_SIZE
*/
int BinarySearch_Recursive(int * items, cuint start, cuint end, int key)
{
	if ( !items ) throw InvalidArrayException();
	if ( (start < 0) || ((end + 1) > MAX_SIZE) ) throw InvalidSizeException();

	if ( start > end ) return -1;

	uint mid = ( start + end ) >> 1;
	int miditem = items[mid];
	if ( key == miditem )
		return mid;
	else if ( key < miditem )
		return BinarySearch_Recursive( items, start, mid - 1, key );
	else
		return BinarySearch_Recursive( items, mid + 1, end, key );
}

void Usage()
{
	cout << "Usage:" << endl;
	cout << "BinarySearch.exe <key>" << endl;
	cout << "Example: BinarySearch.exe" << endl;
}

void PrintArray(int * items, cuint size)
{
	cout << "[ ";
	for (uint i = 0; i < (size - 1); ++i)
		cout << items[i] << ", ";
	cout << items[size - 1] << " ]\n";
}

int compare(const void * first, const void * second)
{
	return ( *(const int*)first - *(const int *)second );
}

void Test_BinarySearch_Iterative(int * items)
{
	// Iterative binary search tests
	for ( uint i = 0; i < MAX_SIZE; ++i ) {
		int key = items[i];
		cout << "Looking for... " << key;
		int found_index = BinarySearch_Iterative( items, MAX_SIZE, key );
		if ( found_index != -1 ) {
			cout << "\tFound " << key << " at index " << found_index << endl;
		} else {
			cout << "\tNot found " << key << endl;
		}
	}
}

void Test_BinarySearch_Recursive(int * items)
{
	// Recursive binary search tests
	for ( uint i = 0; i < MAX_SIZE; ++i ) {
		int key = items[i];
		cout << "Looking for... " << key;
		int found_index = BinarySearch_Recursive( items, 0, MAX_SIZE - 1, key );
		if ( found_index != -1 ) {
			cout << "\tFound " << key << " at index " << found_index << endl;
		} else {
			cout << "\tNot found " << key << endl;
		}
	}
}

int main(int argc, char *argv[])
{
	if ( argc != 1 ) {
		Usage();
		exit(1);
	}

	int * items = new int[MAX_SIZE];
	for ( uint i = 0; i < MAX_SIZE; ++i )
		items[i] = rand() % 100;

	std::qsort(items, MAX_SIZE, sizeof(int), compare);
	PrintArray(items, MAX_SIZE);

	Test_BinarySearch_Iterative(items);
	Test_BinarySearch_Recursive(items);

	cout << "Press Enter to continue..." << endl;
	cin.get();
	return 0;
}
<commit_msg>Fixed potential memory leak<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013 rajendrauppal

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <iostream>

#include "Exceptions.h"

using std::cout;
using std::cin;
using std::endl;

#define uint unsigned int
#define cuint const unsigned int

cuint MAX_SIZE = 10;

/*
* Iterative binary search function

* Input: integer array, items, size of the array, size, key to search, key
* Output: returns 0-based index of the integer found, -1 if not found

* Throws InvalidArrayException (defined in BinarySearch.h) in case NULL is passed
* Throws InvalidSizeException (defined in BinarySearch.h) in case size <= 0 OR size > MAX_SIZE
*/
int BinarySearch_Iterative(int * items, cuint size, int key)
{
	if ( !items ) throw InvalidArrayException();
	if ( (size <= 0) || (size > MAX_SIZE) ) throw InvalidSizeException();

	uint start = 0;
	uint end = size - 1;

	while ( start <= end ) {
		uint mid = ( start + end ) >> 1;
		int miditem = items[mid];
		if ( key == miditem ) {
			return mid;
		} else if ( key < miditem ) {
			end = mid - 1;
		} else {
			start = mid + 1;
		}
	}

	return -1;
}

/*
* Recursive binary search function

* Input: integer array, items, start index, end index, key to search, key
* Output: returns 0-based index of the integer found, -1 if not found

* Throws InvalidArrayException (defined in BinarySearch.h) in case NULL is passed
* Throws InvalidSizeException (defined in BinarySearch.h) in case start < 0 OR (end + 1) > MAX_SIZE
*/
int BinarySearch_Recursive(int * items, cuint start, cuint end, int key)
{
	if ( !items ) throw InvalidArrayException();
	if ( (start < 0) || ((end + 1) > MAX_SIZE) ) throw InvalidSizeException();

	if ( start > end ) return -1;

	uint mid = ( start + end ) >> 1;
	int miditem = items[mid];
	if ( key == miditem )
		return mid;
	else if ( key < miditem )
		return BinarySearch_Recursive( items, start, mid - 1, key );
	else
		return BinarySearch_Recursive( items, mid + 1, end, key );
}

void Usage()
{
	cout << "Usage:" << endl;
	cout << "BinarySearch.exe <key>" << endl;
	cout << "Example: BinarySearch.exe" << endl;
}

void PrintArray(int * items, cuint size)
{
	cout << "[ ";
	for (uint i = 0; i < (size - 1); ++i)
		cout << items[i] << ", ";
	cout << items[size - 1] << " ]\n";
}

int compare(const void * first, const void * second)
{
	return ( *(const int*)first - *(const int *)second );
}

void Test_BinarySearch_Iterative(int * items)
{
	// Iterative binary search tests
	for ( uint i = 0; i < MAX_SIZE; ++i ) {
		int key = items[i];
		cout << "Looking for... " << key;
		int found_index = BinarySearch_Iterative( items, MAX_SIZE, key );
		if ( found_index != -1 ) {
			cout << "\tFound " << key << " at index " << found_index << endl;
		} else {
			cout << "\tNot found " << key << endl;
		}
	}
}

void Test_BinarySearch_Recursive(int * items)
{
	// Recursive binary search tests
	for ( uint i = 0; i < MAX_SIZE; ++i ) {
		int key = items[i];
		cout << "Looking for... " << key;
		int found_index = BinarySearch_Recursive( items, 0, MAX_SIZE - 1, key );
		if ( found_index != -1 ) {
			cout << "\tFound " << key << " at index " << found_index << endl;
		} else {
			cout << "\tNot found " << key << endl;
		}
	}
}

int main(int argc, char *argv[])
{
	if ( argc != 1 ) {
		Usage();
		exit(1);
	}

	int * items = new int[MAX_SIZE];
	for ( uint i = 0; i < MAX_SIZE; ++i )
		items[i] = rand() % 100;

	std::qsort(items, MAX_SIZE, sizeof(int), compare);
	PrintArray(items, MAX_SIZE);

	Test_BinarySearch_Iterative(items);
	Test_BinarySearch_Recursive(items);

	delete [] items;

	cout << "Press Enter to continue..." << endl;
	cin.get();
	return 0;
}
<|endoftext|>


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

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

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

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

=========================================================================*/

// Software Guide : BeginLatex
//
// \index{itk::SpatialObjectTransforms}
// This example describes the different transformations associated with a SpatialObject.
//
// Software Guide : EndLatex

#include "itkSpatialObject.h"

int main( int argc, char *argv[] )
{

// Software Guide : BeginLatex
//
// Like the previous example, we create two SpatialObjects and give
// them the names "First Object"
// and "Second Object" respectively.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::SpatialObject<2>             SpatialObjectType;
  typedef SpatialObjectType::TransformType  TransformType;

  SpatialObjectType::Pointer object1 = SpatialObjectType ::New();
  object1->GetProperty()->SetName("First Object");

  SpatialObjectType::Pointer object2 = SpatialObjectType ::New();
  object2->GetProperty()->SetName("Second Object");
  object1->AddSpatialObject(object2);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// SpatialObject keeps three transformations internally:
// the IndexToObjectTransform, the ObjectToParentTransform and the
// ObjectToWorldTransform. To simplify, the global transformation
// IndexToWorldTransform and its inverse, WorldToIndexTransform, are also kept
// internally.
//
// The two main transformations, IndexToObjectTransform and ObjectToParentTransform, are applied
// successively. ObjectToParentTransform is applied to children.
//
// The IndexToObjectTransform transforms points from the internal data coordinate
// system of the object (typically the indices of the image from which
// the object was defined) to ``physical" space (which accounts
// for the spacing, orientation, and offset of the indices).
//
// The ObjectToParentTransform transforms points from the object-specific
// ``physical" space to the ``physical" space of its parent object.
//
// The ObjectToWorldTransformation transforms points from the global coordinate
// frame. This is useful when the position of the object is known only in the global
// coordinate frame. Note that by setting this transform, the ObjectToParent transform is recomputed.
//
// These transformations use \doxygen{FixedCenterOfRotationAffineTransform}. They are created in
// the constructor of the spatial \doxygen{SpatialObject}
// Software Guide : EndLatex

// Software Guide : BeginLatex
//
// First we define an index scaling factor of 2 for the object2.
// This is done by setting the ScaleComponent of the IndexToObjectTransform.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  double scale[2];
  scale[0]=2;
  scale[1]=2;
  object2->GetIndexToObjectTransform()->SetScaleComponent(scale);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Next, we apply an offset on the ObjectToParentTransform of the child object
// Therefore, object2 is now translated by a vector [4,3] regarding to its
// parent.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  TransformType::OffsetType Object2ToObject1Offset;
  Object2ToObject1Offset[0] = 4;
  Object2ToObject1Offset[1] = 3;
  object2->GetObjectToParentTransform()->SetOffset(Object2ToObject1Offset);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// To make the previous modification on the transformations effective, we should
// invoke the ComputeObjectToWorldTransform() which recomputes all dependent
// transformations.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  object2->ComputeObjectToWorldTransform();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We can now display the ObjectToWorldTransform for both objects.
// One should notice that the \doxygen{FixedCenterOfRotationAffineTransform} derives
// from \doxygen{AffineTransform} and therefore the only valid data for the transformation
// is the Matrix and the Offset. For instance, when we set the ScaleComponent() value
// the internal Matrix is recomputed to reflect the new ScaleComponent.
//
// The \doxygen{FixedCenterOfRotationAffineTransform} performs the following computation
//
//  \begin{equation}
//    X' = MatrixComponent \cdot ( ScaleComponent \cdot X - CenterOfRotationComponent )
//    + CenterOfRotationComponent + OffsetComponent
//    \end{equation}
//
// Therefore the affine matrix and the affine offset are defined as:
//
// \begin{equation}
//  Matrix = MatrixComponent \cdot ScaleComponent
// \end{equation}
// \begin{equation}
// Offset = CenterOfRotation + Offset - MatrixComponent \cdot CenterOfRotationComponent
// \end{equation}
//
// This means that GetScaleComponent() and GetOffsetComponent() as well as the GetMatrixComponent()
// might not be set to the expected value, especially if the transformation results from
// a composition with another transformation since the composition is done using the Matrix and
// the Offset of the affine transformation.
//
// Next, we show the two affine transformations corresponding to the two objects
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "object2 IndexToObject Matrix: " << std::endl;
  std::cout << object2->GetIndexToObjectTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToObject Offset: ";
  std::cout << object2->GetIndexToObjectTransform()->GetOffset() << std::endl;
  std::cout << "object2 IndexToWorld Matrix: " << std::endl;
  std::cout << object2->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToWorld Offset: ";
  std::cout << object2->GetIndexToWorldTransform()->GetOffset() << std::endl;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then, we decide to translate the first object which is the parent of the second
// by a vector [3,3]. This is still done by setting the offset of the ObjectToParentTransform.
// This can also be done by setting the ObjectToWorldTransform because the first object
// does not have any parent and therefore is attached to the world coordinate frame.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  TransformType::OffsetType Object1ToWorldOffset;
  Object1ToWorldOffset[0] = 3;
  Object1ToWorldOffset[1] = 3;
  object1->GetObjectToParentTransform()->SetOffset(Object1ToWorldOffset);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Then we should ComputeObjectToWorldTransform() on the modified object.
// This will propagate the transformation through all the children.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  object1->ComputeObjectToWorldTransform();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
//
// \begin{figure} \center
// \includegraphics[width=\textwidth]{SpatialObjectTransforms.eps}
// \itkcaption[Caption]{Physical positions of the two objects in the world frame. (shapes are
// merely for illustration purposes)}
// \label{fig:SpatialObjectTransforms}
// \end{figure}
//
// Figure~\ref{fig:SpatialObjectTransforms} shows our set of transformations.
//
// Finally, we display the resulting affine transformations.
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "object1 IndexToWorld Matrix: " << std::endl;
  std::cout << object1->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object1 IndexToWorld Offset: ";
  std::cout << object1->GetIndexToWorldTransform()->GetOffset() << std::endl;
  std::cout << "object2 IndexToWorld Matrix: " << std::endl;
  std::cout << object2->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToWorld Offset: ";
  std::cout << object2->GetIndexToWorldTransform()->GetOffset() << std::endl;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The output of this second example looks like the following:
//object2 IndexToObject Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToObject Offset: 0  0
//
//object2 IndexToWorld Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToWorld Offset: 4  3
//
//object1 IndexToWorld Matrix:
//
//1 0
//
//0 1
//
//object1 IndexToWorld Offset: 3  3
//
//object2 IndexToWorld Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToWorld Offset: 7  6
//
// Software Guide : EndLatex
  return 0;
}
<commit_msg>DOC: Latex equations reworked with short symbols.<commit_after>/*=========================================================================

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

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

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

=========================================================================*/

// Software Guide : BeginLatex
//
// \index{itk::SpatialObjectTransforms}
// This example describes the different transformations associated with a SpatialObject.
//
// Software Guide : EndLatex

#include "itkSpatialObject.h"

int main( int argc, char *argv[] )
{

// Software Guide : BeginLatex
//
// Like the previous example, we create two SpatialObjects and give
// them the names "First Object"
// and "Second Object" respectively.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::SpatialObject<2>             SpatialObjectType;
  typedef SpatialObjectType::TransformType  TransformType;

  SpatialObjectType::Pointer object1 = SpatialObjectType ::New();
  object1->GetProperty()->SetName("First Object");

  SpatialObjectType::Pointer object2 = SpatialObjectType ::New();
  object2->GetProperty()->SetName("Second Object");
  object1->AddSpatialObject(object2);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// SpatialObject keeps three transformations internally:
// the IndexToObjectTransform, the ObjectToParentTransform and the
// ObjectToWorldTransform. To simplify, the global transformation
// IndexToWorldTransform and its inverse, WorldToIndexTransform, are also kept
// internally.
//
// The two main transformations, IndexToObjectTransform and ObjectToParentTransform, are applied
// successively. ObjectToParentTransform is applied to children.
//
// The IndexToObjectTransform transforms points from the internal data coordinate
// system of the object (typically the indices of the image from which
// the object was defined) to ``physical" space (which accounts
// for the spacing, orientation, and offset of the indices).
//
// The ObjectToParentTransform transforms points from the object-specific
// ``physical" space to the ``physical" space of its parent object.
//
// The ObjectToWorldTransformation transforms points from the global coordinate
// frame. This is useful when the position of the object is known only in the global
// coordinate frame. Note that by setting this transform, the ObjectToParent transform is recomputed.
//
// These transformations use \doxygen{FixedCenterOfRotationAffineTransform}. They are created in
// the constructor of the spatial \doxygen{SpatialObject}
// Software Guide : EndLatex

// Software Guide : BeginLatex
//
// First we define an index scaling factor of 2 for the object2.
// This is done by setting the ScaleComponent of the IndexToObjectTransform.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  double scale[2];
  scale[0]=2;
  scale[1]=2;
  object2->GetIndexToObjectTransform()->SetScaleComponent(scale);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Next, we apply an offset on the ObjectToParentTransform of the child object
// Therefore, object2 is now translated by a vector [4,3] regarding to its
// parent.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  TransformType::OffsetType Object2ToObject1Offset;
  Object2ToObject1Offset[0] = 4;
  Object2ToObject1Offset[1] = 3;
  object2->GetObjectToParentTransform()->SetOffset(Object2ToObject1Offset);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// To make the previous modification on the transformations effective, we should
// invoke the ComputeObjectToWorldTransform() which recomputes all dependent
// transformations.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  object2->ComputeObjectToWorldTransform();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We can now display the ObjectToWorldTransform for both objects.
// One should notice that the \doxygen{FixedCenterOfRotationAffineTransform} derives
// from \doxygen{AffineTransform} and therefore the only valid data for the transformation
// is the Matrix and the Offset. For instance, when we set the ScaleComponent() value
// the internal Matrix is recomputed to reflect the new ScaleComponent.
//
// The \doxygen{FixedCenterOfRotationAffineTransform} performs the following computation
//
//  \begin{equation}
//  X' = R \cdot \left( S \cdot X - C \right) + C + V
//  \end{equation}
//
// Where $R$ is the rotation matrix, $S$ is a scaling factor, $C$ is the center
// of rotation and $V$ is a translation vector or offset.
// Therefore the affine matrix $M$ and the affine offset $T$ are defined as:
//
// \begin{equation}
// M = R \cdot S
// \end{equation}
// \begin{equation}
// T = C + V - R \cdot C
// \end{equation}
//
// This means that \code{GetScaleComponent()} and \code{GetOffsetComponent()}
// as well as the \code{GetMatrixComponent()} might not be set to the expected
// value, especially if the transformation results from a composition with
// another transformation since the composition is done using the Matrix and
// the Offset of the affine transformation.
//
// Next, we show the two affine transformations corresponding to the two objects
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "object2 IndexToObject Matrix: " << std::endl;
  std::cout << object2->GetIndexToObjectTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToObject Offset: ";
  std::cout << object2->GetIndexToObjectTransform()->GetOffset() << std::endl;
  std::cout << "object2 IndexToWorld Matrix: " << std::endl;
  std::cout << object2->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToWorld Offset: ";
  std::cout << object2->GetIndexToWorldTransform()->GetOffset() << std::endl;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Then, we decide to translate the first object which is the parent of the second
// by a vector [3,3]. This is still done by setting the offset of the ObjectToParentTransform.
// This can also be done by setting the ObjectToWorldTransform because the first object
// does not have any parent and therefore is attached to the world coordinate frame.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  TransformType::OffsetType Object1ToWorldOffset;
  Object1ToWorldOffset[0] = 3;
  Object1ToWorldOffset[1] = 3;
  object1->GetObjectToParentTransform()->SetOffset(Object1ToWorldOffset);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Then we should invoke \code{ComputeObjectToWorldTransform()} on the modified
// object.  This will propagate the transformation through all the children.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  object1->ComputeObjectToWorldTransform();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
//
// \begin{figure} \center
// \includegraphics[width=\textwidth]{SpatialObjectTransforms.eps}
// \itkcaption[SpatialObject Transform Computations]{Physical positions of the
// two objects in the world frame. (shapes are merely for illustration
// purposes)}
// \label{fig:SpatialObjectTransforms}
// \end{figure}
//
// Figure~\ref{fig:SpatialObjectTransforms} shows our set of transformations.
//
// Finally, we display the resulting affine transformations.
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "object1 IndexToWorld Matrix: " << std::endl;
  std::cout << object1->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object1 IndexToWorld Offset: ";
  std::cout << object1->GetIndexToWorldTransform()->GetOffset() << std::endl;
  std::cout << "object2 IndexToWorld Matrix: " << std::endl;
  std::cout << object2->GetIndexToWorldTransform()->GetMatrix() << std::endl;
  std::cout << "object2 IndexToWorld Offset: ";
  std::cout << object2->GetIndexToWorldTransform()->GetOffset() << std::endl;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The output of this second example looks like the following:
//object2 IndexToObject Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToObject Offset: 0  0
//
//object2 IndexToWorld Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToWorld Offset: 4  3
//
//object1 IndexToWorld Matrix:
//
//1 0
//
//0 1
//
//object1 IndexToWorld Offset: 3  3
//
//object2 IndexToWorld Matrix:
//
//2 0
//
//0 2
//
//object2 IndexToWorld Offset: 7  6
//
// Software Guide : EndLatex
  return 0;
}
<|endoftext|>


<commit_before>// Copyright [2016] <Salomão Rodrigues Jacinto>
#ifndef FILA_HPP
#define FILA_HPP

/**
 * @brief  		Implementação de uma estrutura de Fila em C++
 *
 * @tparam  	T			Ponteiro para o início da Fila
 *
 * @param  		fim			Armazena o fim da FIla
 * @param  		tamanho		Armazena o tamanho da Fila
 */
template <typename T>
class Fila {
 private:
	const int MAXFILA = 100;
	T* m_dados;
	int fim;
	int tamanho;

 public:
 	/**
	 * @brief  		Construtor da classe Fila
 	 *
 	 * @details  	Valor do tamanho definido em uma constante como 100
	 */
	Fila() {
		fim = -1;
		m_dados = new T[MAXFILA];
		tamanho = MAXFILA;
	}
	/**
	 * @brief  		Construtor da classe Fila
	 *
	 * @param  		tam		Valor para o tamanho da fila
	 */
	explicit Fila<T>(int tam) {
		fim = -1;
		m_dados = new T[tam];
		tamanho = tam;
	}
	/**
	 * @brief  		Adiciona um dado a fila
	 *
	 * @param  		dado  Dado genérico, podendo ser um inteiro, float...
	 */
	void inclui(T dado) {
		if (filaCheia()) {
			throw "Fila Cheia!";
		} else {
			fim++;
			m_dados[fim] = dado;
		}
	}
	/**
	 * @brief  		Retira o primeiro valor adicionado a fila
	 *
	 * @details  	Retira por ordem de itens colocados na fila, primeiro a
	 * 				ser colocado é o primeiro a sair. A fila é reorganizada para
	 * 				o início do espaço armazenado.
	 */
	T retira() {
		if (filaVazia()) {
			throw "Fila Vazia!";
		} else {
			fim--;
			T dado = m_dados[0];
			for (int i = 0; i <= fim; i++) {
				m_dados[i] = m_dados[i+1];
			}
			return dado;
		}
	}
	/**
	 * @brief      Retira o último valor adicionado a fila
	 */
	T ultimo() {
		if (filaVazia()) {
			throw "Fila Vazia!";
		} else {
			return m_dados[fim];
		}
	}
	/**
	 * @brief      Retorna a posição do último valor
	 */
	int getUltimo() {
		if (filaVazia()) {
			throw "Fila Vazia!";
		} else {
			return fim;
		}
	}
	/**
	 * @brief      Checa se a fila está cheia
	 *
	 * @return     Retorna true caso a fila esteja cheia
	 */
	bool filaCheia() {
		if (fim == tamanho-1) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * @brief      Checa se a fila está vazia }
	 *
	 * @return     Retorna true caso a fila esteja vazia
	 */
	bool filaVazia() {
		if (fim == -1) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * @brief      Inicializa a fila
	 */
	void inicializaFila() {
		fim = -1;
	}
};
#endif  // FILA_HPP
<commit_msg>Delete Fila.hpp<commit_after><|endoftext|>


<commit_before><commit_msg>assets in progress<commit_after><|endoftext|>


<commit_before><commit_msg>Use layout members in render pass creation helper<commit_after><|endoftext|>