#include "ehs/URI.h"

namespace ehs
{
	bool IsAN(const Char_8 c)
	{
		return (c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122);
	}

	Str_8 URI::Encode(const Str_8& in)
	{
		Str_8 result;

		UInt_64 offset = 0;
		for (UInt_64 i = 0; i < in.Size(); ++i)
		{
			if (IsAN(in[i]) || in[i] == '-' || in[i] == '_' || in[i] == '.' || in[i] == '~')
				continue;

			if (i != offset)
				result.Push(&in[offset], i - offset);

			result.Push("%" + Str_8::NumToHex(in[i]));
			offset = i + 1;
		}

		if (offset < in.Size())
			result.Push(&in[offset], in.Size() - offset);

		return result;
	}

	Str_8 URI::Decode(const Str_8& in)
	{
		Str_8 result;

		UInt_64 offset = 0;
		for (UInt_64 i = 0; i < in.Size(); ++i)
		{
			if (in[i] != '%')
				continue;

			if (i != offset)
				result.Push(&in[offset], i - offset);

			result.Push(Str_8::HexToNum<Char_8>({&in[i + 1], 2}));

			i += 2;
			offset = i + 1;
		}

		if (offset < in.Size())
			result.Push(&in[offset], in.Size() - offset);

		return result;
	}
}