Browse Source

String:

* Added casts to fundamental types
* Fixed some allocation issues
Replaced all instances of getPowerTwo32 with slightly more generic 'getPowerTwo' template function
Hash_Table::set now returns a bool
General cleanup
release/0.19
Jessica James 8 years ago
parent
commit
6d92722014
  1. 51
      Jupiter/CString_Imp.h
  2. 44
      Jupiter/Functions.h
  3. 14
      Jupiter/HTTP_Server.cpp
  4. 5
      Jupiter/Hash_Table.h
  5. 19
      Jupiter/Hash_Table_Imp.h
  6. 12
      Jupiter/Readable_String.h
  7. 12
      Jupiter/Socket.cpp
  8. 57
      Jupiter/String_Imp.h

51
Jupiter/CString_Imp.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2015 Jessica James. * Copyright (C) 2013-2016 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -564,7 +564,7 @@ template<typename T> Jupiter::CString_Loose<T>::CString_Loose(Jupiter::CString_L
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(size_t len) : Jupiter::CString_Type<T>::CString_Type(Jupiter::stringConstructorBase) template<typename T> Jupiter::CString_Loose<T>::CString_Loose(size_t len) : Jupiter::CString_Type<T>::CString_Type(Jupiter::stringConstructorBase)
{ {
if (len < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size; if (len < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size;
else Jupiter::CString_Loose<T>::strSize = getPowerTwo32(len + 1); else Jupiter::CString_Loose<T>::strSize = getPowerTwo(len + 1);
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize]; Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base; Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0; *Jupiter::String_Type<T>::str = 0;
@ -611,7 +611,7 @@ template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const T *in) : Jup
else else
{ {
Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in); Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in);
Jupiter::CString_Loose<T>::strSize = getPowerTwo32(Jupiter::String_Type<T>::length + 1); Jupiter::CString_Loose<T>::strSize = getPowerTwo(Jupiter::String_Type<T>::length + 1);
if (Jupiter::CString_Loose<T>::strSize < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size; if (Jupiter::CString_Loose<T>::strSize < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size;
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize]; Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base; Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
@ -685,23 +685,50 @@ template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Rea
template<typename T> bool Jupiter::CString_Loose<T>::setBufferSize(size_t len) template<typename T> bool Jupiter::CString_Loose<T>::setBufferSize(size_t len)
{ {
len = getPowerTwo32(len + 1); size_t offset = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
if (len > Jupiter::CString_Loose<T>::strSize)
++len; // null term
if (len + offset > Jupiter::CString_Loose<T>::strSize)
{ {
T *ptr = new T[len]; if (len > Jupiter::CString_Loose<T>::strSize)
for (unsigned int i = 0; i < Jupiter::String_Type<T>::length; i++) ptr[i] = Jupiter::Shift_String_Type<T>::str[i]; {
ptr[Jupiter::String_Type<T>::length] = 0; // Buffer is not large enough; reallocate
delete[] Jupiter::Shift_String_Type<T>::base; Jupiter::CString_Loose<T>::strSize = getPowerTwo(len);
Jupiter::Shift_String_Type<T>::base = ptr;
T *ptr = new T[Jupiter::CString_Loose<T>::strSize];
for (size_t i = 0; i < Jupiter::String_Type<T>::length; i++)
ptr[i] = Jupiter::String_Type<T>::str[i];
ptr[Jupiter::String_Type<T>::length] = 0;
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = ptr;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
// Buffer has enough space to accomodate; shift data to the left
T *read_itr = Jupiter::String_Type<T>::str;
T *read_end = read_itr + Jupiter::String_Type<T>::length;
T *write_itr = Jupiter::Shift_String_Type<T>::base;
while (read_itr != read_end)
{
*write_itr = *read_itr;
++read_itr;
++write_itr;
}
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base; Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
} }
return false; return false;
} }
template<typename T> bool Jupiter::CString_Loose<T>::setBufferSizeNoCopy(size_t len) template<typename T> bool Jupiter::CString_Loose<T>::setBufferSizeNoCopy(size_t len)
{ {
len = getPowerTwo32(len + 1); len = getPowerTwo(len + 1);
if (len > Jupiter::CString_Loose<T>::strSize) if (len > Jupiter::CString_Loose<T>::strSize)
{ {
Jupiter::String_Type<T>::length = 0; Jupiter::String_Type<T>::length = 0;

44
Jupiter/Functions.h

@ -32,6 +32,7 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include <type_traits>
namespace Jupiter namespace Jupiter
{ {
@ -84,6 +85,14 @@ namespace Jupiter
* @return True if the strings are equal, false otherwise. * @return True if the strings are equal, false otherwise.
*/ */
template<typename T = char> bool streql(const T *str1, const T *str2); template<typename T = char> bool streql(const T *str1, const T *str2);
/**
* @brief Gets the first power of two from in_value
*
* @param in_value Integer to get power of two from
* @return First power of two at least as large as in_value
*/
template<typename T> T getPowerTwo(T in_value);
} }
extern "C" extern "C"
@ -407,6 +416,41 @@ template<typename T> inline bool Jupiter::streql(const T *str1, const T *str2)
return (*str1 == *str2); return (*str1 == *str2);
} }
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4127) /** Conditional is constant; can probably be removed when 'if constexpr' support is added to MSVC */
#pragma warning(disable: 4293) /** shift count negative or too big, undefined behavior */
#endif
template<typename T> T Jupiter::getPowerTwo(T in_value)
{
static_assert(std::is_integral<T>::value, "Integer type required");
--in_value;
in_value |= in_value >> 1;
in_value |= in_value >> 2;
in_value |= in_value >> 4;
if (sizeof(T) >= 2)
in_value |= in_value >> 8;
if (sizeof(T) >= 4)
in_value |= in_value >> 16;
if (sizeof(T) >= 8)
in_value |= in_value >> 32;
if (sizeof(T) >= 16)
in_value |= in_value >> 64;
return ++in_value;
}
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif // __cplusplus #endif // __cplusplus
#endif // _FUNCTIONS_H_HEADER #endif // _FUNCTIONS_H_HEADER

14
Jupiter/HTTP_Server.cpp

@ -92,7 +92,7 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na
if (index == Jupiter::INVALID_INDEX) if (index == Jupiter::INVALID_INDEX)
dir_name = in_name_ref; dir_name = in_name_ref;
else else
dir_name = in_name_ref.substring(0U, index); dir_name = in_name_ref.substring(size_t{ 0 }, index);
in_name_ref.shiftRight(dir_name.size()); in_name_ref.shiftRight(dir_name.size());
Jupiter::HTTP::Server::Directory *directory; Jupiter::HTTP::Server::Directory *directory;
@ -120,7 +120,7 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na
index = in_name_ref.find('/'); index = in_name_ref.find('/');
if (index != Jupiter::INVALID_INDEX) if (index != Jupiter::INVALID_INDEX)
{ {
directory->directories.add(new Jupiter::HTTP::Server::Directory(in_name_ref.substring(0U, index))); directory->directories.add(new Jupiter::HTTP::Server::Directory(in_name_ref.substring(size_t{ 0 }, index)));
directory = directory->directories.get(directories.size() - 1); directory = directory->directories.get(directories.size() - 1);
in_name_ref.shiftRight(index + 1); in_name_ref.shiftRight(index + 1);
goto directory_add_loop; goto directory_add_loop;
@ -165,7 +165,7 @@ bool Jupiter::HTTP::Server::Directory::remove(const Jupiter::ReadableString &pat
if (index == Jupiter::INVALID_INDEX) if (index == Jupiter::INVALID_INDEX)
dir_name = in_name_ref; dir_name = in_name_ref;
else else
dir_name = in_name_ref.substring(0U, index); dir_name = in_name_ref.substring(size_t{ 0 }, index);
in_name_ref.shiftRight(dir_name.size()); in_name_ref.shiftRight(dir_name.size());
Jupiter::HTTP::Server::Directory *directory; Jupiter::HTTP::Server::Directory *directory;
@ -628,9 +628,9 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
else else
{ {
if (session.host == nullptr) if (session.host == nullptr)
content = Jupiter::HTTP::Server::Data::find(query_string.substring(0U, span)); content = Jupiter::HTTP::Server::Data::find(query_string.substring(size_t{ 0 }, span));
else else
content = session.host->find(query_string.substring(0U, span)); content = session.host->find(query_string.substring(size_t{ 0 }, span));
query_string.shiftRight(span + 1); query_string.shiftRight(span + 1);
// decode query_string here // decode query_string here
} }
@ -661,9 +661,9 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
else else
{ {
if (session.host == nullptr) if (session.host == nullptr)
content = Jupiter::HTTP::Server::Data::find(query_string.substring(0U, span)); content = Jupiter::HTTP::Server::Data::find(query_string.substring(size_t{ 0 }, span));
else else
content = session.host->find(query_string.substring(0U, span)); content = session.host->find(query_string.substring(size_t{ 0 }, span));
query_string.shiftRight(span + 1); query_string.shiftRight(span + 1);
// decode query_string here // decode query_string here
} }

5
Jupiter/Hash_Table.h

@ -37,7 +37,7 @@ namespace Jupiter
* @param KeyT Type the table will use for keys; must implement following: operator==, move constructor * @param KeyT Type the table will use for keys; must implement following: operator==, move constructor
* @param ValueT Type the table will use for values * @param ValueT Type the table will use for values
* @param InKeyT Type the table will accept for keys (Default: KeyT) * @param InKeyT Type the table will accept for keys (Default: KeyT)
* @param InValueT Type the table will accept for values (Default: KeyT) * @param InValueT Type the table will accept for values (Default: ValueT)
* @param HashF Function to be used for generating hashes (Default: Fowler-Noll-Vo 1a) * @param HashF Function to be used for generating hashes (Default: Fowler-Noll-Vo 1a)
*/ */
template<typename KeyT, typename ValueT, typename InKeyT = KeyT, typename InValueT = ValueT, size_t(*HashF)(const InKeyT &) = Jupiter::default_hash_function<InKeyT>> class Hash_Table template<typename KeyT, typename ValueT, typename InKeyT = KeyT, typename InValueT = ValueT, size_t(*HashF)(const InKeyT &) = Jupiter::default_hash_function<InKeyT>> class Hash_Table
@ -147,8 +147,9 @@ namespace Jupiter
* *
* @param in_key Key of the entry to set * @param in_key Key of the entry to set
* @param in_value Value of the entry to set * @param in_value Value of the entry to set
* @return True if a new entry was added, false if an entry was overwritten
*/ */
void set(const InKeyT &in_key, const InValueT &in_value); bool set(const InKeyT &in_key, const InValueT &in_value);
/** /**
* @brief Removes an entry from the table and returns its value * @brief Removes an entry from the table and returns its value

19
Jupiter/Hash_Table_Imp.h

@ -32,6 +32,12 @@
* Hash_Table * Hash_Table
*/ */
/** Conditional is constant; can probably be removed when 'if constexpr' support is added to MSVC */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4127)
#endif
template<typename T> inline size_t Jupiter::default_hash_function(const T &in) template<typename T> inline size_t Jupiter::default_hash_function(const T &in)
{ {
if (sizeof(size_t) >= sizeof(uint64_t)) if (sizeof(size_t) >= sizeof(uint64_t))
@ -40,6 +46,11 @@ template<typename T> inline size_t Jupiter::default_hash_function(const T &in)
return static_cast<size_t>(Jupiter::fnv1a_32(in)); return static_cast<size_t>(Jupiter::fnv1a_32(in));
} }
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
#endif
/** Hash_Table::Bucket::Entry */ /** Hash_Table::Bucket::Entry */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
@ -168,11 +179,17 @@ ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::get(const In
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::set(const InKeyT &in_key, const InValueT &in_value) bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::set(const InKeyT &in_key, const InValueT &in_value)
{ {
if (m_buckets[HashF(in_key) % m_buckets_size].set(in_key, in_value)) if (m_buckets[HashF(in_key) % m_buckets_size].set(in_key, in_value))
{
if (++m_length == m_buckets_size) if (++m_length == m_buckets_size)
expand(); expand();
return true;
}
return false;
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>

12
Jupiter/Readable_String.h

@ -430,6 +430,18 @@ namespace Jupiter
inline bool operator>=(const T right)const{ return !operator<(right); } inline bool operator>=(const T right)const{ return !operator<(right); }
/** Conversion operators */ /** Conversion operators */
explicit inline operator bool() { return this->asBool(); }
explicit inline operator short() { return static_cast<short>(this->asInt()); }
explicit inline operator unsigned short() { return static_cast<unsigned short>(this->asUnsignedInt()); }
explicit inline operator int() { return this->asInt(); }
explicit inline operator unsigned int() { return this->asUnsignedInt(); }
explicit inline operator long() { return static_cast<long>(this->asLongLong()); }
explicit inline operator unsigned long() { return static_cast<unsigned long>(this->asLongLong()); }
explicit inline operator long long() { return this->asLongLong(); }
explicit inline operator unsigned long long() { return this->asUnsignedLongLong(); }
explicit inline operator float() { return static_cast<float>(this->asDouble()); }
explicit inline operator double() { return this->asDouble(); }
explicit inline operator long double() { return this->asDouble(); } // NEEDS TO NOT CAST FROM DOUBLE
explicit inline operator std::basic_string<T>() { return std::basic_string<T>(this->ptr(), this->size()); } explicit inline operator std::basic_string<T>() { return std::basic_string<T>(this->ptr(), this->size()); }
private: private:

12
Jupiter/Socket.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2015 Jessica James. * Copyright (C) 2013-2016 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -144,10 +144,16 @@ int Jupiter::Socket::getProtocol() const
bool Jupiter::Socket::connect(addrinfo *info) bool Jupiter::Socket::connect(addrinfo *info)
{ {
#if defined _WIN32 #if defined _WIN32
if (!socketInit && !Jupiter::Socket::init()) return false; if (!socketInit && !Jupiter::Socket::init())
return false;
#endif // _WIN32 #endif // _WIN32
Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || (Jupiter::Socket::data_->sockType != SOCK_RAW && Jupiter::Socket::data_->sockProto != IPPROTO_RAW && ::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)) return false;
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET
|| (Jupiter::Socket::data_->sockType != SOCK_RAW && Jupiter::Socket::data_->sockProto != IPPROTO_RAW && ::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR))
return false;
return true; return true;
} }

57
Jupiter/String_Imp.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2015 Jessica James. * Copyright (C) 2013-2016 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -514,7 +514,7 @@ template<typename T> Jupiter::String_Loose<T>::String_Loose(const T *in)
{ {
Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in); Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in);
Jupiter::String_Loose<T>::strSize = getPowerTwo32(Jupiter::String_Type<T>::length); Jupiter::String_Loose<T>::strSize = getPowerTwo(Jupiter::String_Type<T>::length);
if (Jupiter::String_Loose<T>::strSize < Jupiter::String_Loose<T>::start_size) Jupiter::String_Loose<T>::strSize = Jupiter::String_Loose<T>::start_size; if (Jupiter::String_Loose<T>::strSize < Jupiter::String_Loose<T>::start_size) Jupiter::String_Loose<T>::strSize = Jupiter::String_Loose<T>::start_size;
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::String_Loose<T>::strSize]; Jupiter::Shift_String_Type<T>::base = new T[Jupiter::String_Loose<T>::strSize];
@ -591,12 +591,61 @@ template<typename T> Jupiter::String_Loose<T>::String_Loose(const Jupiter::Reada
template<typename T> bool Jupiter::String_Loose<T>::setBufferSize(size_t len) template<typename T> bool Jupiter::String_Loose<T>::setBufferSize(size_t len)
{ {
return Jupiter::Shift_String_Type<T>::setBufferSize(Jupiter::String_Loose<T>::strSize = getPowerTwo32(len)); size_t offset = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
if (len + offset > Jupiter::String_Loose<T>::strSize)
{
if (len > Jupiter::String_Loose<T>::strSize)
{
// Buffer is not large enough; reallocate
Jupiter::String_Loose<T>::strSize = getPowerTwo(len);
T *ptr = new T[Jupiter::String_Loose<T>::strSize];
for (size_t i = 0; i < Jupiter::String_Type<T>::length; i++)
ptr[i] = Jupiter::String_Type<T>::str[i];
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = ptr;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
// Buffer has enough space to accomodate; shift data to the left
T *read_itr = Jupiter::String_Type<T>::str;
T *read_end = read_itr + Jupiter::String_Type<T>::length;
T *write_itr = Jupiter::Shift_String_Type<T>::base;
while (read_itr != read_end)
{
*write_itr = *read_itr;
++read_itr;
++write_itr;
}
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
return false;
} }
template<typename T> bool Jupiter::String_Loose<T>::setBufferSizeNoCopy(size_t len) template<typename T> bool Jupiter::String_Loose<T>::setBufferSizeNoCopy(size_t len)
{ {
return Jupiter::Shift_String_Type<T>::setBufferSizeNoCopy(Jupiter::String_Loose<T>::strSize = getPowerTwo32(len)); len = getPowerTwo(len);
if (len > Jupiter::String_Loose<T>::strSize)
{
Jupiter::String_Type<T>::length = 0;
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = new T[len];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
Jupiter::String_Type<T>::length = 0;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return false;
} }
// vformat() // vformat()

Loading…
Cancel
Save