Browse Source

Initial Commit

release/0.19
JustinAJ 10 years ago
commit
aa1126569b
  1. 63
      .gitattributes
  2. 156
      .gitignore
  3. 32
      Jupiter.sln
  4. 179
      Jupiter/ArrayList.h
  5. 49
      Jupiter/Base64.cpp
  6. 175
      Jupiter/Base64.h
  7. 235
      Jupiter/Base64C.c
  8. 556
      Jupiter/CString.h
  9. 1203
      Jupiter/CString_Imp.h
  10. 74
      Jupiter/Command.cpp
  11. 100
      Jupiter/Command.h
  12. 276
      Jupiter/DLList.h
  13. 206
      Jupiter/File.cpp
  14. 165
      Jupiter/File.h
  15. 523
      Jupiter/Functions.c
  16. 391
      Jupiter/Functions.h
  17. 581
      Jupiter/INIFile.cpp
  18. 474
      Jupiter/INIFile.h
  19. 8
      Jupiter/IRC.cpp
  20. 54
      Jupiter/IRC.h
  21. 1743
      Jupiter/IRC_Client.cpp
  22. 874
      Jupiter/IRC_Client.h
  23. 708
      Jupiter/IRC_Numerics.h
  24. 13
      Jupiter/IRC_Server.cpp
  25. 32
      Jupiter/IRC_Server.h
  26. 60
      Jupiter/InvalidIndex.h
  27. 18
      Jupiter/Jupiter.cpp
  28. 59
      Jupiter/Jupiter.h
  29. BIN
      Jupiter/Jupiter.rc
  30. 154
      Jupiter/Jupiter.vcxproj
  31. 205
      Jupiter/Jupiter.vcxproj.filters
  32. 77
      Jupiter/List.h
  33. 282
      Jupiter/Plugin.cpp
  34. 306
      Jupiter/Plugin.h
  35. 59
      Jupiter/Queue.cpp
  36. 79
      Jupiter/Queue.h
  37. 130
      Jupiter/Rehash.cpp
  38. 147
      Jupiter/Rehash.h
  39. 216
      Jupiter/SLList.h
  40. 229
      Jupiter/SecureSocket.cpp
  41. 214
      Jupiter/SecureSocket.h
  42. 564
      Jupiter/Socket.cpp
  43. 491
      Jupiter/Socket.h
  44. 258
      Jupiter/String_Type.h
  45. 62
      Jupiter/TCPSocket.cpp
  46. 61
      Jupiter/TCPSocket.h
  47. 54
      Jupiter/Thinker.h
  48. 148
      Jupiter/Timer.cpp
  49. 191
      Jupiter/Timer.h
  50. 22
      Jupiter/UDPSocket.cpp
  51. 43
      Jupiter/UDPSocket.h
  52. 14
      Jupiter/resource.h
  53. BIN
      Release/Jupiter.lib
  54. 51
      Tester/Test.cpp
  55. 87
      Tester/Tester.vcxproj
  56. 27
      Tester/Tester.vcxproj.filters

63
.gitattributes

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

156
.gitignore

@ -0,0 +1,156 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

32
Jupiter.sln

@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Jupiter", "Jupiter\Jupiter.vcxproj", "{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tester", "Tester\Tester.vcxproj", "{0F041791-1047-4C6A-A4C1-814E6957D5EB}"
ProjectSection(ProjectDependencies) = postProject
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8} = {367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}.Debug|Win32.ActiveCfg = Release|Win32
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}.Debug|Win32.Build.0 = Release|Win32
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}.Debug|Win32.Deploy.0 = Release|Win32
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}.Release|Win32.ActiveCfg = Release|Win32
{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}.Release|Win32.Build.0 = Release|Win32
{0F041791-1047-4C6A-A4C1-814E6957D5EB}.Debug|Win32.ActiveCfg = Debug|Win32
{0F041791-1047-4C6A-A4C1-814E6957D5EB}.Debug|Win32.Build.0 = Debug|Win32
{0F041791-1047-4C6A-A4C1-814E6957D5EB}.Release|Win32.ActiveCfg = Release|Win32
{0F041791-1047-4C6A-A4C1-814E6957D5EB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

179
Jupiter/ArrayList.h

@ -0,0 +1,179 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _ARRAYLIST_H_HEADER
#define _ARRAYLIST_H_HEADER
#include "Jupiter.h"
#include "List.h"
/**
* @file ArrayList.h
* @brief Provides an array-based list implementation using the List interface.
*/
namespace Jupiter
{
/**
* @brief Provides an array-based list implementation using the List interface.
*/
template<typename T> class ArrayList : public List<T>
{
public:
/**
* @brief Gets the data at a specified index.
*
* @param index Index of the data to get.
* @return Data stored at the specified index.
*/
T *get(unsigned int index) const;
/**
* @brief Removes the data at a specified index from the list, and returns the removed data.
*
* @param n Index of the node to remove.
* @return Data removed.
*/
T *remove(unsigned int index);
/**
* @brief Adds data to the list at a specified index.
*
* @param data Data to add to the list.
* @param index Position in the list to add the data to.
*/
void add(T *data, unsigned int index);
/**
* @brief Adds data to the end of the list.
*
* @param data Data to add to the list.
*/
void add(T *data);
/**
* @brief Empties the ArrayList of all elements.
*/
void empty();
/**
* @brief Remove and deletes all elements within the ArrayList.
*/
void emptyAndDelete();
/**
* @brief Default constructor for the ArrayList class.
*/
ArrayList();
/**
* @brief Copy constructor for the ArrayList class.
*/
ArrayList(const ArrayList<T> &);
/**
* @brief Destructor for the ArrayList class.
* Note: This does not delete data added to the list.
*/
~ArrayList();
/** Access Operator */
inline T *operator[](size_t index) { return this->get(index); };
/** Private members */
private:
T **data;
unsigned int dataSize;
unsigned int expandArray();
};
}
// Implementation
const unsigned int INIT_SIZE = 8;
template<typename T> unsigned int Jupiter::ArrayList<T>::expandArray()
{
T **tmp = new T *[Jupiter::ArrayList<T>::dataSize * 2];
for (unsigned int i = 0; i < Jupiter::ArrayList<T>::dataSize; i++) tmp[i] = data[i];
delete[] Jupiter::ArrayList<T>::data;
Jupiter::ArrayList<T>::data = tmp;
Jupiter::ArrayList<T>::dataSize *= 2;
return Jupiter::ArrayList<T>::dataSize;
}
template<typename T> Jupiter::ArrayList<T>::ArrayList()
{
Jupiter::ArrayList<T>::dataSize = INIT_SIZE;
Jupiter::ArrayList<T>::data = new T*[Jupiter::ArrayList<T>::dataSize];
Jupiter::List<T>::length = 0;
}
template<typename T> Jupiter::ArrayList<T>::ArrayList(const Jupiter::ArrayList<T> &source)
{
Jupiter::ArrayList<T>::dataSize = source.dataSize;
Jupiter::ArrayList<T>::data = new T*[Jupiter::ArrayList<T>::dataSize];
Jupiter::List<T>::length = source.length;
for (unsigned int i = 0; i < Jupiter::List<T>::length; i++) Jupiter::ArrayList<T>::data[i] = source.data[i];
}
template<typename T> Jupiter::ArrayList<T>::~ArrayList()
{
delete[] Jupiter::ArrayList<T>::data;
}
template<typename T> T *Jupiter::ArrayList<T>::get(unsigned int index) const
{
return Jupiter::ArrayList<T>::data[index];
}
template<typename T> T *Jupiter::ArrayList<T>::remove(unsigned int index)
{
T *r = Jupiter::ArrayList<T>::data[index];
Jupiter::ArrayList<T>::data[index] = nullptr;
for (unsigned int i = index + 1; i < Jupiter::List<T>::length; i++) Jupiter::ArrayList<T>::data[i - 1] = Jupiter::ArrayList<T>::data[i];
Jupiter::List<T>::length--;
return r;
}
template<typename T> void Jupiter::ArrayList<T>::add(T *ndata, unsigned int index)
{
if (Jupiter::List<T>::length == Jupiter::ArrayList<T>::dataSize) Jupiter::ArrayList<T>::expandArray();
for (unsigned int i = Jupiter::List<T>::length; i > index; i--) Jupiter::ArrayList<T>::data[i] = Jupiter::ArrayList<T>::data[i - 1];
Jupiter::ArrayList<T>::data[index] = ndata;
Jupiter::List<T>::length++;
}
template<typename T> void Jupiter::ArrayList<T>::add(T *ndata)
{
Jupiter::ArrayList<T>::add(ndata, Jupiter::List<T>::length);
}
template<typename T> void Jupiter::ArrayList<T>::empty()
{
Jupiter::List<T>::length = 0;
}
template<typename T> void Jupiter::ArrayList<T>::emptyAndDelete()
{
for (unsigned int i = 0; i < Jupiter::List<T>::length; i++) delete Jupiter::ArrayList<T>::data[i];
Jupiter::List<T>::length = 0;
}
#endif // _ARRAYLIST_H_HEADER

49
Jupiter/Base64.cpp

@ -0,0 +1,49 @@
#include "Base64.h"
#include "Functions.h"
unsigned int Jupiter::base64encode(const void *data, size_t dataLength, char *result)
{
return Jupiter_base64encode(data, dataLength, result);
}
unsigned int Jupiter::base64encode(const void *data, size_t dataLength, char *result, size_t resultSize)
{
if (resultSize < (dataLength / 3) * 4 + 5) return 0;
return Jupiter::base64encode(data, dataLength, result);
}
char *Jupiter::base64encode(const void *data, size_t dataLength)
{
size_t resultSize = (dataLength / 3) * 4 + 5;
char *result = new char[resultSize];
Jupiter::base64encode(data, dataLength, result, resultSize);
return result;
}
char *Jupiter::base64encode(const char *str)
{
return Jupiter::base64encode(str, strlen(str));
}
unsigned int Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result)
{
return Jupiter_base64decode2(data, dataLength, result);
}
unsigned int Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize)
{
if (resultSize < Jupiter_minBase64DecodeLength(data, dataLength)) return 0;
return Jupiter::base64decode(data, dataLength, result);
}
char *Jupiter::base64decode(const char *data, size_t dataLength)
{
char *result = new char[Jupiter_minBase64DecodeLength(data, dataLength) + 1];
result[Jupiter_base64decode(data, (unsigned char *)result)] = 0;
return result;
}
char *Jupiter::base64decode(const char *data)
{
return Jupiter::base64decode(data, strlen(data));
}

175
Jupiter/Base64.h

@ -0,0 +1,175 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _BASE64_H_HEADER
#define _BASE64_H_HEADER
#include "Jupiter.h"
/**
* @file Base64.h
* @brief Provides C and C++ functions to encode/decode using base64.
*/
#if defined __cplusplus
#include <cstdint>
namespace Jupiter
{
/**
* @brief Encodes an input buffer into a base64 C-String.
*
* @param data Data to encode.
* @param dataLength Number of bytes to encode.
* @param result Character buffer for output.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int base64encode(const void *data, size_t dataLength, char *result);
/**
* @brief Checks if a buffer is large enough, and if so, encodes an input buffer into a base64 C-String.
*
* @param data Data to encode.
* @param dataLength Number of bytes to encode.
* @param result Character buffer for output.
* @param outputSize Size of the "result" buffer.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int base64encode(const void *data, size_t dataLength, char *result, size_t outputSize);
/**
* @brief Encodes an input C-String into a base64 C-String.
*
* @param data String to encode.
* @param dataLength Number of bytes to encode.
* @return Buffer containing the encoded base64 string.
*/
JUPITER_API char *base64encode(const void *data, size_t dataLength);
/**
* @brief Encodes an input C-String into a base64 C-String.
*
* @param data String to encode.
* @return Buffer containing the encoded base64 string.
*/
JUPITER_API char *base64encode(const char *data);
/**
* @brief Decodes an input base64 C-String into a data buffer.
*
* @param str Data to decode.
* @param result Data buffer for output.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize);
/**
* @brief Decodes an input base64 character string into a C-String buffer.
*
* @param data Data to decode.
* @param dataLength Length of the data to decode.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int base64decode(const char *data, size_t dataLength, unsigned char *result);
/**
* @brief Decodes an input base64 character string into a C-String buffer.
*
* @param data Data to decode.
* @param dataLength Length of the data to decode.
* @return C-String containing the decoded buffer.
*/
JUPITER_API char *base64decode(const char *data, size_t dataLength);
/**
* @brief Decodes an input base64 C-String into a C-String buffer.
*
* @param str Data to decode.
* @return C-String containing the decoded buffer.
*/
JUPITER_API char *base64decode(const char *str);
}
extern "C"
{
#else
#include <stdbool.h>
#include <stdint.h>
#endif // __cplusplus
/**
* @brief Encodes an input buffer into a base64 C-String.
*
* @param data Data to encode.
* @param dataLength Number of bytes to encode.
* @param result Character buffer for output.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int Jupiter_base64encode(const void *data, size_t dataLength, char *result);
/**
* @brief Calculates the minimum buffer size to decode a specified base64 string.
* Note: This does NOT include the neccessary space for a null-terminator.
*
* @param data Data which would be decoded.
* @param inLen Length of the input string.
* @return Minimum number of bytes to fit the decoded buffer.
*/
JUPITER_API unsigned int Jupiter_minBase64DecodeLength(const char *data, size_t inLen);
/**
* @brief Checks if a buffer is a valid base64 string.
*
* @param str C-String containing data to check.
* @return True if the input buffer is a valid base64 string, false otherwise.
*/
JUPITER_API bool Jupiter_isBase64(const char *str);
/**
* @brief Checks if a buffer is a valid base64 string.
*
* @param data Buffer to check.
* @param dataLength Length of the data to check.
* @return True if the input buffer is a valid base64 string, false otherwise.
*/
JUPITER_API bool Jupiter_isBase642(const char *data, size_t dataLength);
/**
* @brief Decodes an input base64 C-String into a data buffer.
*
* @param str C-String containing data to decode.
* @param result Data buffer for output.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int Jupiter_base64decode(const char *str, unsigned char *result);
/**
* @brief Decodes an input base64 string into a data buffer.
*
* @param data Data to decode.
* @param dataLength Length of the base64 string.
* @param result Data buffer for output.
* @return Number of bytes written to the output buffer.
*/
JUPITER_API unsigned int Jupiter_base64decode2(const char *data, size_t dataLength, unsigned char *result);
#if defined __cplusplus
}
#endif
#endif _BASE64_H_HEADER

235
Jupiter/Base64C.c

@ -0,0 +1,235 @@
#include "Base64.h"
unsigned int Jupiter_base64encode(const void *data_buf, size_t dataLength, char *result)
{
const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const uint8_t *data = (const uint8_t *)data_buf;
char *resultPtr = result;
uint32_t n = 0;
int padCount = dataLength % 3;
uint8_t n0, n1, n2, n3;
/* increment over the length of the string, three characters at a time */
for (size_t x = 0; x < dataLength; x += 3)
{
/* these three 8-bit (ASCII) characters become one 24-bit number */
n = data[x] << 16;
if ((x + 1) < dataLength) n += data[x + 1] << 8;
if ((x + 2) < dataLength) n += data[x + 2];
/* this 24-bit number gets separated into four 6-bit numbers */
n0 = (uint8_t)(n >> 18) & 63;
n1 = (uint8_t)(n >> 12) & 63;
n2 = (uint8_t)(n >> 6) & 63;
n3 = (uint8_t)n & 63;
/*
* if we have one byte available, then its encoding is spread
* out over two characters
*/
*resultPtr = base64chars[n0];
resultPtr++;
*resultPtr = base64chars[n1];
resultPtr++;
/*
* if we have only two bytes available, then their encoding is
* spread out over three chars
*/
if ((x + 1) < dataLength)
{
*resultPtr = base64chars[n2];
resultPtr++;
}
/*
* if we have all three bytes available, then their encoding is spread
* out over four characters
*/
if ((x + 2) < dataLength)
{
*resultPtr = base64chars[n3];
resultPtr++;
}
}
/*
* create and add padding that is required if we did not have a multiple of 3
* number of characters available
*/
if (padCount > 0)
{
while (padCount < 3)
{
*resultPtr = '=';
resultPtr++;
padCount++;
}
}
*resultPtr = 0;
return resultPtr - result;
}
static const unsigned char Jupiter_base64DecodeTable[256] = {
66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, 66, 66, 66, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66
};
unsigned int Jupiter_minBase64DecodeLength(const char *data, size_t inLen)
{
if (inLen == 0) return 0;
data += inLen - 1;
if (*data == '=')
{
data--;
if (*data == '=') return inLen / 4 * 3 - 2;
return inLen / 4 * 3 - 1;
}
return inLen / 4 * 3;
}
bool Jupiter_isBase64(const char *in)
{
while (*in != 0)
{
switch (Jupiter_base64DecodeTable[*in++])
{
case 66:
return false;
default:
break;
}
}
return true;
}
bool Jupiter_isBase642(const char *in, size_t inLen)
{
if (inLen % 4 != 0)
{
return false;
}
const char *end = in + inLen;
while (in != end)
{
switch (Jupiter_base64DecodeTable[*in++])
{
case 66:
return false;
default:
break;
}
}
return true;
}
/** Disable warning 4244 */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4244) // conversion from 'size_t' to 'unsigned char', possible loss of data
#endif
unsigned int Jupiter_base64decode(const char *in, unsigned char *out)
{
unsigned char *outOrig = out;
size_t buf = 1;
while (*in != 0)
{
unsigned char c = Jupiter_base64DecodeTable[*in++];
switch (c)
{
case 66:
/* invalid input */
return 0;
case 65:
/* pad character, end of data */
goto endLoop;
case 64:
break;
default:
buf = buf << 6 | c;
/* If the buffer is full, split it into bytes */
if (buf & 0x1000000)
{
*out++ = buf >> 16;
*out++ = buf >> 8;
*out++ = buf;
buf = 1;
}
break;
}
}
endLoop:
if (buf & 0x40000)
{
*out++ = buf >> 10;
*out++ = buf >> 2;
}
else if (buf & 0x1000) *out++ = buf >> 4;
return out - outOrig;
}
unsigned int Jupiter_base64decode2(const char *in, size_t inLen, unsigned char *out)
{
unsigned char *outOrig = out;
const char *end = in + inLen;
size_t buf = 1;
while (in != end)
{
unsigned char c = Jupiter_base64DecodeTable[*in++];
switch (c)
{
case 66:
/* invalid input */
return false;
case 65:
/* pad character, end of data */
in = end;
case 64:
break;
default:
buf = buf << 6 | c;
/* If the buffer is full, split it into bytes */
if (buf & 0x1000000)
{
*out++ = buf >> 16;
*out++ = buf >> 8;
*out++ = buf;
buf = 1;
}
break;
}
}
if (buf & 0x40000)
{
*out++ = buf >> 10;
*out++ = buf >> 2;
}
else if (buf & 0x1000) *out++ = buf >> 4;
return out - outOrig;
}
/** Re-enable warning */
#if defined _MSC_VER
#pragma warning(pop)
#endif

556
Jupiter/CString.h

@ -0,0 +1,556 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _CSTRING_H_HEADER
#define _CSTRING_H_HEADER
#include <stdarg.h>
#include "String_Type.h"
/**
* @file CString.h
* @brief Defines the base CString_Type, as well as a series of CString types.
* Note: Functions which take "case" or "wildcards" into consideration will only function
* for types char and wchar_t; inputs with other types will simply return false.
*/
namespace Jupiter
{
/**
* @brief Provides the basis for CString classes by providing the implementations for many abstract methods in String_Type.
* Note: This is an abstract type.
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Type : public String_Type<T>
{
public:
/**
* @brief Returns the C-Style string behind the CString.
*
* @return C-Style string that the CString represents.
*/
const T *c_str() const;
/**
* @brief Returns the number of elements in the CString.
*
* @return Number of elements in the string.
*/
size_t size() const;
/**
* @brief Compares another string against the CString.
*
* @param in String to compare against.
* @return 0 if the strings are equal, negative if the first mismatched character is greater in the CString, or positive if it's less.
*/
int compare(const String_Type<T> &in) const;
int compare(const std::basic_string<T> &in) const;
int compare(const T *in) const;
int compare(const T in) const;
/**
* @brief Checks if the strings are equal.
* Note: Case sensitive.
*
* @param in String to compare against.
* @return True if the contents of the strings are equal, false otherwise.
*/
bool equals(const String_Type<T> &in) const;
bool equals(const std::basic_string<T> &in) const;
bool equals(const T *in) const;
bool equals(const T in) const;
/**
* @brief Checks if the strings are equal.
* Note: Case insensitive. Returns false for any type other than char and wchar_t.
*
* @param in String to compare against.
* @return True if the contents of the strings are equal, false otherwise.
*/
bool equalsi(const String_Type<T> &in) const;
bool equalsi(const std::basic_string<T> &in) const;
bool equalsi(const T *in) const;
bool equalsi(const T in) const;
/**
* @brief Checks if the CString matches a wildcard format.
* Note: Case sensitive. Returns false for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @return True if the CString matches the wildcard format, false otherwise.
*/
bool match(const String_Type<T> &format) const;
bool match(const std::basic_string<T> &format) const;
bool match(const T *format) const;
/**
* @brief Checks if the CString matches a wildcard format.
* Note: Case insensitive. Returns false for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @return True if the CString matches the wildcard format, false otherwise.
*/
bool matchi(const String_Type<T> &format) const;
bool matchi(const std::basic_string<T> &format) const;
bool matchi(const T *format) const;
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
virtual size_t format(const String_Type<T> &format, ...);
virtual size_t format(const std::basic_string<T> &format, ...);
virtual size_t format(const T *format, ...);
virtual size_t vformat(const T *format, va_list args) = 0;
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
virtual size_t aformat(const String_Type<T> &format, ...);
virtual size_t aformat(const std::basic_string<T> &format, ...);
virtual size_t aformat(const T *format, ...);
virtual size_t avformat(const T *format, va_list args) = 0;
/**
* @brief Counts the number of token deliminated words.
*
* @param whitespace A string of tokens used to deliminate words.
* @return Number of words found.
*/
unsigned int wordCount(const T *whitespace) const;
/**
* @brief Truncates the string by a specified number of elements.
*
* @param n Number of elements to remove from the tail.
* @return New size of the CString.
*/
size_t truncate(size_t n);
/**
* @brief Fetches an element from the string.
*
* @param index Index of the element to return.
* @return The element located at the specified index.
*/
T &get(size_t index) const;
/**
* @brief Shifts the string pointer to the left.
*
* @param length Number of elements to shift
* @return Number of elements shifted to the left.
*/
size_t shiftLeft(size_t length);
/**
* @brief Shifts the string pointer to the right.
*
* @param length Number of elements to shift
* @return Number of elements shifted.
*/
size_t shiftRight(size_t length);
/**
* @brief Removes the first instance of an element from the string.
*
* @param value Value of the element to remove.
* @return True if an element was removed, false otherwise.
*/
bool remove(T &value);
/**
* @brief Checks if the string contains an element with the specified value.
*
* @param value Value of the element to search for.
* @return True if a match is found, false otherwise.
*/
bool contains(const T &value);
/** Access Operator */
inline T &operator[](size_t pos) { return Jupiter::CString_Type<T>::curr[pos]; };
/** Assignment Operators */
inline CString_Type<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T right) { this->set(right); return *this; };
protected:
T *base; /** Base pointer for the underlying C-style string */
T *curr; /** Active pointer for the underlying C-style string */
size_t strLen; /** Length of underlying C-style string */
};
/**
* @brief Provides a "strict" CString implementation that's more optimized for minimal memory usage.
* Note: This recreates the underlying C-style string with every concatenation.
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Strict : public CString_Type<T>
{
public:
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param args Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t vformat(const T *format, va_list args);
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param args Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t avformat(const T *format, va_list args);
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return String containing the new format.
*/
static CString_Strict Format(const T *format, ...);
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> substring(size_t pos, size_t length) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> getWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
*
* @param in C-Style string to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> gotoWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Copies the data from the input string to the CString.
*
* @param in String containing the data to be copied.
* @return New size of the CString.
*/
size_t set(const String_Type<T> &in);
size_t set(const std::basic_string<T> &in);
size_t set(const T *in);
size_t set(const T in);
/**
* @brief Sets the string buffer.
* Note: This class will free the buffer for you when it's done.
*
* @param in New buffer to be used.
* @return The length of the string.
*/
size_t setString(T *in);
/**
* @brief Sets the string buffer.
* Note: This class will free the buffer for you when it's done. DO NOT DELETE THE INPUT BUFFER.
* Note: This method is unique to the CString_Strict template class, and does not appear in CString_Loose.
*
* @param in New buffer to be used.
* @param size At least the number of characters in the buffer, not including the null-terminator.
* @return The length of the string.
*/
size_t setString(T *in, size_t size);
/**
* @brief Copies the data from the input string and concatenates it to the end of CString.
*
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
size_t concat(const String_Type<T> &in);
size_t concat(const std::basic_string<T> &in);
size_t concat(const T *in);
size_t concat(const T in);
/** Default Constructor */
CString_Strict();
/** Copy Constructors */
CString_Strict(const CString_Strict &in);
CString_Strict(const String_Type<T> &in);
CString_Strict(const std::basic_string<T> &in);
CString_Strict(const T *in);
CString_Strict(const T in);
/** Destructor */
virtual ~CString_Strict();
/** Assignment Operators */
inline CString_Strict<T> &operator=(const CString_Strict<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const T right) { this->set(right); return *this; };
};
/**
* @brief Provides a "loose" CString implementation that's more optimized for repeated concatenations.
* Note: The underlying C-style string will always have a size which is a power of 2, but no fewer than 8 elements.
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Loose : public CString_Type<T>
{
public:
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t vformat(const T *format, va_list args);
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t avformat(const T *format, va_list args);
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return String containing the new format.
*/
static CString_Loose<T> Format(const T *format, ...);
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> substring(size_t pos, size_t length) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> getWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
* Useful when the input string's type isn't known.
*
* @param in String to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
* Useful when the input string's type isn't known.
*
* @param in C-Style string to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> gotoWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Copies the data from the input string to the CString.
*
* @param in String containing the data to be copied.
* @return New size of the CString.
*/
size_t set(const CString_Loose &in);
size_t set(const String_Type<T> &in);
size_t set(const std::basic_string<T> &in);
size_t set(const T *in);
size_t set(const T in);
/**
* @brief Copies the data from the input string and concatenats it to the end of CString.
*
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
size_t concat(const String_Type<T> &in);
size_t concat(const std::basic_string<T> &in);
size_t concat(const T *in);
size_t concat(const T in);
/** Default constructor */
CString_Loose();
/** Copy Constructors */
CString_Loose(const CString_Loose &in);
CString_Loose(const String_Type<T> &in);
CString_Loose(const std::basic_string<T> &in);
CString_Loose(const T *in);
CString_Loose(const T in);
/** Destructor */
virtual ~CString_Loose();
static const size_t start_size = 8; /** Starting size for loose CStrings. */
/** Assignment Operators */
inline CString_Loose<T> &operator=(const CString_Loose<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const T right) { this->set(right); return *this; };
protected:
size_t strSize; /** Size of underlying C-string buffer */
};
/** Definition of a Loose CString. */
typedef CString_Loose<char> CStringL;
/** Definition of a Loose Wide CString */
typedef CString_Loose<wchar_t> WCStringL;
/** Definition of a Strict CString. */
typedef CString_Strict<char> CStringS;
/** Definition of a Strict Wide CString */
typedef CString_Strict<wchar_t> WCStringS;
/** Definition of a CString. */
typedef CStringL CString;
/** Definition of a Wide CString */
typedef WCStringL WCString;
/** Generic CString Type */
typedef CString_Type<char> CStringType;
/** Generic Wide CString Type */
typedef CString_Type<wchar_t> WCStringType;
/** Empty String constants */
static const Jupiter::CStringS emptyCStringS;
static const Jupiter::CStringS emptyCStringL;
static const Jupiter::CStringS &emptyCString = emptyCStringS;
static const Jupiter::CStringS &emptyString = emptyCString;
}
/** Implementation for CString_Type, CString_Strict, and CString_Loose. Very scary. */
#include "CString_IMP.h"
#endif // _CSTRING_H_HEADER

1203
Jupiter/CString_Imp.h

File diff suppressed because it is too large

74
Jupiter/Command.cpp

@ -0,0 +1,74 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <cstring>
#include "ArrayList.h"
#include "Functions.h"
#include "Command.h"
struct Jupiter::Command::Data
{
public:
Jupiter::ArrayList<Jupiter::CString_Strict<char>> triggers;
};
Jupiter::Command::Command()
{
Jupiter::Command::data_ = new Jupiter::Command::Data();
}
Jupiter::Command::Command(const Command &command)
{
Jupiter::Command::data_ = new Jupiter::Command::Data();
Jupiter::CStringS *trigger;
for (int i = command.data_->triggers.size() - 1; i >= 0; i--)
{
trigger = new Jupiter::CStringS(*command.data_->triggers.get(i));
Jupiter::Command::data_->triggers.add(trigger);
}
}
Jupiter::Command::~Command()
{
for (int i = Jupiter::Command::data_->triggers.size() - 1; i >= 0; i--) delete Jupiter::Command::data_->triggers.remove(i);
delete Jupiter::Command::data_;
}
// Command Functions
void Jupiter::Command::addTrigger(const char *trigger)
{
Jupiter::CStringS *aTrigger = new Jupiter::CStringS(trigger);
Jupiter::Command::data_->triggers.add(aTrigger);
}
const char *Jupiter::Command::getTrigger(short index) const
{
return Jupiter::Command::data_->triggers.get(index)->c_str();
}
unsigned int Jupiter::Command::getTriggerCount() const
{
return Jupiter::Command::data_->triggers.size();
}
bool Jupiter::Command::matches(const char *trigger) const
{
unsigned int size = Jupiter::Command::data_->triggers.size();
for (unsigned int i = 0; i < size; i++) if (Jupiter::Command::data_->triggers.get(i)->equalsi(trigger)) return true;
return false;
}

100
Jupiter/Command.h

@ -0,0 +1,100 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _COMMAND_H_HEADER
#define _COMMAND_H_HEADER
/**
* @file Command.h
* @brief Provides an extendable command system.
*/
#include "Jupiter.h"
#include "ArrayList.h"
#include "CString.h"
namespace Jupiter
{
/**
* @brief Provides the basis of a command system.
*/
class JUPITER_API Command
{
public:
/**
* @brief Adds a trigger to the command.
*
* @param trigger Trigger to add to the command.
*/
void addTrigger(const char *trigger);
/**
* @brief Fetches a command's specified trigger.
*
* @param index Index of the trigger to return.
* @return Trigger of the command at the specified index.
*/
const char *getTrigger(short index = 0) const;
/**
* @brief Returns the number of triggers accepted by the command.
*
* @return Number of triggers the command accepts.
*/
unsigned int getTriggerCount() const;
/**
* @brief Checks if a specified trigger matches one of the stored triggers.
* Note: Case insensitive.
*
* @param trigger Trigger to check against the trigger list.
* @return True if a match was found, false otherwise.
*/
bool matches(const char *trigger) const;
/**
* @brief Returns a brief explanation and syntax description about a command.
*
* @return Brief description of command and syntax.
*/
virtual const char *getHelp() = 0;
/**
* @brief Default constructor for command class.
*/
Command();
/**
* @brief Copy constructor for command class.
*/
Command(const Command &command);
/**
* @brief destructor for command class.
*/
virtual ~Command();
/** Private members */
private:
struct Data;
Data *data_;
};
}
#endif // _COMMAND_H_HEADER

276
Jupiter/DLList.h

@ -0,0 +1,276 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _DLLIST_H_HEADER
#define _DLLIST_H_HEADER
#include "Jupiter.h"
#include "List.h"
/**
* @file DLList.h
* @brief Provides a generic Doubly Linked List implementation using the List interface.
*/
namespace Jupiter
{
/**
* @brief Provides a Doubly Linked List implementation using the List interface.
*/
template<typename T> class DLList : public List<T>
{
public:
/**
* @brief Stores a pointer to data, and a pointer to the next node in the list.
*/
struct Node
{
Node *next;
Node *previous;
T *data;
};
/**
* @brief Returns the n'th Node in the list.
*
* @param n Index of the node to return.
* @return n'th Node in the list.
*/
Node *getNode(unsigned int n) const;
/**
* @brief Gets the data at a specified index.
*
* @param index Index of the data to get.
* @return Data stored at the specified index.
*/
T *get(unsigned int index) const;
/**
* @brief Removes the n'th Node in the list, and returns its contents.
*
* @param n Index of the node to remove.
* @return Contents of the node removed.
*/
T *remove(unsigned int n);
/**
* @brief Removes a node from the list.
*
* @param data Node to remove.
* @return Contents of the node removed.
*/
T *remove(Node *data);
/**
* @brief Adds data to the list at a specified index.
*
* @param data Data to add to the list.
* @param index Position in the list to add the data to.
*/
void add(T *data, unsigned int index);
/**
* @brief Adds data to the end of the list.
*
* @param data Data to add to the list.
*/
void add(T *data);
/**
* @brief Default constructor for the DLList class.
*/
DLList();
/**
* @brief Copy constructor for the DLList class.
*/
DLList(const DLList<T> &);
/**
* @brief Destructor for the DLList class.
* Note: This does not delete data added to the list.
*/
~DLList();
/** Private members */
private:
Node *head;
Node *end;
};
}
// Implementation
template<typename T> Jupiter::DLList<T>::DLList()
{
Jupiter::DLList<T>::head = nullptr;
Jupiter::DLList<T>::end = nullptr;
Jupiter::List<T>::length = 0;
}
template<typename T> Jupiter::DLList<T>::DLList(const Jupiter::DLList<T> &source)
{
Jupiter::List<T>::length = source.length;
if (Jupiter::List<T>::length == 0)
{
Jupiter::DLList<T>::head = nullptr;
Jupiter::DLList<T>::end = nullptr;
}
else if (Jupiter::List<T>::length == 1)
{
Jupiter::DLList<T>::Node *n = new Jupiter::DLList<T>::Node;
n->data = source.getNode(0)->data;
Jupiter::DLList<T>::head = n;
Jupiter::DLList<T>::end = n;
}
else
{
Jupiter::DLList<T>::Node *sourceNode = source.getNode(0);
Jupiter::DLList<T>::Node *n = new Jupiter::DLList<T>::Node;
n->data = sourceNode->data;
Jupiter::DLList<T>::head = n;
sourceNode = sourceNode->next;
while (sourceNode->next != nullptr)
{
n->next = new Jupiter::DLList<T>::Node;
n = n->next;
n->data = sourceNode->data;
sourceNode = sourceNode->next;
}
n->next = new Jupiter::DLList<T>::Node;
n = n->next;
n->data = sourceNode->data;
Jupiter::DLList<T>::end = n;
}
}
template<typename T> Jupiter::DLList<T>::~DLList()
{
Jupiter::DLList<T>::Node *p;
Jupiter::DLList<T>::Node *c = Jupiter::DLList<T>::head;
while (c != nullptr)
{
p = c;
c = c->next;
delete p;
}
}
template<typename T> typename Jupiter::DLList<T>::Node *Jupiter::DLList<T>::getNode(unsigned int index) const
{
Jupiter::DLList<T>::Node *r;
if (index * 2 < Jupiter::List<T>::length)
{
r = Jupiter::DLList<T>::head;
for (unsigned int i = 0; i < index; i++) r = r->next;
return r;
}
r = Jupiter::DLList<T>::end;
for (unsigned int i = Jupiter::List<T>::length - 1; i > index; i--) r = r->previous;
return r;
}
template<typename T> T *Jupiter::DLList<T>::get(unsigned int index) const
{
return Jupiter::DLList<T>::getNode(index)->data;
}
template<typename T> T *Jupiter::DLList<T>::remove(unsigned int index)
{
return Jupiter::DLList<T>::remove(Jupiter::DLList<T>::getNode(index));
}
template<typename T> T *Jupiter::DLList<T>::remove(Node *data)
{
if (Jupiter::DLList<T>::head == data)
{
Jupiter::DLList<T>::head = data->next;
if (data->next != nullptr) data->next->previous = data->previous;
else Jupiter::DLList<T>::end = nullptr;
}
else if (Jupiter::DLList<T>::end == data)
{
Jupiter::DLList<T>::end = data->previous;
Jupiter::DLList<T>::end->next = nullptr;
}
else
{
data->next->previous = data->previous;
data->previous->next = data->next;
}
T *r = data->data;
delete data;
Jupiter::List<T>::length--;
return r;
}
template<typename T> void Jupiter::DLList<T>::add(T *data, unsigned int index)
{
Jupiter::DLList<T>::Node *node = new Jupiter::DLList<T>::Node();
node->data = data;
if (index == 0)
{
node->next = Jupiter::DLList<T>::head;
Jupiter::DLList<T>::head->previous = node;
Jupiter::DLList<T>::head = node;
node->previous = nullptr;
}
else if (index == Jupiter::List<T>::length)
{
node->previous = Jupiter::DLList<T>::end;
Jupiter::DLList<T>::end->next = node;
Jupiter::DLList<T>::end = node;
node->next = nullptr;
}
else
{
Jupiter::DLList<T>::Node *n = Jupiter::DLList<T>::getNode(index);
node->next = n;
node->previous = n->previous;
node->previous->next = node;
n->previous = node;
}
Jupiter::List<T>::length++;
}
template<typename T> void Jupiter::DLList<T>::add(T *data)
{
Jupiter::DLList<T>::Node *n = new Jupiter::DLList<T>::Node();
n->data = data;
n->next = nullptr;
if (Jupiter::List<T>::length == 0)
{
Jupiter::DLList<T>::head = n;
Jupiter::DLList<T>::end = n;
n->previous = nullptr;
}
else
{
n->previous = Jupiter::DLList<T>::end;
Jupiter::DLList<T>::end->next = n;
Jupiter::DLList<T>::end = n;
}
Jupiter::List<T>::length++;
}
#endif // _DLLIST_H_HEADER

206
Jupiter/File.cpp

@ -0,0 +1,206 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <sys/stat.h>
#include "File.h"
/**
* TODO:
* Upon writing Jupiter::String, port Jupiter::File to use Jupiter::String isntead of Jupiter::CString.
* Instead of an array of String, consider an ArrayList to remove the cost of constant construction/destruction when expanding.
*/
#if defined _WIN32
#define stat64 _stat64
#endif
int64_t getFileSize(const char *file)
{
struct stat64 data;
if (stat64(file, &data) == 0) return data.st_size;
return -1;
}
const size_t defaultBufferSize = 8192;
template class JUPITER_API Jupiter::CString_Strict<char>;
struct JUPITER_API Jupiter::File::Data
{
Jupiter::CStringS fileName;
size_t lineCount;
Jupiter::CStringS *lines;
Data();
Data(const Data &data);
~Data();
};
Jupiter::File::Data::Data()
{
Jupiter::File::Data::lineCount = 0;
Jupiter::File::Data::lines = nullptr;
}
Jupiter::File::Data::Data(const Jupiter::File::Data &data)
{
Jupiter::File::Data::fileName = data.fileName;
if ((Jupiter::File::Data::lineCount = data.lineCount) != 0)
{
Jupiter::File::Data::lines = new Jupiter::CStringS[Jupiter::File::Data::lineCount];
for (unsigned int i = 0; i != Jupiter::File::Data::lineCount; i++) Jupiter::File::Data::lines[i] = data.lines[i];
}
else Jupiter::File::Data::lines = nullptr;
}
Jupiter::File::Data::~Data()
{
if (Jupiter::File::Data::lines != nullptr) delete[] Jupiter::File::Data::lines;
}
Jupiter::File::File()
{
Jupiter::File::data_ = new Jupiter::File::Data();
}
Jupiter::File::File(const File &file)
{
Jupiter::File::data_ = new Jupiter::File::Data(*file.data_);
}
Jupiter::File::~File()
{
delete Jupiter::File::data_;
}
unsigned int Jupiter::File::getLineCount() const
{
return Jupiter::File::data_->lineCount;
}
const Jupiter::StringType &Jupiter::File::getLine(unsigned int line) const
{
return Jupiter::File::data_->lines[line];
}
const Jupiter::StringType &Jupiter::File::getFileName() const
{
return Jupiter::File::data_->fileName;
}
bool Jupiter::File::addData(const Jupiter::StringType &data)
{
if (Jupiter::File::data_->lineCount == 0)
{
if ((Jupiter::File::data_->lineCount = data.wordCount(ENDL)) != 0)
{
Jupiter::File::data_->lines = new Jupiter::CStringS[Jupiter::File::data_->lineCount];
for (unsigned int i = Jupiter::File::data_->lineCount - 1; i != 0; i--) Jupiter::File::data_->lines[i] = Jupiter::CStringS::getWord(data, i, ENDL);
Jupiter::File::data_->lines[0] = Jupiter::CStringS::getWord(data, 0, ENDL);
return true;
}
return false;
}
else
{
unsigned int wc = data.wordCount(ENDL);
if (wc != 0)
{
Jupiter::CStringS *oldLines = Jupiter::File::data_->lines;
Jupiter::File::data_->lines = new Jupiter::CStringS[Jupiter::File::data_->lineCount + wc];
unsigned int i;
for (i = 0; i < Jupiter::File::data_->lineCount; i++) Jupiter::File::data_->lines[i] = oldLines[i];
delete[] oldLines;
Jupiter::File::data_->lineCount += wc;
for (unsigned int b = 0; b < wc; i++, b++) Jupiter::File::data_->lines[i] = Jupiter::CStringS::getWord(data, b, ENDL);
return true;
}
return false;
}
}
bool Jupiter::File::addData(const char *data)
{
return Jupiter::File::addData(Jupiter::CStringS(data));
}
bool Jupiter::File::load(const char *file)
{
FILE *filePtr = fopen(file, "rb");
if (filePtr == nullptr) return false;
if (Jupiter::File::data_->fileName.size() == 0) Jupiter::File::data_->fileName = file;
bool r = Jupiter::File::load(filePtr);
fclose(filePtr);
return r;
}
bool Jupiter::File::load(FILE *file)
{
Jupiter::CStringL fileBuffer;
char buffer[defaultBufferSize];
while (fgets(buffer, defaultBufferSize, file) != nullptr)
{
fileBuffer += buffer;
if (feof(file)) break;
}
return Jupiter::File::addData(fileBuffer);
}
void Jupiter::File::unload()
{
delete Jupiter::File::data_;
Jupiter::File::data_ = new Jupiter::File::Data();
}
bool Jupiter::File::reload()
{
if (Jupiter::File::data_->fileName.size() == 0) return false;
Jupiter::CStringS fileName = Jupiter::File::data_->fileName;
Jupiter::File::unload();
return Jupiter::File::load(fileName.c_str());
}
bool Jupiter::File::reload(const char *file)
{
Jupiter::File::unload();
return Jupiter::File::load(file);
}
bool Jupiter::File::reload(FILE *file)
{
Jupiter::File::unload();
return Jupiter::File::load(file);
}
bool Jupiter::File::sync()
{
if (Jupiter::File::data_->fileName.size() == 0) return false;
return Jupiter::File::sync(Jupiter::File::data_->fileName.c_str());
}
bool Jupiter::File::sync(const char *file)
{
FILE *filePtr = fopen(file, "wb");
if (filePtr == nullptr) return false;
Jupiter::File::sync(filePtr); // Always returns true.
fclose(filePtr);
return true;
}
bool Jupiter::File::sync(FILE *file)
{
for (unsigned int i = 0; i < Jupiter::File::data_->lineCount; i++)
{
fputs(Jupiter::File::data_->lines[i].c_str(), file);
fputs(ENDL, file);
}
return true;
}

165
Jupiter/File.h

@ -0,0 +1,165 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _FILE_H_HEADER
#define _FILE_H_HEADER
/**
* @file File.h
* @brief Provides a fast interface for accessing stored file data.
*/
#include "Jupiter.h"
#include "CString.h"
#include <cstdio>
namespace Jupiter
{
class JUPITER_API File
{
public:
/**
* @brief Fetches the number of lines in the file.
*
* @return Total number of lines.
*/
unsigned int getLineCount() const;
/**
* @brief Fetches a line of the file.
*
* @param line Index of the line to fetch.
* @return Line of text at the specified index.
*/
const Jupiter::StringType &getLine(unsigned int line) const;
/**
* @brief Returns the name of the first raw file originally loaded.
*
* @return String containing the name of the first file loaded into this file.
*/
const Jupiter::StringType &getFileName() const;
/**
* @brief Adds data to a file, which may consist of one or more lines.
*
* @param data Data to add to the file.
* @param True if data was added to the file, false otherwise.
*/
bool addData(const Jupiter::StringType &data);
/**
* @brief Adds data to a file, which may consist of one or more lines.
*
* @param data Data to add to the file.
* @param True if data was added to the file, false otherwise.
*/
bool addData(const char *data);
/**
* @brief Loads a file from the drive into this file.
*
* @param file name of the file to load from drive.
* @return True if a file was successfully loaded from the drive, false otherwise.
*/
bool load(const char *file);
/**
* @brief Loads a file from the drive into this file.
*
* @param file C FILE stream to read from. This must not be an endless stream (such as stdin).
* @return True if a file was successfully loaded from the drive, false otherwise.
*/
bool load(FILE *file);
/**
* @brief Frees all of the stored data of the file, and puts it in a new state, ready for loading.
*/
void unload();
/**
* @brief Unloads all of a file's contents, and attempts to load from the originally loaded file.
*
* @return True if a file was successfully loaded from the drive, false otherwise.
*/
bool reload();
/**
* @brief Unloads all of a file's contents, and attempts to load from a specified file.
*
* @param file Name of a file to load from the drive.
* @return True if a file was successfully loaded from the drive, false otherwise.
*/
bool reload(const char *file);
/**
* @brief Unloads all of a file's contents, and attempts to load from a specified file stream.
*
* @param file C FILE stream to read from. This must not be an endless stream (such as stdin).
* @return True if a file was successfully loaded from the drive, false otherwise.
*/
bool reload(FILE *file);
/**
* @brief Syncs data from the file to the drive. This will write to the first loaded file.
*
* @return True if the file was successfully written to the drive, false otherwise.
*/
bool sync();
/**
* @brief Syncs data from the file to the drive.
*
* @param file Name of the file to write to.
* @return True if the file was successfully written to the drive, false otherwise.
*/
bool sync(const char *file);
/**
* @brief Syncs data from the file to the drive.
*
* @param file C FILE stream to output to.
* @return True if the file was successfully written to the drive, false otherwise.
*/
bool sync(FILE *file);
/**
* @brief Default constructor for File class.
*/
File();
/**
* @brief Copy constructor for File class.
*/
File(const File &file);
/**
* @brief Destructor for File class.
*/
virtual ~File();
/** Private members */
private:
struct Data;
Data *data_;
};
}
#endif // _FILE_H_HEADER

523
Jupiter/Functions.c

@ -0,0 +1,523 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <stdlib.h> // malloc
#include <stdint.h> // uintxx_t typedefs.
#include <stdio.h> // fprintf and stderr
#include <time.h> // Used by getTime()
#include <ctype.h> // toupper
#include <wctype.h> // towupper
#include "Functions.h"
// Little Endian
unsigned int getZeroByte(uint32_t *v)
{
if ((*v & 0x000000FF) == 0) return 0;
if ((*v & 0x0000FF00) == 0) return 1;
if ((*v & 0x00FF0000) == 0) return 2;
if ((*v & 0xFF000000) == 0) return 3;
return 4;
}
unsigned int getZeroByte2(uint64_t v)
{
if ((v & 0x00000000000000FF) == 0) return 0;
if ((v & 0x000000000000FF00) == 0) return 1;
if ((v & 0x0000000000FF0000) == 0) return 2;
if ((v & 0x00000000FF000000) == 0) return 3;
if ((v & 0x000000FF00000000) == 0) return 4;
if ((v & 0x0000FF0000000000) == 0) return 5;
if ((v & 0x00FF000000000000) == 0) return 6;
if ((v & 0xFF00000000000000) == 0) return 7;
return 8;
}
/*
// Big Endian
unsigned int getZeroByte(uint32_t v)
{
if ((v & 0xFF000000) == 0) return 0;
if ((v & 0x00FF0000) == 0) return 1;
if ((v & 0x0000FF00) == 0) return 2;
if ((v & 0x000000FF) == 0) return 3;
return 4;
}
unsigned int getZeroByte64(uint64_t v)
{
if ((v & 0xFF00000000000000) == 0) return 0;
if ((v & 0x00FF000000000000) == 0) return 1;
if ((v & 0x0000FF0000000000) == 0) return 2;
if ((v & 0x000000FF00000000) == 0) return 3;
if ((v & 0x00000000FF000000) == 0) return 4;
if ((v & 0x0000000000FF0000) == 0) return 5;
if ((v & 0x000000000000FF00) == 0) return 6;
if ((v & 0x00000000000000FF) == 0) return 7;
return 8;
}
*/
uint32_t getPowerTwo32(uint32_t v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
uint64_t getPowerTwo64(uint64_t v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v |= v >> 32;
v++;
return v;
}
#define STRLEN_WRAPPER(TYPE) \
register const TYPE *s = str; \
while (*s != 0) s++; \
return s - str;
size_t Jupiter_strlen(const char *str)
{
STRLEN_WRAPPER(char)
}
size_t Jupiter_wstrlen(const wchar_t *str)
{
STRLEN_WRAPPER(wchar_t)
}
size_t Jupiter_strlen8(const uint8_t *str)
{
STRLEN_WRAPPER(uint8_t)
}
size_t Jupiter_strlen16(const uint16_t *str)
{
STRLEN_WRAPPER(uint16_t)
}
size_t Jupiter_strlen32(const uint32_t *str)
{
STRLEN_WRAPPER(uint32_t)
}
size_t Jupiter_strlen64(const uint64_t *str)
{
STRLEN_WRAPPER(uint64_t)
}
size_t Jupiter_vstrlen(const void *str, size_t size)
{
const char *s;
const char *s2;
switch (size)
{
case 0:
return 0;
case 1:
return Jupiter_strlen((const char *)str);
case 2:
return Jupiter_strlen16((const uint16_t *)str);
case 4:
return Jupiter_strlen32((const uint32_t *)str);
case 8:
return Jupiter_strlen64((const uint64_t *)str);
default:
s = (const char *)str;
s2 = s;
while ((unsigned)(s2 - s) != size)
{
s2 = s;
while ((unsigned)(s2 - s) > size)
{
if (*s2 != 0) break;
s2++;
}
s += size;
}
return (s - (const char *)str) / size;
}
}
const char *stristr(const char *str1, const char *str2)
{
const char *strr;
int i;
int a;
for (i = 0; str1[i] != 0; i++)
{
if (toupper(str1[i]) == toupper(str2[0]))
{
a = 1;
while (str2[a] != 0)
{
if (toupper(str1[i + a]) != toupper(str2[a])) break;
a++;
}
if (str2[a] == 0)
{
strr = &str1[i];
return strr;
}
}
}
return NULL;
}
bool streql(const char *s1, const char *s2)
{
if (s1 == s2) return true;
while (*s1 != 0 && *s1 == *s2)
{
s1++;
s2++;
}
return (*s1 == *s2);
}
bool streqli(const char *s1, const char *s2)
{
if (s1 == s2) return true;
while (*s1 != 0 && toupper(*s1) == toupper(*s2))
{
s1++;
s2++;
}
if (*s1 == *s2) return true;
return false;
}
bool wstreql(const wchar_t *s1, const wchar_t *s2)
{
if (s1 == s2) return true;
while (*s1 != 0 && *s1 == *s2)
{
s1++;
s2++;
}
return (*s1 == *s2);
}
bool wstreqli(const wchar_t *s1, const wchar_t *s2)
{
if (s1 == s2) return true;
while (*s1 != 0 && towupper(*s1) == towupper(*s2))
{
s1++;
s2++;
}
if (*s1 == *s2) return true;
return false;
}
bool strmatch(const char *f, const char *s)
{
while (*f != 0)
{
if (*f == '*')
{
f++;
if (*f == 0) return true;
while (*s != 0)
{
if (*f == *s) break;
s++;
}
if (*s == 0) return false;
}
else if (*f != '?' && *f != *s) return false;
f++;
s++;
}
return *f == *s;
}
bool strmatchi(const char *f, const char *s)
{
while (*f != 0)
{
if (*f == '*')
{
f++;
if (*f == 0) return true;
while (*s != 0)
{
if (*f == *s) break;
s++;
}
if (*s == 0) return false;
}
else if (*f != '?' && toupper(*f) != toupper(*s)) return false;
f++;
s++;
}
return *f == *s;
}
bool wstrmatch(const wchar_t *f, const wchar_t *s)
{
while (*f != 0)
{
if (*f == L'*')
{
f++;
if (*f == 0) return true;
while (*s != 0)
{
if (*f == *s) break;
s++;
}
if (*s == 0) return false;
}
else if (*f != L'?' && *f != *s) return false;
f++;
s++;
}
return *f == *s;
}
bool wstrmatchi(const wchar_t *f, const wchar_t *s)
{
while (*f != 0)
{
if (*f == L'*')
{
f++;
if (*f == 0) return true;
while (*s != 0)
{
if (*f == *s) break;
s++;
}
if (*s == 0) return false;
}
else if (*f != L'?' && towupper(*f) != towupper(*s)) return false;
f++;
s++;
}
return *f == *s;
}
char *charToChar(const char *a, int b, int c)
{
char *r = (char *) malloc(sizeof(char) * (c-b+1));
if (r != NULL)
{
int i = 0;
while (b < c)
{
r[i] = a[b];
i++;
b++;
}
r[i] = 0;
}
else fprintf(stderr, "ERROR: UNABLE TO ALLOCATE IN %s" ENDL, __FUNCTION__);
return r;
}
wchar_t *wcharToChar(const wchar_t *a, int b, int c)
{
wchar_t *r = (wchar_t *)malloc(sizeof(wchar_t)* (c - b + 1));
if (r != NULL)
{
int i = 0;
while (b < c)
{
r[i] = a[b];
i++;
b++;
}
r[i] = 0;
}
else fprintf(stderr, "ERROR: UNABLE TO ALLOCATE IN %s" ENDL, __FUNCTION__);
return r;
}
void trim(char *str)
{
int p = 0;
int x = 0;
int i;
while (str[p] != 0)
{
if (str[p] == 10)
{
str[p] = 0;
}
else if (str[p] == 13)
{
str[p] = 0;
}
p++;
}
for (i = 0; i < p; i++)
{
if (str[i] != 0)
{
str[x] = str[i];
x++;
}
}
str[x] = 0;
}
char *getWord(const char *str, int w)
{
char *result;
int x = 0;
int y;
int i;
for (i = 0; i < w; x++)
{
if (str[x] == 0) return NULL;
if (str[x] == ' ') i++;
}
for (y = x; str[y] != ' ' && str[y] != 0; y++);
result = (char *) malloc(sizeof(char) * (y-x+1));
if (result != NULL)
{
for (i = 0; x < y; i++)
{
result[i] = str[x];
x++;
}
result[i] = 0;
}
else fprintf(stderr, "ERROR: UNABLE TO ALLOCATE IN %s" ENDL, __FUNCTION__);
return result;
}
unsigned int countSymbol(const char *str, char c)
{
unsigned int result = 0;
while(*str != 0)
{
if (*str == c) result++;
str++;
}
return result;
}
unsigned int wordCount(const char *str)
{
unsigned int result = 0;
int i;
for (i = 0; str[i] != 0; i++)
{
if (str[i] == ' ')
{
if (i > 0)
{
if (str[i-1] > ' ') result++;
}
}
else if (str[i+1] < ' ') result++;
}
return result;
}
unsigned int countLines(const char *str)
{
unsigned int r = 0;
while (*str != 0)
{
if ((*str == '\r' && *(str + 1) != '\n') || *str == '\n') r++;
str++;
}
return r;
}
char *getLine(const char *str, unsigned int l)
{
char *result;
unsigned int x = 0;
unsigned int y;
unsigned int i;
for (i = 0; i < l; x++)
{
if (str[x] == 0) break;
if (str[x] == '\n' || (str[x] == '\r' && str[x+1] != '\n')) i++;
}
for (y = x; str[y] != '\r' && str[y] != '\n' && str[y] != 0; y++);// if (str[y] == 0) break;
result = (char *) malloc(sizeof(char) * (y-x+1));
if (result != NULL)
{
for (i = 0; x < y; i++)
{
result[i] = str[x];
x++;
}
result[i] = 0;
}
else fprintf(stderr, "ERROR: UNABLE TO ALLOCATE IN %s" ENDL, __FUNCTION__);
return result;
}
int findSymbol(const char *str, char c, int pos)
{
int r = 0;
int a = 0;
while (str[r] != 0)
{
if (str[r] == c)
{
if (a == pos) return r;
a++;
}
r++;
}
return -1;
}
bool containsSymbol(const char *str, char c)
{
int i;
for (i = 0; str[i] != 0; i++) if (str[i] == c) return true;
return false;
}
char *makestr(const char *str)
{
char *r;
size_t len;
if (str == NULL) return NULL;
len = Jupiter_strlen(str);
r = (char *) malloc(sizeof(char) * (len + 1));
if (r != NULL)
{
r[len] = 0;
while (len != 0)
{
len--;
r[len] = str[len];
}
return r;
}
return NULL;
}
char *getTime()
{
time_t rawtime = time(0);
static char rtime[256];
strftime(rtime, sizeof(rtime), "%a %b %d %H:%M:%S %Y %Z", localtime(&rawtime));
return rtime;
}

391
Jupiter/Functions.h

@ -0,0 +1,391 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _FUNCTIONS_H_HEADER
#define _FUNCTIONS_H_HEADER
#include "Jupiter.h"
#define ENDL "\r\n"
#define WHITESPACE " \t"
/**
* @file Functions.h
* @brief Provides some functions to be used at your convenience.
*/
#if defined __cplusplus
#include <cstdint>
namespace Jupiter
{
/**
* @brief Returns the length of a C-style string.
* This will often get optimized by the compiler such that the calculation time is 0.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
template<typename T = char> inline size_t strlen(const T *str);
/**
* @brief Copies a string of elements from one buffer to another.
* Note: The destination buffer must be at least as long as the source + 1.
*
* @param dest Destination buffer for the string of elements.
* @param source Buffer containing the source elements.
* @return Pointer to the destination.
*/
template<typename T = char> inline T *strcpy(T *dest, const T *source);
/**
* @brief Copies a string of elements from one buffer to another.
* Note: The destination buffer must be at least as long as sourceLength + 1.
*
* @param dest Destination buffer for the string of elements.
* @param source Buffer containing the source elements.
* @param sourceLength Number of elements to copy, excluding null-terminator.
* @return Pointer to the destination.
*/
template<typename T = char> inline T *strcpy(T *dest, const T *source, size_t sourceLength);
/**
* @brief Returns a pointer to the first occurance of an element from str2 appearing in str1, or nullptr.
* Note: The destination buffer must be at least as long as sourceLength + 1.
*
* @param str1 String to be scanned.
* @param str2 String containing elements to find.
* @return Pointer to the first instance of a character in str2 being in str1, or nullptr if there is none.
*/
template<typename T = char> inline const T *strpbrk(const T *str1, const T *str2);
template<typename T = char> inline const T *strpbrk(const T *str1, const T str2);
/**
* @brief Checks if two strings are equal.
*
* @param str1 String to be compared.
* @param str2 String to be compared.
* @return True if the strings are equal, false otherwise.
*/
template<typename T = char> bool streql(const T *str1, const T *str2);
}
extern "C"
{
#else // __cplusplus
#include <stdbool.h>
#include <stdint.h>
#endif // __cplusplus
/**
* @brief Case insensitive version of strstr().
*
* @param str1 String to be scanned.
* @param str2 String to be matched.
* @return Pointer to the first occurance of str2 in str1 if it exists, NULL otherwise.
*/
JUPITER_API const char *stristr(const char *str1, const char *str2);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_strlen(const char *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_wstrlen(const wchar_t *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_strlen8(const uint8_t *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_strlen16(const uint16_t *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_strlen32(const uint32_t *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_strlen64(const uint64_t *str);
/**
* @brief Returns the length of a C-style string.
*
* @param str C-style string to get the length of.
* @return Length of the C-style string.
*/
JUPITER_API size_t Jupiter_vstrlen(const void *str, size_t size);
/**
* @brief Checks if two strings are equal. This function is case-sensitive.
*
* @param str1 String to be compared.
* @param str2 String to be compared.
* @return True if the strings are equal, false otherwise.
*/
JUPITER_API bool streql(const char *str1, const char *str2);
JUPITER_API bool wstreql(const wchar_t *str1, const wchar_t *str2);
/**
* @brief Checks if two strings are equal. This function is not case-sensitive.
*
* @param str1 String to be compared.
* @param str2 String to be compared.
* @return True if the strings are equal, false otherwise.
*/
JUPITER_API bool streqli(const char *str1, const char *str2);
JUPITER_API bool wstreqli(const wchar_t *str1, const wchar_t *str2);
/**
* @brief Checks if a string matches a wildcard format.
* Note: Case sensitive.
*
* @param format Sring containing the wildcard format information.
* @param str2 String to be compared.
* @return True if the string matches the wildcard format, false otherwise.
*/
JUPITER_API bool strmatch(const char *format, const char *str);
JUPITER_API bool wstrmatch(const wchar_t *format, const wchar_t *str);
/**
* @brief Checks if a string matches a wildcard format.
* Note: Case insensitive.
*
* @param format Sring containing the wildcard format information.
* @param str2 String to be compared.
* @return True if the string matches the wildcard format, false otherwise.
*/
JUPITER_API bool strmatchi(const char *format, const char *str);
JUPITER_API bool wstrmatchi(const wchar_t *format, const wchar_t *str);
/**
* @brief Returns a copy of a substring.
*
* @param str String
* @param a String to be compared.
* @param b String to be compared.
* @return String containing the substring, or NULL on malloc failure.
*/
JUPITER_API char *charToChar(const char *str, int a, int b);
JUPITER_API wchar_t *wcharToChar(const wchar_t *str, int a, int b);
/**
* @brief Removes any carriage-returns (\r) and new lines (\n) from a string.
*
* @param str String to be trimed.
*/
JUPITER_API void trim(char *str);
/**
* @brief Returns a copy of a "word" from a string.
*
* @param str String to be parsed.
* @param w Position of the word, starting at 0.
* @return String containing the word on success, or NULL otherwise.
*/
JUPITER_API char *getWord(const char *str, int w);
/**
* @brief Returns the number of occurances of a given character.
*
* @param str String to be scanned.
* @param c Character to be counted.
* @return Total number of occurances of a character in a string.
*/
JUPITER_API unsigned int countSymbol(const char *str, char c);
/**
* @brief Returns the number of space-deliminated words in a string.
*
* @param str String to be scanned.
* @return Total number of space-deliminated words in a string.
*/
JUPITER_API unsigned int wordCount(const char *str);
/**
* @brief Returns the number of newlines in a string.
*
* @param str String to be scanned.
* @return Total number of newlines in a string.
*/
JUPITER_API unsigned int countLines(const char *str);
/**
* @brief Returns a substring in the form of a new String,
*
* @param str String to be scanned.
* @return String representing a single line of the input string on success, NULL otherwise.
*/
JUPITER_API char *getLine(const char *str, unsigned int l);
/**
* @brief Returns the position of the n'th occurance of a character in a string.
*
* @param str String to be scanned.
* @param c Character to find.
* @param n Position of the character to search for.
* @return Position of the n'th occurance of a character if it exists, -1 otherwise.
*/
JUPITER_API int findSymbol(const char *str, char c, int n);
/**
* @brief Checks if a character exists in a string.
*
* @param str String to scan.
* @return True if it contains a given character, false otherwise.
*/
JUPITER_API bool containsSymbol(const char *str, char c);
/**
* @brief Creates a copy of a string.
*
* @param str String to copy.
* @return String containing a copy of the input string on success, NULL otherwise.
*/
JUPITER_API char *makestr(const char *str);
/**
* @brief returns the current time in a string format.
* This will vary depending on locale.
* Format: Day_of_week Month Day hh:mm:ss Year Timezone.
* Example 1: Sun Aug 18 13:52:21 2013 EST
* Example 2: Thu Nov 14 03:52:57 2013 Eastern Standard Time
* Exmaple 3: Sun Nov 17 15:06:19 2013 Tokyo Standard Time
*
* @return A string containing the time in the format specified above.
*/
JUPITER_API char *getTime();
/**
* @brief Gets the next power of 2 after a specified number.
*
* @param number 32-bit integer to start from.
* @return Next highest power of 2.
*/
JUPITER_API uint32_t getPowerTwo32(uint32_t number);
/**
* @brief Gets the next power of 2 after a specified number.
*
* @param number 64-bit integer to start from.
* @return Next highest power of 2.
*/
JUPITER_API uint64_t getPowerTwo64(uint64_t number);
#if defined __cplusplus
}
/** strlen implementation */
template<typename T> inline size_t Jupiter::strlen(const T *str)
{
register const T *s = str;
while (*s != 0) s++;
return s - str;
}
/** strcpy implementation */
template<typename T> inline T *Jupiter::strcpy(T *dest, const T *source)
{
register T *d = dest;
while (*source != 0)
{
*d = *source;
d++;
source++;
}
*d = *source;
return dest;
}
/** strcpy implementation */
template<typename T> inline T *Jupiter::strcpy(T *dest, const T *source, size_t length)
{
dest[length] = 0;
while (length > 0)
{
length--;
dest[length] = source[length];
}
return dest;
}
template<typename T> inline const T *Jupiter::strpbrk(const T *str1, const T *str2)
{
const T *s;
while (*str1 != 0)
{
s = str2;
while (*s != 0)
{
if (*str1 == *s) return str1;
s++;
}
str1++;
}
return nullptr;
}
template<typename T> inline const T *Jupiter::strpbrk(const T *str1, const T e)
{
while (*str1 != 0)
{
if (*str1 == e) return str1;
str1++;
}
return nullptr;
}
template<typename T> inline bool Jupiter::streql(const T *str1, const T *str2)
{
if (str1 == str2) return true;
while (*str1 != 0 && *str1 == *str2)
{
str1++;
str2++;
}
return (*str1 == *str2);
}
#endif // __cplusplus
#endif // _FUNCTIONS_H_HEADER

581
Jupiter/INIFile.cpp

@ -0,0 +1,581 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include "Functions.h"
#include "INIFile.h"
#include "CString.h"
#include "ArrayList.h"
#include "InvalidIndex.h"
/**
* TODO:
* Rewrite using String, and ArrayList. Consider using File when reading data.
* Add support for unspecified section.
* Consider sort/search optimization.
*/
/** KeyValuePair implementation */
struct Jupiter::INIFile::Section::KeyValuePair::Data
{
Jupiter::CStringS key;
Jupiter::CStringS value;
};
Jupiter::INIFile::Section::KeyValuePair::KeyValuePair()
{
Jupiter::INIFile::Section::KeyValuePair::data_ = new Jupiter::INIFile::Section::KeyValuePair::Data();
}
Jupiter::INIFile::Section::KeyValuePair::KeyValuePair(const KeyValuePair &source)
{
Jupiter::INIFile::Section::KeyValuePair::data_ = new Jupiter::INIFile::Section::KeyValuePair::Data();
Jupiter::INIFile::Section::KeyValuePair::data_->key = source.data_->key;
Jupiter::INIFile::Section::KeyValuePair::data_->value = source.data_->value;
}
Jupiter::INIFile::Section::KeyValuePair::~KeyValuePair()
{
delete Jupiter::INIFile::Section::KeyValuePair::data_;
}
const Jupiter::StringType &Jupiter::INIFile::Section::KeyValuePair::getKey() const
{
return Jupiter::INIFile::Section::KeyValuePair::data_->key;
}
const Jupiter::StringType &Jupiter::INIFile::Section::KeyValuePair::getValue() const
{
return Jupiter::INIFile::Section::KeyValuePair::data_->value;
}
void Jupiter::INIFile::Section::KeyValuePair::setValue(const Jupiter::StringType &value)
{
Jupiter::INIFile::Section::KeyValuePair::data_->value = value;
}
void Jupiter::INIFile::Section::KeyValuePair::setValue(const char *value)
{
Jupiter::INIFile::Section::KeyValuePair::data_->value = value;
}
/** Section implementation */
struct Jupiter::INIFile::Section::Data
{
Jupiter::CStringS name;
Jupiter::ArrayList<Jupiter::INIFile::Section::KeyValuePair> data;
~Data();
};
Jupiter::INIFile::Section::Data::~Data()
{
Jupiter::INIFile::Section::Data::data.emptyAndDelete();
}
Jupiter::INIFile::Section::Section()
{
Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data();
}
Jupiter::INIFile::Section::Section(const Jupiter::StringType &name)
{
Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data();
Jupiter::INIFile::Section::data_->name = name;
}
Jupiter::INIFile::Section::Section(const char *name)
{
Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data();
Jupiter::INIFile::Section::data_->name = name;
}
Jupiter::INIFile::Section::Section(const Jupiter::INIFile::Section &source)
{
Jupiter::INIFile::Section::data_ = new Jupiter::INIFile::Section::Data();
Jupiter::INIFile::Section::data_->name = source.data_->name;
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
for (unsigned int i = 0; i < size; i++)
{
Jupiter::INIFile::Section::data_->data.add(new Jupiter::INIFile::Section::KeyValuePair(*source.data_->data.get(i)));
}
}
Jupiter::INIFile::Section::~Section()
{
delete Jupiter::INIFile::Section::data_;
}
const Jupiter::StringType &Jupiter::INIFile::Section::getName() const
{
return Jupiter::INIFile::Section::data_->name;
}
const Jupiter::StringType &Jupiter::INIFile::Section::getValue(unsigned int index) const
{
return Jupiter::INIFile::Section::data_->data.get(index)->data_->value;
}
const Jupiter::StringType &Jupiter::INIFile::Section::getValue(const Jupiter::StringType &key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return pair->getValue();
}
return Jupiter::emptyString;
}
const Jupiter::StringType &Jupiter::INIFile::Section::getValue(const char *key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return pair->getValue();
}
return Jupiter::emptyString;
}
Jupiter::INIFile::Section::KeyValuePair *Jupiter::INIFile::Section::getPair(unsigned int index) const
{
return Jupiter::INIFile::Section::data_->data.get(index);
}
Jupiter::INIFile::Section::KeyValuePair *Jupiter::INIFile::Section::getPair(const Jupiter::StringType &key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return pair;
}
return nullptr;
}
Jupiter::INIFile::Section::KeyValuePair *Jupiter::INIFile::Section::getPair(const char *key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return pair;
}
return nullptr;
}
unsigned int Jupiter::INIFile::Section::size() const
{
return Jupiter::INIFile::Section::data_->data.size();
}
bool Jupiter::INIFile::Section::hasKey(const Jupiter::StringType &key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return true;
}
return false;
}
bool Jupiter::INIFile::Section::hasKey(const char *key) const
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key)) return true;
}
return false;
}
bool Jupiter::INIFile::Section::set(Jupiter::StringType &key, Jupiter::StringType &value)
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key))
{
pair->data_->value = value;
return false;
}
}
pair = new Jupiter::INIFile::Section::KeyValuePair();
pair->data_->key = key;
pair->data_->value = value;
Jupiter::INIFile::Section::data_->data.add(pair);
return true;
}
bool Jupiter::INIFile::Section::set(const char *key, const char *value)
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
Jupiter::INIFile::Section::KeyValuePair *pair;
for (unsigned int i = 0; i < size; i++)
{
pair = Jupiter::INIFile::Section::data_->data.get(i);
if (pair->getKey().equalsi(key))
{
pair->data_->value = value;
return false;
}
}
pair = new Jupiter::INIFile::Section::KeyValuePair();
pair->data_->key = key;
pair->data_->value = value;
Jupiter::INIFile::Section::data_->data.add(pair);
return true;
}
void Jupiter::INIFile::Section::setName(const Jupiter::StringType &name)
{
Jupiter::INIFile::Section::data_->name = name;
}
void Jupiter::INIFile::Section::setName(const char *name)
{
Jupiter::INIFile::Section::data_->name = name;
}
bool Jupiter::INIFile::Section::remove(Jupiter::StringType &key)
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
for (unsigned int i = 0; i < size; i++)
{
if (Jupiter::INIFile::Section::data_->data.get(i)->getKey().equalsi(key))
{
delete Jupiter::INIFile::Section::data_->data.remove(i);
return true;
}
}
return false;
}
bool Jupiter::INIFile::Section::remove(const char *key)
{
unsigned int size = Jupiter::INIFile::Section::data_->data.size();
for (unsigned int i = 0; i < size; i++)
{
if (Jupiter::INIFile::Section::data_->data.get(i)->getKey().equalsi(key))
{
delete Jupiter::INIFile::Section::data_->data.remove(i);
return true;
}
}
return false;
}
/** INIFile implementation */
struct Jupiter::INIFile::Data
{
Jupiter::ArrayList<Section> data;
Jupiter::CStringS fName;
~Data();
};
Jupiter::INIFile::Data::~Data()
{
Jupiter::INIFile::Data::data.emptyAndDelete();
}
Jupiter::INIFile::INIFile()
{
Jupiter::INIFile::data_ = new Jupiter::INIFile::Data;
}
Jupiter::INIFile::INIFile(const INIFile &source)
{
Jupiter::INIFile::data_ = new Jupiter::INIFile::Data;
Jupiter::INIFile::data_->fName = source.data_->fName;
unsigned int size = Jupiter::INIFile::data_->data.size();
for (unsigned int i = 0; i < size; i++)
{
Jupiter::INIFile::data_->data.add(new Jupiter::INIFile::Section(*source.data_->data.get(i)));
}
}
Jupiter::INIFile::~INIFile()
{
delete Jupiter::INIFile::data_;
}
void Jupiter::INIFile::flushData()
{
delete Jupiter::INIFile::data_;
Jupiter::INIFile::data_ = new Jupiter::INIFile::Data();
}
// TODO: Rewrite this.
unsigned int Jupiter::INIFile::readFile(const char *fileName)
{
int count = 0;
if (Jupiter::INIFile::data_->fName.size() != 0)
{
Jupiter::INIFile::data_->fName = "";
}
Jupiter::INIFile::data_->fName = fileName;
FILE *file = fopen(Jupiter::INIFile::data_->fName.c_str(), "rb");
if (file == nullptr) return Jupiter::ERROR_INDICATOR;
char fileBuffer[8192];
char *section;
//int nSection = 0;
while (!feof(file))
{
if (fgets(fileBuffer, sizeof(fileBuffer), file))
{
do1:
if (fileBuffer[strspn(fileBuffer, WHITESPACE)] != ';' && fileBuffer[strspn(fileBuffer, WHITESPACE)] == '[')
{
section = charToChar(fileBuffer, strspn(fileBuffer, WHITESPACE) + 1, strcspn(fileBuffer, "]"));
do2:
if (fgets(fileBuffer, sizeof(fileBuffer), file))
{
size_t eqlpos = strcspn(fileBuffer, "=");
if (fileBuffer[strspn(fileBuffer, WHITESPACE)] != ';' && eqlpos != strlen(fileBuffer))
{
size_t a = strspn(fileBuffer, WHITESPACE);
char *tkey = charToChar(fileBuffer, a, a + strcspn(fileBuffer + a, WHITESPACE "="));
char *tval = charToChar(fileBuffer, eqlpos + 1 + strspn(fileBuffer + eqlpos + 1, WHITESPACE), strcspn(fileBuffer, ENDL));
if (Jupiter::INIFile::set(section, tkey, tval)) count++;
delete[] tval;
delete[] tkey;
}
}
if (!feof(file))
{
if (fileBuffer[strspn(fileBuffer, WHITESPACE)] != '[') goto do2;
else goto do1;
}
}
}
}
fclose(file);
return count;
}
unsigned int Jupiter::INIFile::reload()
{
Jupiter::CStringS fileName = Jupiter::INIFile::data_->fName;
Jupiter::INIFile::flushData();
return Jupiter::INIFile::readFile(fileName.c_str());
}
bool Jupiter::INIFile::sync(const char *fileName)
{
unsigned int size = Jupiter::INIFile::data_->data.size();
unsigned int sectionSize;
Jupiter::INIFile::Section *section;
Jupiter::INIFile::Section::KeyValuePair *pair;
FILE *file = fopen(fileName, "wb");
if (file == nullptr) return false;
fputs("; This file was automatically generated by Agent's INI parser." ENDL "; The currently used data values are as follows." ENDL ENDL, file);
for (unsigned int a = 0; a < size; a++)
{
section = Jupiter::INIFile::data_->data.get(a);
fputc('[', file);
fputs(section->getName().c_str(), file);
fputs("]" ENDL, file);
sectionSize = section->size();
for (unsigned int b = 0; b < sectionSize; b++)
{
pair = section->getPair(b);
fputs(pair->getKey().c_str(), file);
fputc('=', file);
fputs(pair->getValue().c_str(), file);
fputs(ENDL, file);
}
fputs(ENDL, file);
}
fputs("; EOF", file);
fclose(file);
return true;
}
bool Jupiter::INIFile::sync()
{
if (Jupiter::INIFile::data_->fName.size() == 0) return false;
return Jupiter::INIFile::sync(Jupiter::INIFile::data_->fName.c_str());
}
bool Jupiter::INIFile::set(const char *section, const char *key, const char *value)
{
unsigned int i = 0;
unsigned int size = Jupiter::INIFile::data_->data.size();
Jupiter::INIFile::Section *sec;
while (i < size)
{
sec = Jupiter::INIFile::data_->data.get(i);
if (sec->getName().equalsi(section))
{
sec->set(key, value);
return false;
}
i++;
}
sec = new Jupiter::INIFile::Section(section);
sec->set(key, value);
Jupiter::INIFile::data_->data.add(sec);
return true;
}
bool Jupiter::INIFile::remove(const char *section, const char *key)
{
unsigned int size = Jupiter::INIFile::data_->data.size();
Jupiter::INIFile::Section *sec;
for (unsigned int i = 0; i < size; i++)
{
sec = Jupiter::INIFile::data_->data.get(i);
if (sec->getName().equalsi(section)) return sec->remove(key);
i++;
}
return false;
}
unsigned int Jupiter::INIFile::getSections() const
{
return Jupiter::INIFile::data_->data.size();
}
Jupiter::INIFile::Section *Jupiter::INIFile::getSection(unsigned int index) const
{
return Jupiter::INIFile::data_->data.get(index);
}
unsigned int Jupiter::INIFile::getSectionIndex(const char *section) const
{
unsigned int size = Jupiter::INIFile::data_->data.size();
for (unsigned int i = 0; i < size; i++)
{
if (Jupiter::INIFile::data_->data.get(i)->getName().equalsi(section)) return i;
}
return Jupiter::INVALID_INDEX;
}
unsigned int Jupiter::INIFile::getSectionLength(unsigned int index) const
{
return Jupiter::INIFile::data_->data.get(index)->size();
}
const char *Jupiter::INIFile::getKey(const char *section, unsigned int index) const
{
unsigned int sectionIndex = Jupiter::INIFile::getSectionIndex(section);
if (sectionIndex == Jupiter::INVALID_INDEX) return nullptr;
return Jupiter::INIFile::data_->data.get(sectionIndex)->getPair(index)->getKey().c_str();
}
unsigned int Jupiter::INIFile::getKeyIndex(const char *section, const char *key) const
{
unsigned int sectionIndex = Jupiter::INIFile::getSectionIndex(section);
if (sectionIndex == Jupiter::INVALID_INDEX) return Jupiter::INVALID_INDEX;
Jupiter::INIFile::Section *sect = Jupiter::INIFile::data_->data.get(sectionIndex);
unsigned int sectionSize = sect->size();
for (unsigned int i = 0; i < sectionSize; i++) if (sect->getPair(i)->getKey().equalsi(key)) return i;
return Jupiter::INVALID_INDEX;
}
const char *Jupiter::INIFile::get(const char *section, const char *key, const char *defaultValue) const
{
unsigned int size = Jupiter::INIFile::data_->data.size();
Jupiter::INIFile::Section *sect;
for (unsigned int i = 0; i < size; i++)
{
sect = Jupiter::INIFile::data_->data.get(i);
if (sect->getName().equalsi(section))
{
Jupiter::INIFile::Section::KeyValuePair *pair = sect->getPair(key);
if (pair == nullptr) return defaultValue;
return pair->getValue().c_str();
}
}
return defaultValue;
}
bool Jupiter::INIFile::getBool(const char *section, const char *key, bool defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr)
{
if (streqli(val, "FALSE")) return false;
if (streql(val, "0")) return false;
if (streqli(val, "OFF")) return false;
return true;
}
return defaultValue;
}
/*char Jupiter::INIFile::getChar(const char *section, const char *key) const
{
const char *val = Jupiter::INIFile::get(section,key);
if (val != nullptr) return val[0];
return 0;
}*/
short Jupiter::INIFile::getShort(const char *section, const char *key, short defaultValue) const
{
return (short)Jupiter::INIFile::getInt(section, key, defaultValue);
}
int Jupiter::INIFile::getInt(const char *section, const char *key, int defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return atoi(val);
return defaultValue;
}
long Jupiter::INIFile::getLong(const char *section, const char *key, long defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return strtol(val, nullptr, 0);
return defaultValue;
}
long long Jupiter::INIFile::getLongLong(const char *section, const char *key, long long defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return strtoll(val, nullptr, 0);
return defaultValue;
}
float Jupiter::INIFile::getFloat(const char *section, const char *key, float defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return strtof(val, nullptr);
return defaultValue;
}
double Jupiter::INIFile::getDouble(const char *section, const char *key, double defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return strtod(val, nullptr);
return defaultValue;
}
long double Jupiter::INIFile::getLongDouble(const char *section, const char *key, long double defaultValue) const
{
const char *val = Jupiter::INIFile::get(section, key);
if (val != nullptr) return strtold(val, nullptr);
return defaultValue;
}

474
Jupiter/INIFile.h

@ -0,0 +1,474 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _INIFILE_H_HEADER
#define _INIFILE_H_HEADER
/**
* @file INIFile.h
* @brief Provides interaction with INI files.
*/
#include "Jupiter.h"
#include "String_Type.h"
#include "InvalidIndex.h"
namespace Jupiter
{
/**
* @brief Provides interfacing with INI files.
* INIFile objects store the contents of .INI files into memory,
* and access them as neccessary. The INIFile object can store
* the contents of multiple files at a time, but does not store
* where data came from. As such, you can read from multiple files,
* however the contents will always go to a single file when synced.
* Disk contents are only modified when sync() is called.
*/
class JUPITER_API INIFile
{
public:
class JUPITER_API Section
{
public:
class JUPITER_API KeyValuePair
{
friend class Jupiter::INIFile::Section;
public:
/**
* @brief Fetches the key in the key-value pair.
*
* @return Reference to the key String in the pair.
*/
const Jupiter::StringType &getKey() const;
/**
* @brief Fetches the value in the key-value pair.
*
* @return Reference to the value String in the pair.
*/
const Jupiter::StringType &getValue() const;
/**
* @brief Sets the value of a key-value pair.
*
* @param value Value to set the key-value pair to.
*/
void setValue(const Jupiter::StringType &value);
/**
* @brief Sets the value of a key-value pair.
*
* @param value Value to set the key-value pair to.
*/
void setValue(const char *value);
/**
* @brief Default constructor for the KeyValuePair class.
*/
KeyValuePair();
/**
* @brief Copy constructor for the KeyValuePair class.
*/
KeyValuePair(const KeyValuePair &);
/**
* @brief Destructor for the KeyValuePair class.
*/
~KeyValuePair();
private:
struct Data;
Data *data_;
};
/**
* @brief Fetches the name of a section.
*
* @return Name of the section in a String.
*/
const Jupiter::StringType &getName() const;
/**
* @brief Fetches the value of a key-value pair at a specified index.
*
* @param index Index of the key-value pair.
* @return Value of a key-value pair at a specified index.
*/
const Jupiter::StringType &getValue(unsigned int index) const;
/**
* @brief Fetches the value of a key-value pair.
*
* @param key Key of the key-value pair.
* @return Value of a key-value pair, or an empty string if none is found.
*/
const Jupiter::StringType &getValue(const Jupiter::StringType &key) const;
/**
* @brief Fetches the value of a key-value pair.
*
* @param key Key of the key-value pair.
* @return Value of a key-value pair, or an empty string if none is found.
*/
const Jupiter::StringType &getValue(const char *key) const;
/**
* @brief Fetches a key-value pair at a specified index.
*
* @param index Index of the key-value pair to fetch.
* @return The key-value pair at the specified index.
*/
Jupiter::INIFile::Section::KeyValuePair *getPair(unsigned int index) const;
/**
* @brief Fetches a key-value pair.
*
* @param key Key of the key-value pair.
* @return A key-value pair if a match is found, nullptr otherwise.
*/
Jupiter::INIFile::Section::KeyValuePair *getPair(const Jupiter::StringType &key) const;
/**
* @brief Fetches a key-value pair.
*
* @param key Key of the key-value pair.
* @return A key-value pair if a match is found, nullptr otherwise.
*/
Jupiter::INIFile::Section::KeyValuePair *getPair(const char *key) const;
/**
* @brief Fetches the number of key-value pairs in the section.
*
* @return Number of key-value pairs in the section.
*/
unsigned int size() const;
/**
* @brief Checks if a section has a key-value pair with a specified key.
*
* @param key Key of the key-value pair to search for.
* @return True if a match is found, false otherwise.
*/
bool hasKey(const Jupiter::StringType &key) const;
/**
* @brief Checks if a section has a key-value pair with a specified key.
*
* @param key Key of the key-value pair to search for.
* @return True if a match is found, false otherwise.
*/
bool hasKey(const char *key) const;
/**
* @brief Sets a key-value pair's value to a specified value. Creates a new pair if none is found.
*
* @param key Key of the key-value pair to search for or create.
* @param value Value to set the key-value pair to.
* @return True if a new key-value pair was created, false otherwise.
*/
bool set(Jupiter::StringType &key, Jupiter::StringType &value);
/**
* @brief Sets a key-value pair's value to a specified value. Creates a new pair if none is found.
*
* @param key Key of the key-value pair to search for or create.
* @param value Value to set the key-value pair to.
* @return True if a new key-value pair was created, false otherwise.
*/
bool set(const char *key, const char *value);
/**
* @brief Sets the name of a section.
*
* @param name String to set the section name to.
*/
void setName(const Jupiter::StringType &name);
/**
* @brief Sets the name of a section.
*
* @param name String to set the section name to.
*/
void setName(const char *name);
/**
* @brief Removes a key-value pair from the section.
*
* @param key Key of the key-value pair to remove.
* @return True if a key-value pair was removed, false otherwise.
*/
bool remove(Jupiter::StringType &key);
/**
* @brief Removes a key-value pair from the section.
*
* @param key Key of the key-value pair to remove.
* @return True if a key-value pair was removed, false otherwise.
*/
bool remove(const char *key);
/**
* @brief Default constructor for the Section class.
*/
Section();
/**
* @brief Name-specifiable constructors for the Section class
*/
Section(const Jupiter::StringType &name);
Section(const char *name);
/**
* @brief Copy constructor for the Section class.
*/
Section(const Section &);
/**
* @brief Destructor for the Section class.
*/
~Section();
private:
struct Data;
Data *data_;
};
/**
* @brief Flushes all stored data.
*/
void flushData();
/**
* @brief Reads data from a file.
* The readFile function does not currently support keys which
* are not under a section, though this is not currently an issue,
* and may still be added later. The parser will also automatically
* remove any excessive whitespace, including any whitespace prefixing
* a key name, prefixing a key value, trailing a key name, or traling
* a key value.
*
* @param fileName String containing the name of a file.
* @return The number of entries added on success, ERROR_INDICATOR (-1) otherwise.
*/
unsigned int readFile(const char *fileName);
/**
* @brief Flushes all stored data and recollects from the last read file.
*
* @return The number of entries added on success, ERROR_INDICATOR (-1) otherwise.
*/
unsigned int reload();
/**
* @brief Syncs data to a file.
*
* @param fileName String containing the name of a file.
* @return True on success, false otherwise.
*/
bool sync(const char *fileName);
/**
* @brief Syncs data to the file that was last read from.
*
* @return True on success, false otherwise.
*/
bool sync();
/**
* @brief Sets a key's value. Adds a key if an existing one is not found. Does not modify any files.
*
* @param section Section within which the data is to be stored.
* @param keyName String containing key name.
* @param keyValue String containing new key value.
* @return True if a new key was added, false otherwise.
*/
bool set(const char *section, const char *keyName, const char *keyValue);
/**
* @brief Removes a key. Does not modify any files.
*
* @param section String containing section.
* @param keyName String containing key name.
* @return True if an entry was removed, false otherwise.
*/
bool remove(const char *section, const char *keyName);
/**
* @brief Returns the number of sections in memory.
*
* @return Number of sections.
*/
unsigned int getSections() const;
/**
* @brief Returns a section.
*
* @param index Index of the section to get.
* @return String containing section if it exists, nullptr otherwise.
*/
Jupiter::INIFile::Section *getSection(unsigned int index) const;
/**
* @brief Returns the index of a section.
*
* @param section The name of the section.
* @return The index of section if it exists, INVALID_INDEX (-1) otherwise.
*/
unsigned int getSectionIndex(const char *section) const;
/**
* @brief Returns the number of keys in a section.
*
* @return Number of data entries in a section.
*/
unsigned int getSectionLength(unsigned int index) const;
/**
* @brief Returns a key name.
*
* @param section String containing section.
* @param keyIndex Index of the key.
* @return Key name on success, nullptr otherwise.
*/
const char *getKey(const char *section, unsigned int index) const;
/**
* @brief Returns the index of a key.
*
* @param section String containing section.
* @param key String containing key name.
* @return Index of key if it exists, INVALID_INDEX (-1) otherwise.
*/
unsigned int getKeyIndex(const char *section, const char *key) const;
/**
* @brief Returns the value of a key.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return Pointer to a string containing key value if it exists, defaultValue otherwise.
*/
const char *get(const char *section, const char *key, const char *defaultValue = nullptr) const;
/**
* @brief Translates and returns the value of a key as a boolean.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return true if key exists and is not "false" or "0", defaultValue otherwise.
*/
bool getBool(const char *section, const char *key, bool defaultValue = false) const;
/**
* @brief Translates and returns the value of a key as a short.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return short value of the key if it exits, defaultValue otherwise.
*/
short getShort(const char *section, const char *key, short defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as an int.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return int value of the key if it exits, defaultValue otherwise.
*/
int getInt(const char *section, const char *key, int defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as a long.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return long value of the key if it exits, defaultValue otherwise.
*/
long getLong(const char *section, const char *key, long defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as a long long.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return long long value of the key if it exits, defaultValue otherwise.
*/
long long getLongLong(const char *section, const char *key, long long defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as a float.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return float value of the key if it exits, defaultValue otherwise.
*/
float getFloat(const char *section, const char *key, float defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as a double.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return double value of the key if it exits, defaultValue otherwise.
*/
double getDouble(const char *section, const char *key, double defaultValue = 0) const;
/**
* @brief Translates and returns the value of a key as a long double.
*
* @param section String containing section.
* @param key String containing key name.
* @param defaultValue Value to return if none is found.
* @return long double value of the key if it exits, defaultValue otherwise.
*/
long double getLongDouble(const char *section, const char *key, long double defaultValue = 0) const;
/**
* @brief Default constructor for the INIFile class.
*/
INIFile();
/**
* @brief Copy constructor for the INIFile class.
*/
INIFile(const INIFile &);
/**
* @brief Destructor for the INIFile class.
*/
~INIFile();
/** Private members */
private:
struct Data;
Data *data_;
};
}
#endif // _INIFILE_H_HEADER

8
Jupiter/IRC.cpp

@ -0,0 +1,8 @@
#include "IRC.h"
const char Jupiter::IRC::CTCP = IRCCTCP[0]; /** IRC CTCP character */
const char Jupiter::IRC::bold = IRCBOLD[0]; /** IRC bold character */
const char Jupiter::IRC::color = IRCCOLOR[0]; /** IRC color character */
const char Jupiter::IRC::normal = IRCNORMAL[0]; /** IRC normal character */
const char Jupiter::IRC::reverse = IRCREVERSE[0]; /** IRC reverse character */
const char Jupiter::IRC::underline = IRCUNDERLINE[0]; /** IRC underline character */

54
Jupiter/IRC.h

@ -0,0 +1,54 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _IRC_H_HEADER
#define _IRC_H_HEADER
/**
* @file IRC.h
* @brief Defines IRC protocol constants.
*/
#include "Jupiter.h"
/** Special Character Definitions */
#define IRCCTCP "\001" /** IRC CTCP character contained in a string literal */
#define IRCBOLD "\002" /** IRC bold character contained in a string literal */
#define IRCCOLOR "\003" /** IRC color character contained in a string literal */
#define IRCNORMAL "\017" /** IRC normal character contained in a string literal */
#define IRCREVERSE "\026" /** IRC reverse character contained in a string literal */
#define IRCUNDERLINE "\037" /** IRC underline character contained in a string literal */
#if defined __cplusplus
namespace Jupiter
{
namespace IRC
{
JUPITER_API extern const char CTCP; /** IRC CTCP character */
JUPITER_API extern const char bold; /** IRC bold character */
JUPITER_API extern const char color; /** IRC color character */
JUPITER_API extern const char normal; /** IRC normal character */
JUPITER_API extern const char reverse; /** IRC reverse character */
JUPITER_API extern const char underline; /** IRC underline character */
}
}
#endif // __cplusplus
#endif // _IRC_H_HEADER

1743
Jupiter/IRC_Client.cpp

File diff suppressed because it is too large

874
Jupiter/IRC_Client.h

@ -0,0 +1,874 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _IRC_CLIENT_H_HEADER
#define _IRC_CLIENT_H_HEADER
/**
* @file IRC Client.h
* @brief Provides connectivity to IRC servers.
*/
#include <cstdlib>
#include <cstdio>
#include "Jupiter.h"
#include "Thinker.h"
#include "IRC.h"
#include "CString.h"
#define CONFIG_INI "Config.ini" /** Default location of the Config file. */
namespace Jupiter
{
class INIFile; /** Forward declaration for Jupiter::INIFile. See Jupiter::INIFile in INIFile.h. */
namespace IRC
{
/**
* @brief Provides connectivity to IRC servers.
*/
class JUPITER_API Client : public Thinker
{
protected:
/**
* @brief This is called when a connection has been successfully established.
* The current implementation calls this after the MOTD.
*/
virtual void OnConnect();
/**
* @brief This is called when at the end of disconnect().
* This is called upon any connection failure or error.
*/
virtual void OnDisconnect();
/**
* @brief This is called when at the end of reconnect().
*
* @param successConnect Used to determine if a connection was successfully established.
* @see connect().
*/
virtual void OnReconnectAttempt(bool successConnect);
/**
* @brief This is called after a message has been normally processed.
* This always happens last. All other hooks will be called before this.
*
* @param raw The raw message.
*/
virtual void OnRaw(const StringType &raw);
/**
* @brief This is called after an IRC numeric has been processed.
*
* @param raw The raw message.
*/
virtual void OnNumeric(long int numeric, const StringType &raw);
/**
* @brief This is called when an ERROR is received.
* This indicates a connection termination, and thus, disconnect() is called immediately after this.
*
* @param message Message sent by the server.
*/
virtual void OnError(const StringType &message);
/**
* @brief This is called when a chat message is received.
*
* @param channel String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnChat(const StringType &channel, const StringType &nick, const StringType &message);
/**
* @brief This is called when a notice is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnNotice(const StringType &chan, const StringType &sender, const StringType &message);
/**
* @brief This is called when a server notice is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the sender.
* @param message String containing the message sent.
*/
virtual void OnServerNotice(const StringType &chan, const StringType &sender, const StringType &message);
/**
* @brief This is called when a CTCP message is received.
*
* @param channel String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnCTCP(const StringType &channel, const StringType &nick, const StringType &command, const StringType &message);
/**
* @brief This is called when an action message is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnAction(const StringType &chan, const StringType &nick, const StringType &message);
/**
* @brief This is called when an invite is received.
*
* @param chan String containing the destination of the message.
* @param inviter String containing the nickname of the inviter.
* @param invited String containing the nickname of the user invited.
*/
virtual void OnInvite(const StringType &chan, const StringType &inviter, const StringType &invited);
/**
* @brief This is called when a chat message is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnJoin(const StringType &chan, const StringType &nick);
/**
* @brief This is called when a user parts a channel.
*
* @param chan String containing the channel parted from.
* @param nick String containing the nickname of the user.
* @param reason String containing the reason for parting, or nullptr if none is specified.
*/
virtual void OnPart(const StringType &chan, const StringType &nick, const StringType &reason);
/**
* @brief This is called when a user changes their nickname.
*
* @param oldnick String containing the old nickname of the user.
* @param newnick String containing the new nickname of the user.
*/
virtual void OnNick(const StringType &oldnick, const StringType &newnick);
/**
* @brief This is called when a user is kicked from a channel.
*
* @param chan String containing the channel kicked from.
* @param kicker String containing the nickname of the kicker.
* @param kicked String containing the nickname of the user kicked.
* @param reason String containing the reason for the kick, or nullptr if none is specified.
*/
virtual void OnKick(const StringType &chan, const StringType &kicker, const StringType &kicked, const StringType &reason);
/**
* @brief This is called when a user quits the server.
*
* @param nick String containing the nickname of the user.
* @param message String containing the reason for quiting.
*/
virtual void OnQuit(const StringType &nick, const StringType &message);
/**
* @brief This is called when a channel mode is changed.
*
* @param chan String containing the affected channel.
* @param nick String containing the nickname of the user.
* @param modeString String containing the modes changed.
*/
virtual void OnMode(const Jupiter::StringType &chan, const Jupiter::StringType &nick, const Jupiter::StringType &modeString);
public:
static INIFile *Config; /** IRC client config file. This is automatically instantiated upon library initialization. */
class Channel;
/**
* @brief Stores data about users.
*/
class JUPITER_API User
{
friend class Jupiter::IRC::Client;
friend class Jupiter::IRC::Client::Channel;
public:
/**
* @brief Fetches the user's nickname.
*
* @return String containing the user's nickname.
*/
const Jupiter::StringType &getNickname() const;
/**
* @brief Fetches the user's username.
*
* @return String containing the user's username.
*/
const Jupiter::StringType &getUsername() const;
/**
* @brief Fetches the user's hostname.
*
* @return String containing the user's hostname.
*/
const Jupiter::StringType &getHostname() const;
/**
* @brief Returns the number of channels the user shares with the local client.
*
* @return Number of channels.
*/
unsigned int getChannelCount() const;
User();
~User();
/** Private members */
private:
struct Data;
Data *data_;
};
/**
* @brief Provides interfacing with channels and stores channel data.
*/
class JUPITER_API Channel
{
friend class Jupiter::IRC::Client;
public:
/**
* @brief Stores data about users.
*/
class JUPITER_API User
{
friend class Jupiter::IRC::Client::Channel;
public:
/**
* @brief Returns the local user's global user object.
*
* @return Local user's global user object.
*/
Jupiter::IRC::Client::User *getUser() const;
/**
* @brief Returns the user's string of channel prefixes.
*
* @return String containing the user's channel prefixes.
*/
const Jupiter::StringType &getPrefixes() const;
/**
* @brief Fetches the user's nickname.
*
* @return String containing the user's nickname.
*/
const Jupiter::StringType &getNickname() const;
/**
* @brief Fetches the user's username.
*
* @return String containing the user's username.
*/
const Jupiter::StringType &getUsername() const;
/**
* @brief Fetches the user's hostname.
*
* @return String containing the user's hostname.
*/
const Jupiter::StringType &getHostname() const;
/**
* @brief Returns the number of channels the user shares with the local client.
*
* @return Number of channels.
*/
unsigned int getChannelCount() const;
User();
~User();
/** Private members */
private:
struct Data;
Data *data_;
};
/**
* @brief Returns the name of the channel.
*
* @return String containing the name of the channel.
*/
const StringType &getName() const;
/**
* @brief Returns a user at an index.
*
* @param index The index of the user.
* @return A user if within range, nullptr otherwise.
*/
Jupiter::IRC::Client::Channel::User *getUser(unsigned int index) const;
/**
* @brief Searches for a user based on their nickname.
*
* @param nickname String containing the nickname of the user to find.
* @return A user if a match is found, nullptr otherwise.
*/
Jupiter::IRC::Client::Channel::User *getUser(const char *nickname) const;
/**
* @brief Adds a user to the channel
*
* @param nickname Nickname of the user.
* @return Index of the new user.
*/
unsigned int addUser(Jupiter::IRC::Client::User *user);
/**
* @brief Adds a user to the channel
*
* @param nickname Nickname of the user.
* @param prefix The user's prefix.
* @return Index of the new user.
*/
unsigned int addUser(Jupiter::IRC::Client::User *user, const char prefix);
/**
* @brief Removes a user from the channel.
*
* @param nickname String containing the nickname of the user.
*/
void delUser(const char *nickname);
/**
* @brief Removes a user from the channel.
*
* @param index Index of a user.
*/
void delUser(unsigned int index);
/**
* @brief Adds a prefix to a user.
*
* @param index Index of a user.
* @param prefix Prefix to add to the user.
*/
void addUserPrefix(unsigned int index, char prefix);
/**
* @brief Adds a prefix to a user.
*
* @param user String containing the nickname of the user.
* @param prefix Prefix to add to the user.
*/
void addUserPrefix(const char *user, char prefix);
/**
* @brief Removes a prefix from a user.
*
* @param index Index of a user.
* @param prefix Prefix to remove from the user.
*/
void delUserPrefix(unsigned int index, char prefix);
/**
* @brief Removes a prefix from a user.
*
* @param user String containing the nickname of a user.
* @param prefix Prefix to remove from the user.
*/
void delUserPrefix(const char *user, char prefix);
/**
* @brief Returns the index of a user.
*
* @param user String containing the nickname of a user.
* @return Index of a user if they're found, -1 otherwise.
*/
int getUserIndex(const char *user) const;
/**
* @brief Returns the index of a user.
*
* @param user String containing part of the nickname of a user.
* @return Index of a user if they're found, -1 otherwise.
*/
int getUserIndexByPartName(const char *user) const;
/**
* @brief Returns a user's most significant prefix.
*
* @param index Index of a user.
* @return User's most significant prefix.
*/
char getUserPrefix(unsigned int index) const;
/**
* @brief Returns a user's most significant prefix.
*
* @param user String containing the nickname of a user.
* @return User's most significant prefix.
*/
char getUserPrefix(const char *user) const;
/**
* @brief Returns the number of users in this channel.
*
* @return Number of users.
*/
unsigned int getUserCount() const;
/**
* @brief Returns the type of this channel.
*
* @return Type of this channel.
*/
int getType() const;
/**
* @brief Sets the type of this channel.
*
* @param iType Type to set this channel to.
*/
void setType(int iType);
/**
* @brief Constructor for Channel
*
* @param channelName String containing the name of a channel.
* @param iFace Server in which this channel is located.
*/
Channel(const char *channelName, Client *iFace);
/**
* @brief Destructor for Channel
*/
~Channel();
/** Private members */
private:
struct Data;
Data *data_;
}; // Jupiter::IRC::Client::Channel class
/**
* @brief Returns the config section this refers to.
*
* @return String containing a config section.
*/
const StringType &getConfigSection() const;
/**
* @brief Returns the name of the file this logs to.
*
* @return String containing a log file's name.
*/
const StringType &getLogFile() const;
/**
* @brief Returns the nickname prefixes supported by the connected server.
*
* @return String containing nickname prefixes.
*/
const StringType &getPrefixes() const;
/**
* @brief Returns the client's current nickname.
*
* @return String containing a nickame.
*/
const StringType &getNickname() const;
/**
* @brief Returns the client's real name.
*
* @return String containing a name.
*/
const StringType &getRealname() const;
/**
* @brief Returns the server's name
*
* @return String containing the server's name.
*/
const StringType &getServerName() const;
/**
* @brief Returns the server's hostname.
* Note: This is the same as the config's value.
*
* @return String containing a hostname.
*/
const StringType &getServerHostname() const;
/**
* @brief Returns the server's port.
* Note: This is the same as the config's value.
*
* @return Port used to connect.
*/
unsigned short getServerPort() const;
/**
* @brief Returns the time delay between reconnect attempts.
*
* @return Time delay between reconnect attemps.
*/
time_t getReconnectDelay() const;
/**
* @brief Returns the time scheduled to make a reconenct attempt.
* This is the sum of the time of disconnection and the reconnection time delay.
*
* @return Time scheduled.
*/
time_t getReconnectTime() const;
/**
* @brief Returns the number of consecutive reconnect attempts executed so far.
*
* @return Number of reconnects attempted.
*/
int getReconnectAttempts() const;
/**
* @brief Returns the maximum number of consecutive reconnect attempts to make before failing.
*
* @return Maximum number of reconnect attempts.
*/
int getMaxReconnectAttempts() const;
/**
* @brief Returns the default channel type.
*
* @return Default channel type.
*/
short getDefaultChanType() const;
/**
* @brief Returns if this prints to stdout.
*
* @return True if it prints, false otherwise.
*/
FILE *getPrintOutput() const;
/**
* @brief Sets where to print output.
*
* @param outf FILE object to output to.
* Note: outf must be either a valid and open FILE pointer, or nullptr to disable output.
*/
void setPrintOutput(FILE *outf);
/**
* @brief Fetches a user from the user list.
*
* @param index Index of the user to fetch.
* @return User located at the specified index.
*/
Jupiter::IRC::Client::User *getUser(unsigned int index) const;
/**
* @brief Fetches a user from the user list.
*
* @param nickname String containing the nickname of the user to fetch.
* @return A User if a match is found, nullptr otherwise.
*/
Jupiter::IRC::Client::User *getUser(const char *nickname) const;
/**
* @brief Fetches a user's index from the user list.
*
* @param nickname String containing the nickname of the user to fetch.
* @return The index of a user if a match is found, -1 otherwise.
*/
int getUserIndex(const char *nickname) const;
/**
* @brief Fetches a user's index from the user list.
*
* @param user Pointer to a user's data.
* @return The index of a user if a match is found, -1 otherwise.
*/
int getUserIndex(Jupiter::IRC::Client::User *user) const;
/**
* @brief Fetches the size of the user list.
*
* @return Size of the user list.
*/
unsigned int getUserCount() const;
/**
* @brief Returns the number of channels.
*
* @return Number of channels.
*/
unsigned int getChannelCount() const;
/**
* @brief Returns a channel.
*
* @param index Index of the chanel to return.
* @return The channel at index.
*/
Channel *getChannel(unsigned int index) const;
/**
* @brief Returns a channel.
*
* @param chanName String containing the name of a channel.
* @return The channel at index.
*/
Channel *getChannel(const char *chanName) const;
/**
* @brief Returns a channel's name at index.
*
* @param index Index of the channel.
* @return Channel's name.
*/
const StringType &getChannelName(unsigned int index) const;
/**
* @brief Returns the index of the channel with a given name.
*
* @param chanName String containing the name of a channel.
* @return Index of a channel if a match is found, -1 otherwise.
*/
int getChannelIndex(const char *chanName) const;
/**
* @brief Sends a join request.
*
* @param channel Channel to join.
*/
void joinChannel(const char *channel);
/**
* @brief Sends a join request with a password.
*
* @param channel Channel to join.
* @param password Password to use.
*/
void joinChannel(const char *channel, const char *password);
/**
* @brief Parts a channel.
*
* @param channel Channel to part.
*/
void partChannel(const char *channel);
/**
* @brief Parts a channel.
*
* @param channel Channel to part.
* @param message Reason for parting.
*/
void partChannel(const char *channel, const char *message);
/**
* @brief Gets the access level of a user.
*
* @param chan String containing a channel name to get the access level from.
* @param nick String containing the nickname of the user.
* @return Access level of the user.
*/
int getAccessLevel(const char *chan, const char *nick) const;
/**
* @brief Sends a message.
*
* @param dest String containing the destination of the message (nickname or channel).
* @param message String containing the message to send.
*/
void sendMessage(const char *dest, const char *message);
/**
* @brief Sends a notice.
*
* @param dest String containing the destination of the message (nickname or channel).
* @param message String containing the message to send.
*/
void sendNotice(const char *dest, const char *message);
/**
* @brief Sends a message to all channels of a given type.
*
* @param type Type of channel to messasge.
* @param message String containing the message to send.
* @return Number of messages sent.
*/
unsigned int messageChannels(short type, const char *message);
/**
* @brief Sends a message to all channels with a type of at least 0.
*
* @param message String containing the message to send.
* @return Number of messages sent.
*/
unsigned int messageChannels(const char *message);
/**
* @brief Returns if the client will automatically reconnect upon failure.
*
* @return True if the server will automatically reconnect, false otherwise.
*/
bool isAutoReconnect() const;
/**
* @brief Sets how many times the client should attempt to automatically reconnect.
*
* @param autoReconnect Maximum number of reconnect attempts. A negative value indicates infinity.
*/
void setAutoReconnect(int autoReconnect);
/**
* @brief Sends data to the server.
* Endlines are automatically added.
*
* @param rawMessage String containing the data to send.
*/
void send(const char *rawMessage);
/**
* @brief Method that is called by think() to handle all of the IRC protocol.
* Note: This command should not be used unless you wish to bypass auto-reconnect abilities. Use think() instead.
*
* @return 0 upon success, an error code otherwise.
*/
int primaryHandler();
/**
* @brief Returns a key's value.
* This reads from the client's config section first, then default if it doesn't exist.
*
* @param key String containing the key name.
* @return String containing the key value if it exists, defaultValue otherwise.
*/
Jupiter::CStringS readConfigValue(const char *key, const char *defaultValue = nullptr) const;
/**
* @brief Returns a key's value as a boolean.
* This reads from the client's config section first, then default if it doesn't exist.
*
* @param key String containing the key name.
* @return Boolean value of the key value if it exists, defaultValue otherwise.
*/
bool readConfigBool(const char *key, bool defaultValue = false) const;
/**
* @brief Returns a key's value as an integer.
* This reads from the client's config section first, then default if it doesn't exist.
*
* @param key String containing the key name.
* @return Integer value of the key value if it exists, defaultValue otherwise.
*/
int readConfigInt(const char *key, int defaultValue = 0) const;
/**
* @brief Returns a key's value as a long integer.
* This reads from the client's config section first, then default if it doesn't exist.
*
* @param key String containing the key name.
* @return Long integer value of the key value if it exists, defaultValue otherwise.
*/
long readConfigLong(const char *key, long defaultValue = 0) const;
/**
* @brief Returns a key's value as a double.
* This reads from the client's config section first, then default if it doesn't exist.
*
* @param key String containing the key name.
* @return Double value of the key value if it exists, defaultValue otherwise.
*/
double readConfigDouble(const char *key, double defaultValue = 0) const;
/**
* @brief Writes to the server's log file.
*
* @param message String containing the text to write to the file.
*/
void writeToLogs(const char *message);
/**
* @brief Connects the client to its server.
* Note: This should not be called unless it is not already connected to a server.
* Also, a successful socket connection does not mean the server accepted the connection.
*
* @return True upon successful socket connection, false otherwise.
*/
bool connect();
/**
* @brief Completely disconnects the client from a server.
* Note: This does not send any type of QUIT message.
*/
void disconnect(bool stayDead = false);
/**
* @brief Completely disconnects the client from a server.
*
* @param message String containing the QUIT message to send prior to disconnecting.
*/
void disconnect(const char *message, bool stayDead = false);
/**
* @brief Calls disconnect() if the client has not already, then calls connect().
* Note: This will increment the current reconnect attempts by 1.
*/
void reconnect();
/**
* @brief Method to be looped to sustain the IRC connection.
* Note: This client should be deleted if this returns anything other than 0.
*
* @return 0 if the client should still exist, error code otherwise.
*/
virtual int think();
/**
* @brief Constructor for a client.
*
* @param configSection String containing the config section for the client to read from, before defaulting to "Default".
*/
Client(const char *configSection);
/**
* @brief Destructor for a client.
*/
virtual ~Client();
/** Private members */
private:
struct Data;
Data *data_;
}; // Jupiter::IRC::Client class
} // Jupiter::IRC namespace
} // Jupiter namespace
#endif // _IRC_CLIENT_H_HEADER

708
Jupiter/IRC_Numerics.h

@ -0,0 +1,708 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _IRC_NUMERICS_H_HEADER
#define _IRC_NUMERICS_H_HEADER
/**
* These numerics are in large part found here: https://www.alien.net.au/irc/irc2numerics.html
* Not all numerics from the above list are included (generally conflicting numerics such as RPL_MAP).
*/
/**
* To enable the shorter definitions (those without IRC_ in front), define "SHORT_IRC_MACROS" prior to including this file.
*/
#if !defined SKIP_IRC_MACROS
#define IRC_RPL_WELCOME 1 /** RFC2812: Post-registration welcome message. */
#define IRC_RPL_YOURHOST 2 /** RFC2812: Post-registration. Your host is this server and I am running some daemon */
#define IRC_RPL_CREATED 3 /** RFC2812: Post-registration. This was was created at some point in time */
#define IRC_RPL_MYINFO 4 /** RFC2812: Post-registration. <server_name> <version> <user_modes> <chan_modes> */
#define IRC_RPL_BOUNCEOLD 5 /** RFC2812/DEPRECATED: 005 is rarely used as a bounce indicator, but was defined in RFC2812. */
#define IRC_RPL_ISUPPORT 5 /** Used to indicate what a server supports. Does not appear in any RFC, but was drafted in 2004. */
#define IRC_RPL_PROTOCTL IRC_RPL_ISUPPORT /** Use IRC_RPL_ISUPPORT instead */
#define IRC_RPL_SNOMASK 8 /** Server notice mask */
#define IRC_RPL_STATMEMTOT 9 /** I have no idea what this does. */
#define IRC_RPL_BOUNCE 10 /** Bounce server message. Different syntax from IRC_RPL_BOUNCEOLD */
#define IRC_RPL_STATMEM 10 /** I have no idea what this does. */
#define IRC_RPL_YOURCOOKIE 14 /** I have no idea what this does. */
#define IRC_RPL_YOURID 42 /** Informs you of your unique ID. */
#define IRC_RPL_SAVENICK 43 /** Your nick was force-changed due to a nick collision */
#define IRC_RPL_ATTEMPTINGJUNC 50 /** I have no idea what this does. */
#define IRC_RPL_ATTEMPTINGREROUTE 51 /** I have no idea what this does. */
#define IRC_RPL_TRACELINK 200 /** RFC1459: "If the TRACE message is destined for another server, all intermediate servers must return a IRC_RPL_TRACELINK reply to indicate that the TRACE passed through it and where its going next."*/
#define IRC_RPL_TRACECONNECTING 201 /** RFC1459 */
#define IRC_RPL_TRACEHANDSHAKE 202 /** RFC1459 */
#define IRC_RPL_TRACEUNKNOWN 203 /** RFC1459 */
#define IRC_RPL_TRACEOPERATOR 204 /** RFC1459 */
#define IRC_RPL_TRACEUSER 205 /** RFC1459 */
#define IRC_RPL_TRACESERVER 206 /** RFC1459 */
#define IRC_RPL_TRACESERVICE 207 /** RFC2812 */
#define IRC_RPL_TRACENEWTYPE 208 /** RFC1459 */
#define IRC_RPL_TRACECLASS 209 /** RFC2812 */
#define IRC_RPL_TRACERECONNECT 210 /** RFC2812 */
#define IRC_RPL_STATS 210 /** I have no idea what this does. */
#define IRC_RPL_STATSLINKINFO 211 /** RFC1459 */
#define IRC_RPL_STATSCOMMANDS 212 /** RFC1459 */
#define IRC_RPL_STATSCLINE 213 /** RFC1459 */
#define IRC_RPL_STATSNLINE 214 /** RFC1459 */
#define IRC_RPL_STATSILINE 215 /** RFC1459 */
#define IRC_RPL_STATSKLINE 216 /** RFC1459 */
#define IRC_RPL_STATSQLINE 217 /** RFC1459 */
#define IRC_RPL_STATSYLINE 218 /** RFC1459 */
#define IRC_RPL_ENDOFSTATS 219 /** RFC1459 */
#define IRC_RPL_UMODEIS 221 /** RFC1459 */
#define IRC_RPL_SERVICEINFO 231 /** RFC1459 */
#define IRC_RPL_ENDOFSERVICES 232 /** RFC1459 */
#define IRC_RPL_SERVICE 233 /** RFC1459 */
#define IRC_RPL_SERVLIST 234 /** RFC2812 */
#define IRC_RPL_STATSVERBOSE 236 /** I have no idea what this does. */
#define IRC_RPL_STATSENGINE 237 /** I have no idea what this does. */
#define IRC_RPL_STATSIAUTH 239 /** I have no idea what this does. */
#define IRC_RPL_STATSLLINE 241 /** RFC1459 */
#define IRC_RPL_STATSUPTIME 242 /** RFC1459 */
#define IRC_RPL_STATSOLINE 243 /** RFC1459 */
#define IRC_RPL_STATSHLINE 244 /** RFC1459 */
#define IRC_RPL_STATSSLINE 245 /** I have no idea what this does. */
#define IRC_RPL_STATSPING 246 /** RFC2812 */
#define IRC_RPL_STATSCONN 250 /** I have no idea what this does. */
#define IRC_RPL_LUSERCLIENT 251 /** RFC1459 */
#define IRC_RPL_LUSEROP 252 /** RFC1459 */
#define IRC_RPL_LUSERUNKNOWN 253 /** RFC1459 */
#define IRC_RPL_LUSERCHANNELS 254 /** RFC1459 */
#define IRC_RPL_LUSERME 255 /** RFC1459 */
#define IRC_RPL_ADMINME 256 /** RFC1459 */
#define IRC_RPL_ADMINLOC1 257 /** RFC1459 */
#define IRC_RPL_ADMINLOC2 258 /** RFC1459 */
#define IRC_RPL_ADMINEMAIL 259 /** RFC1459 */
#define IRC_RPL_TRACELOG 261 /** RFC1459 */
#define IRC_RPL_TRACEEND 262 /** RFC2812 */
#define IRC_RPL_TRYAGAIN 263 /** RFC2812 */
#define IRC_RPL_LOCALUSERS 265 /** I have no idea what this does. */
#define IRC_RPL_CURRENT_LOCAL IRC_RPL_LOCALUSERS /** Use IRC_RPL_GLOBALUSERS */
#define IRC_RPL_GLOBALUSERS 266 /** I have no idea what this does. */
#define IRC_RPL_CURRENT_GLOBAL IRC_RPL_GLOBALUSERS /** Use IRC_RPL_GLOBALUSERS */
#define IRC_RPL_START_NETSTAT 267 /** I have no idea what this does. */
#define IRC_RPL_NETSTAT 268 /** I have no idea what this does. */
#define IRC_RPL_END_NETSTAT 269 /** I have no idea what this does. */
#define IRC_RPL_PRIVS 270 /** I have no idea what this does. */
#define IRC_RPL_SILELIST 271 /** I have no idea what this does. */
#define IRC_RPL_ENDOFSILELIST 272 /** I have no idea what this does. */
#define IRC_RPL_NOTIFY 273 /** I have no idea what this does. */
#define IRC_RPL_VCHANEXIST 276 /** I have no idea what this does. */
#define IRC_RPL_VCHANLIST 277 /** I have no idea what this does. */
#define IRC_RPL_VCHANHELP 278 /** I have no idea what this does. */
#define IRC_RPL_GLIST 280 /** I have no idea what this does. */
#define IRC_RPL_CHANINFO_KICKS 296 /** I have no idea what this does. */
#define IRC_RPL_END_CHANINFO 299 /** I have no idea what this does. */
#define IRC_RPL_NONE 300 /** RFC1459 */
#define IRC_RPL_AWAY 301 /** RFC1459 */
#define IRC_RPL_USERHOST 302 /** RFC1459 */
#define IRC_RPL_ISON 303 /** RFC1459 */
#define IRC_RPL_TEXT 304 /** I have no idea what this does. Supposedly deprecated? */
#define IRC_RPL_UNAWAY 305 /** RFC1459 */
#define IRC_RPL_NOWAWAY 306 /** RFC1459 */
#define IRC_RPL_WHOISUSER 311 /** RFC1459 */
#define IRC_RPL_WHOISSERVER 312 /** RFC1459 */
#define IRC_RPL_WHOISOPERATOR 313 /** RFC1459 */
#define IRC_RPL_WHOWASUSER 314 /** RFC1459 */
#define IRC_RPL_ENDOFWHO 315 /** RFC1459 */
#define IRC_RPL_WHOISCHANOP 316 /** RFC1459 */
#define IRC_RPL_WHOISIDLE 317 /** RFC1459 */
#define IRC_RPL_ENDOFWHOIS 318 /** RFC1459 */
#define IRC_RPL_WHOISCHANNELS 319 /** RFC1459 */
#define IRC_RPL_WHOISVIRT 320 /** I have no idea what this does. */
#define IRC_RPL_WHOIS_HIDDEN 320 /** I have no idea what this does. */
#define IRC_RPL_WHOISSPECIAL 320 /** I have no idea what this does. */
#define IRC_RPL_LISTSTART 321 /** RFC1459 */
#define IRC_RPL_LIST 322 /** RFC1459 */
#define IRC_RPL_LISTEND 323 /** RFC1459 */
#define IRC_RPL_CHANNELMODEIS 324 /** RFC1459 */
#define IRC_RPL_UNIQOPIS 325 /** RFC2812 */
#define IRC_RPL_NOCHANPASS 326 /** I have no idea what this does. */
#define IRC_RPL_CHPASSUNKNOWN 327 /** I have no idea what this does. */
#define IRC_RPL_CHANNEL_URL 328 /** I have no idea what this does. */
#define IRC_RPL_CREATIONTIME 329 /** I have no idea what this does. */
#define IRC_RPL_NOTOPIC 331 /** RFC1459 */
#define IRC_RPL_TOPIC 332 /** RFC1459 */
#define IRC_RPL_TOPICWHOTIME 333 /** I have no idea what this does. */
#define IRC_RPL_BADCHANPASS 339 /** I have no idea what this does. */
#define IRC_RPL_USERIP 340 /** I have no idea what this does. */
#define IRC_RPL_INVITING 341 /** RFC1459 */
#define IRC_RPL_SUMMONING 342 /** RFC1459 */
#define IRC_RPL_INVITED 345 /** I have no idea what this does. */
#define IRC_RPL_INVITELIST 346 /** RFC2812 */
#define IRC_RPL_ENDOFINVITELIST 347 /** RFC2812 */
#define IRC_RPL_EXCEPTLIST 348 /** RFC2812 */
#define IRC_RPL_ENDOFEXCEPTLIST 349 /** RFC2812 */
#define IRC_RPL_VERSION 351 /** RFC1459 */
#define IRC_RPL_WHOREPLY 352 /** RFC1459 */
#define IRC_RPL_NAMREPLY 353 /** RFC1459 */
#define IRC_RPL_WHOSPCRPL 354 /** I have no idea what this does. */
#define IRC_RPL_NAMREPLY_ 355 /** I have no idea what this does. */
#define IRC_RPL_KILLDONE 361 /** RFC1459 */
#define IRC_RPL_CLOSING 362 /** RFC1459 */
#define IRC_RPL_CLOSEEND 363 /** RFC1459 */
#define IRC_RPL_LINKS 364 /** RFC1459 */
#define IRC_RPL_ENDOFLINKS 365 /** RFC1459 */
#define IRC_RPL_ENDOFNAMES 366 /** RFC1459 */
#define IRC_RPL_BANLIST 367 /** RFC1459 */
#define IRC_RPL_ENDOFBANLIST 368 /** RFC1459 */
#define IRC_RPL_ENDOFWHOWAS 369 /** RFC1459 */
#define IRC_RPL_INFO 371 /** RFC1459 */
#define IRC_RPL_MOTD 372 /** RFC1459 */
#define IRC_RPL_INFOSTART 373 /** RFC1459 */
#define IRC_RPL_ENDOFINFO 374 /** RFC1459 */
#define IRC_RPL_MOTDSTART 375 /** RFC1459 */
#define IRC_RPL_ENDOFMOTD 376 /** RFC1459 */
#define IRC_RPL_YOUREOPER 381 /** RFC1459 */
#define IRC_RPL_REHASHING 382 /** RFC1459 */
#define IRC_RPL_YOURESERVICE 383 /** RFC2812 */
#define IRC_RPL_MYPORTIS 384 /** RFC1459 */
#define IRC_RPL_NOTOPERANYMORE 385 /** You are no longer a server operator */
#define IRC_RPL_ALIST 388 /** I have no idea what this does. */
#define IRC_RPL_ENDOFALIST 389 /** I have no idea what this does. */
#define IRC_RPL_TIME 391 /** RFC1459: TIME command response. <server> [possible extension data] :<time string>*/
#define IRC_RPL_USERSSTART 392 /** RFC1459 */
#define IRC_RPL_USERS 393 /** RFC1459 */
#define IRC_RPL_ENDOFUSERS 394 /** RFC1459 */
#define IRC_RPL_NOUSERS 395 /** I have no idea what this does. */
#define IRC_RPL_HOSTHIDDEN 396 /** Your hostname is now hidden. */
#define IRC_ERR_UNKNOWNERROR 400 /** An unknown error occured. */
#define IRC_ERR_NOSUCHNICK 401 /** RFC1459 */
#define IRC_ERR_NOSUCHSERVER 402 /** RFC1459 */
#define IRC_ERR_NOSUCHCHANNEL 403 /** RFC1459 */
#define IRC_ERR_CANNOTSENDTOCHAN 404 /** RFC1459 */
#define IRC_ERR_TOOMANYCHANNELS 405 /** RFC1459 */
#define IRC_ERR_WASNOSUCHNICK 406 /** RFC1459 */
#define IRC_ERR_TOOMANYTARGETS 407 /** RFC1459 */
#define IRC_ERR_NOSUCHSERVICE 408 /** RFC2812 */
#define IRC_ERR_NOORIGIN 409 /** RFC1459 */
#define IRC_ERR_NORECIPIENT 411 /** RFC1459 */
#define IRC_ERR_NOTEXTTOSEND 412 /** RFC1459 */
#define IRC_ERR_NOTOPLEVEL 413 /** RFC1459 */
#define IRC_ERR_WILDTOPLEVEL 414 /** RFC1459 */
#define IRC_ERR_BADMASK 415 /** RFC2812 */
#define IRC_ERR_TOOMANYMATCHES 416 /** I have no idea what this does. */
#define IRC_ERR_QUERYTOOLONG 416 /** I have no idea what this does. */
#define IRC_ERR_LENGTHTRUNCATED 419 /** I have no idea what this does. */
#define IRC_ERR_UNKNOWNCOMMAND 421 /** RFC1459 */
#define IRC_ERR_NOMOTD 422 /** RFC1459 */
#define IRC_ERR_NOADMININFO 423 /** RFC1459 */
#define IRC_ERR_FILEERROR 424 /** RFC1459 */
#define IRC_ERR_NOOPERMOTD 425 /** There is no operator MOTD. */
#define IRC_ERR_TOOMANYAWAY 429 /** I have no idea what this does. */
#define IRC_ERR_EVENTNICKCHANGE 430 /** Can not change nickname due to channel event. */
#define IRC_ERR_NONICKNAMEGIVEN 431 /** RFC1459: You didn't specify a nickname. */
#define IRC_ERR_ERRONEOUSNICKNAME 432 /** RFC1459: Nickname is reserved or otherwise invalid. */
#define IRC_ERR_ERRONEUSNICKNAME IRC_ERR_ERRONEOUSNICKNAME /** Use IRC_ERR_EERONEOUSNICKNAME instead. */
#define IRC_ERR_NICKNAMEINUSE 433 /** RFC1459: Already used nickname was passed to NICK */
#define IRC_ERR_NICKCOLLISION 436 /** RFC1459: A nickname collision was detected. */
#define IRC_ERR_UNAVAILRESOURCE 437 /** RFC2812: Target is temporarily unreachable. */
#define IRC_ERR_BANNICKCHANGE 437 /** "Ban nick change" */
#define IRC_ERR_TARGETTOOFAST 439 /** I have no idea what this does. */
#define IRC_RPL_INVTOOFAST IRC_ERR_TARGETTOOFAST
#define IRC_RPL_MSGTOOFAST IRC_ERR_TARGETTOOFAST
#define IRC_ERR_SERVICESDOWN 440 /** I have no idea what this does. */
#define IRC_ERR_USERNOTINCHANNEL 441 /** RFC1459 */
#define IRC_ERR_NOTONCHANNEL 442 /** RFC1459 */
#define IRC_ERR_USERONCHANNEL 443 /** RFC1459 */
#define IRC_ERR_NOLOGIN 444 /** RFC1459 */
#define IRC_ERR_SUMMONDISABLED 445 /** RFC1459 */
#define IRC_ERR_USERSDISABLED 446 /** RFC1459 */
#define IRC_ERR_NONICKCHANGE 447 /** I have no idea what this does. */
#define IRC_ERR_NOTIMPLEMENTED 449 /** I have no idea what this does. */
#define IRC_ERR_NOTREGISTERED 451 /** RFC1459: You need to be registered. */
#define IRC_ERR_IDCOLLISION 452 /** I have no idea what this does. */
#define IRC_ERR_NICKLOST 453 /** I have no idea what this does. */
#define IRC_ERR_HOSTILENAME 455 /** I have no idea what this does. */
#define IRC_ERR_ACCEPTFULL 456 /** I have no idea what this does. */
#define IRC_ERR_ACCEPTEXIST 457 /** I have no idea what this does. */
#define IRC_ERR_ACCEPTNOT 458 /** I have no idea what this does. */
#define IRC_ERR_NOHIDING 459 /** I have no idea what this does. */
#define IRC_ERR_NOTFORHALFOPS 460 /** I have no idea what this does. */
#define IRC_ERR_NEEDMOREPARAMS 461 /** RFC1459: Command requires more parameters. */
#define IRC_ERR_ALREADYREGISTERED 462 /** RFC1459: You're already registered. */
#define IRC_ERR_NOPERMFORHOST 463 /** RFC1459: Your host is blocked. */
#define IRC_ERR_PASSWDMISMATCH 464 /** RFC1459: Incorrect or missing server password. */
#define IRC_ERR_YOUREBANNEDCREEP 465 /** RFC1459: You're banned. */
#define IRC_ERR_YOUWILLBEBANNED 466 /** RFC1459: You will soon be banned. */
#define IRC_ERR_KEYSET 467 /** RFC1459: A key for this channel has already been set. */
#define IRC_ERR_LINKSET 469 /** I have no idea what this does. */
#define IRC_ERR_CHANNELISFULL 471 /** RFC1459: That channel is full. */
#define IRC_ERR_UNKNOWNMODE 472 /** RFC1459: That mode is unknown. */
#define IRC_ERR_INVITEONLYCHAN 473 /** RFC1459: That channel is invite-only. */
#define IRC_ERR_BANNEDFROMCHAN 474 /** RFC1459: You're banned from that channel. */
#define IRC_ERR_BADCHANNELKEY 475 /** RFC1459: Channel key was missing/incorrect. */
#define IRC_ERR_BADCHANMASK 476 /** RFC2812: That channel mask is invalid. */
#define IRC_ERR_NOCHANMODES 477 /** RFC2812: Channel does not support mode changes. */
#define IRC_ERR_BANLISTFULL 478 /** RFC2812: Channel access/ban list is full. */
#define IRC_ERR_BADCHANNAME 479 /** I have no idea what this does. */
#define IRC_ERR_LINKFAIL 479 /** I have no idea what this does. */
#define IRC_ERR_NOPRIVILEGES 481 /** RFC1459: You do not have the neccessary privledges. */
#define IRC_ERR_CHANOPRIVSNEEDED 482 /** RFC1459: You do not have the neccessary channel privledges. */
#define IRC_ERR_CANTKILLSERVER 483 /** RFC1459: You can not KILL a server. */
#define IRC_ERR_RESTRICTED 484 /** RFC2812: This connection is "restricted" */
#define IRC_ERR_UNIQOPRIVSNEEDED 485 /** RFC2812: That mode requires "channel creator" privledges. */
#define IRC_ERR_TSLESSCHAN 488 /** I have no idea what this does. */
#define IRC_ERR_NOOPERHOST 491 /** RFC1459: You can not become a server operator. */
#define IRC_ERR_NOSERVICEHOST 492 /** RFC1459 */
#define IRC_ERR_NOFEATURE 493 /** I have no idea what this does. */
#define IRC_ERR_BADFEATURE 494 /** I have no idea what this does. */
#define IRC_ERR_BADLOGTYPE 495 /** I have no idea what this does. */
#define IRC_ERR_BADLOGSYS 496 /** I have no idea what this does. */
#define IRC_ERR_BADLOGVALUE 497 /** I have no idea what this does. */
#define IRC_ERR_ISOPERLCHAN 498 /** I have no idea what this does. */
#define IRC_ERR_CHANOWNPRIVNEEDED 499 /** I have no idea what this does. */
#define IRC_ERR_UMODEUNKNOWNFLAG 501 /** RFC1459: This user mode flag is not recognized. */
#define IRC_ERR_USERSDONTMATCH 502 /** RFC1459: You can not mody/view other users' modes. */
#define IRC_ERR_GHOSTEDCLIENT 503 /** I have no idea what this does. */
#define IRC_ERR_USERNOTONSERV 504 /** I have no idea what this does. */
#define IRC_ERR_SILELISTFULL 511 /** I have no idea what this does. */
#define IRC_ERR_TOOMANYWATCH 512 /** I have no idea what this does. */
#define IRC_ERR_BADPING 513 /** Invalid PING response. */
#define IRC_ERR_NEEDPONG IRC_ERR_BADPING /** Use IRC_ERR_BADPING instead. */
#define IRC_ERR_BADEXPIRE 515 /** I have no idea what this does. */
#define IRC_ERR_DONTCHEAT 516 /** I have no idea what this does. */
#define IRC_ERR_DISABLED 517 /** I have no idea what this does. */
#define IRC_ERR_WHOSYNTAX 522 /** I have no idea what this does. */
#define IRC_ERR_WHOLIMEXCEED 523 /** I have no idea what this does. */
#define IRC_ERR_REMOTEPFX 525 /** I have no idea what this does. */
#define IRC_ERR_PFXUNROUTABLE 526 /** I have no idea what this does. */
#define IRC_ERR_BADHOSTMASK 550 /** I have no idea what this does. */
#define IRC_ERR_HOSTUNAVAIL 551 /** I have no idea what this does. */
#define IRC_ERR_USINGSLINE 552 /** I have no idea what this does. */
#define IRC_RPL_LOGON 600 /** I have no idea what this does. */
#define IRC_RPL_LOGOFF 601 /** I have no idea what this does. */
#define IRC_RPL_WATCHOFF 602 /** I have no idea what this does. */
#define IRC_RPL_WATCHSTAT 602 /** I have no idea what this does. */
#define IRC_RPL_NOWON 604 /** I have no idea what this does. */
#define IRC_RPL_NOWOFF 605 /** I have no idea what this does. */
#define IRC_RPL_WATCHLIST 606 /** I have no idea what this does. */
#define IRC_RPL_ENDOFWATCHLIST 607 /** I have no idea what this does. */
#define IRC_RPL_WATCHCLEAR 608 /** I have no idea what this does. */
#define IRC_RPL_ISLOCOP 611 /** I have no idea what this does. */
#define IRC_RPL_ISNOTOPER 612 /** I have no idea what this does. */
#define IRC_RPL_ENDOFISOPER 613 /** I have no idea what this does. */
#define IRC_RPL_DCCLIST 618 /** I have no idea what this does. */
#define IRC_RPL_OMOTDSTART 624 /** I have no idea what this does. */
#define IRC_RPL_OMOTD 625 /** I have no idea what this does. */
#define IRC_RPL_ENDOFO 626 /** I have no idea what this does. */
#define IRC_RPL_SETTINGS 630 /** I have no idea what this does. */
#define IRC_RPL_ENDOFSETTINGS 631 /** I have no idea what this does. */
#define IRC_RPL_TRACEROUTE_HOP 660 /** I have no idea what this does. */
#define IRC_RPL_TRACEROUTE_START 661 /** I have no idea what this does. */
#define IRC_RPL_MODECHANGEWARN 662 /** I have no idea what this does. */
#define IRC_RPL_CHANREDIR 663 /** I have no idea what this does. */
#define IRC_RPL_SERVMODEIS 664 /** I have no idea what this does. */
#define IRC_RPL_OTHERUMODEIS 665 /** I have no idea what this does. */
#define IRC_RPL_ENDOF_GENERIC 666 /** I have no idea what this does. */
#define IRC_RPL_WHOWASDETAILS 667 /** I have no idea what this does. */
#define IRC_RPL_STARTTLS 670 /** Proceed with SSL/TLS initialization */
#define IRC_RPL_WHOISSECURE 671 /** User is using a secure connection. */
#define IRC_RPL_UNKNOWNMODES 672 /** I have no idea what this does. */
#define IRC_RPL_CANNOTSETMODES 673 /** I have no idea what this does. */
#define IRC_RPL_LUSERSTAFF 678 /** I have no idea what this does. */
#define IRC_RPL_TIMEONSERVERIS 679 /** I have no idea what this does. */
#define IRC_RPL_NETWORKS 682 /** I have no idea what this does. */
#define IRC_RPL_YOURLANGUAGEIS 687 /** I have no idea what this does. */
#define IRC_RPL_LANGUAGE 688 /** I have no idea what this does. */
#define IRC_RPL_WHOISSTAFF 689 /** I have no idea what this does. */
#define IRC_RPL_WHOISLANGUAGE 690 /** I have no idea what this does. */
#define IRC_ERR_STARTTLS 691 /** An error occured setting up SSL/TLS server-side */
#define IRC_RPL_MODLIST 702 /** I have no idea what this does. */
#define IRC_RPL_ENDOFMODLIST 703 /** I have no idea what this does. */
#define IRC_RPL_HELPSTART 704 /** I have no idea what this does. */
#define IRC_RPL_HELPTXT 705 /** I have no idea what this does. */
#define IRC_RPL_ENDOFHELP 706 /** I have no idea what this does. */
#define IRC_RPL_ETRACEFULL 708 /** I have no idea what this does. */
#define IRC_RPL_ETRACE 709 /** I have no idea what this does. */
#define IRC_RPL_KNOCK 710 /** I have no idea what this does. */
#define IRC_RPL_KNOCKDLVR 711 /** I have no idea what this does. */
#define IRC_RPL_TOOMANYKNOCK 712 /** I have no idea what this does. */
#define IRC_RPL_CHANOPEN 713 /** I have no idea what this does. */
#define IRC_RPL_KNOCKONCHAN 714 /** I have no idea what this does. */
#define IRC_RPL_KNOCKDISABLED 715 /** I have no idea what this does. */
#define IRC_RPL_TARGUMODEG 716 /** I have no idea what this does. */
#define IRC_RPL_TARGNOTIFY 717 /** I have no idea what this does. */
#define IRC_RPL_UMODEGMSG 718 /** I have no idea what this does. */
//#define IRC_RPL_OMOTDSTART 720 /** I have no idea what this does. */
//#define IRC_RPL_OMOTD 721 /** I have no idea what this does. */
//#define IRC_RPL_ENDOFOMOTD 722 /** I have no idea what this does. */
#define IRC_RPL_NOPRIVS 723 /** I have no idea what this does. */
#define IRC_RPL_TESTMARK 724 /** I have no idea what this does. */
#define IRC_RPL_TESTLINE 725 /** I have no idea what this does. */
#define IRC_RPL_NOTESTLINE 726 /** I have no idea what this does. */
#define IRC_RPL_XINFO 771 /** I have no idea what this does. */
#define IRC_RPL_XINFOSTART 773 /** I have no idea what this does. */
#define IRC_RPL_XINFOEND 774 /** I have no idea what this does. */
#define IRC_RPL_CANNOTDOCOMMAND 972 /** I have no idea what this does. */
#define IRC_RPL_CANNOTCHANGEUMODE 973 /** I have no idea what this does. */
#define IRC_RPL_CANNOTCHANGECHANMODE 974 /** I have no idea what this does. */
#define IRC_RPL_CANNOTCHANGESERVERMODE 975 /** I have no idea what this does. */
#define IRC_RPL_CANNOTSENDTONICK 976 /** I have no idea what this does. */
#define IRC_RPL_UNKNOWNSERVERMODE 977 /** I have no idea what this does. */
#define IRC_RPL_SERVERMODELOCK 979 /** I have no idea what this does. */
#define IRC_RPL_BADCHARENCODING 980 /** I have no idea what this does. */
#define IRC_RPL_TOOMANYLANGUAGES 981 /** I have no idea what this does. */
#define IRC_RPL_NOLANGUAGE 982 /** I have no idea what this does. */
#define IRC_RPL_TEXTTOOSHORT 983 /** I have no idea what this does. */
#define IRC_RPL_NUMERIC_ERR 999 /** I have no idea what this does. */
#if defined SHORT_IRC_MACROS
#define RPL_WELCOME 1 /** RFC2812: Post-registration welcome message. */
#define RPL_YOURHOST 2 /** RFC2812: Post-registration. Your host is this server and I am running some daemon */
#define RPL_CREATED 3 /** RFC2812: Post-registration. This was was created at some point in time */
#define RPL_MYINFO 4 /** RFC2812: Post-registration. <server_name> <version> <user_modes> <chan_modes> */
#define RPL_BOUNCEOLD 5 /** RFC2812/DEPRECATED: 005 is rarely used as a bounce indicator, but was defined in RFC2812. */
#define RPL_ISUPPORT 5 /** Used to indicate what a server supports. Does not appear in any RFC, but was drafted in 2004. */
#define RPL_PROTOCTL RPL_ISUPPORT /** Use RPL_ISUPPORT instead */
#define RPL_SNOMASK 8 /** Server notice mask */
#define RPL_STATMEMTOT 9 /** I have no idea what this does. */
#define RPL_BOUNCE 10 /** Bounce server message. Different syntax from RPL_BOUNCEOLD */
#define RPL_STATMEM 10 /** I have no idea what this does. */
#define RPL_YOURCOOKIE 14 /** I have no idea what this does. */
#define RPL_YOURID 42 /** Informs you of your unique ID. */
#define RPL_SAVENICK 43 /** Your nick was force-changed due to a nick collision */
#define RPL_ATTEMPTINGJUNC 50 /** I have no idea what this does. */
#define RPL_ATTEMPTINGREROUTE 51 /** I have no idea what this does. */
#define RPL_TRACELINK 200 /** RFC1459: "If the TRACE message is destined for another server, all intermediate servers must return a RPL_TRACELINK reply to indicate that the TRACE passed through it and where its going next."*/
#define RPL_TRACECONNECTING 201 /** RFC1459 */
#define RPL_TRACEHANDSHAKE 202 /** RFC1459 */
#define RPL_TRACEUNKNOWN 203 /** RFC1459 */
#define RPL_TRACEOPERATOR 204 /** RFC1459 */
#define RPL_TRACEUSER 205 /** RFC1459 */
#define RPL_TRACESERVER 206 /** RFC1459 */
#define RPL_TRACESERVICE 207 /** RFC2812 */
#define RPL_TRACENEWTYPE 208 /** RFC1459 */
#define RPL_TRACECLASS 209 /** RFC2812 */
#define RPL_TRACERECONNECT 210 /** RFC2812 */
#define RPL_STATS 210 /** I have no idea what this does. */
#define RPL_STATSLINKINFO 211 /** RFC1459 */
#define RPL_STATSCOMMANDS 212 /** RFC1459 */
#define RPL_STATSCLINE 213 /** RFC1459 */
#define RPL_STATSNLINE 214 /** RFC1459 */
#define RPL_STATSILINE 215 /** RFC1459 */
#define RPL_STATSKLINE 216 /** RFC1459 */
#define RPL_STATSQLINE 217 /** RFC1459 */
#define RPL_STATSYLINE 218 /** RFC1459 */
#define RPL_ENDOFSTATS 219 /** RFC1459 */
#define RPL_UMODEIS 221 /** RFC1459 */
#define RPL_SERVICEINFO 231 /** RFC1459 */
#define RPL_ENDOFSERVICES 232 /** RFC1459 */
#define RPL_SERVICE 233 /** RFC1459 */
#define RPL_SERVLIST 234 /** RFC2812 */
#define RPL_STATSVERBOSE 236 /** I have no idea what this does. */
#define RPL_STATSENGINE 237 /** I have no idea what this does. */
#define RPL_STATSIAUTH 239 /** I have no idea what this does. */
#define RPL_STATSLLINE 241 /** RFC1459 */
#define RPL_STATSUPTIME 242 /** RFC1459 */
#define RPL_STATSOLINE 243 /** RFC1459 */
#define RPL_STATSHLINE 244 /** RFC1459 */
#define RPL_STATSSLINE 245 /** I have no idea what this does. */
#define RPL_STATSPING 246 /** RFC2812 */
#define RPL_STATSCONN 250 /** I have no idea what this does. */
#define RPL_LUSERCLIENT 251 /** RFC1459 */
#define RPL_LUSEROP 252 /** RFC1459 */
#define RPL_LUSERUNKNOWN 253 /** RFC1459 */
#define RPL_LUSERCHANNELS 254 /** RFC1459 */
#define RPL_LUSERME 255 /** RFC1459 */
#define RPL_ADMINME 256 /** RFC1459 */
#define RPL_ADMINLOC1 257 /** RFC1459 */
#define RPL_ADMINLOC2 258 /** RFC1459 */
#define RPL_ADMINEMAIL 259 /** RFC1459 */
#define RPL_TRACELOG 261 /** RFC1459 */
#define RPL_TRACEEND 262 /** RFC2812 */
#define RPL_TRYAGAIN 263 /** RFC2812 */
#define RPL_LOCALUSERS 265 /** I have no idea what this does. */
#define RPL_CURRENT_LOCAL RPL_LOCALUSERS /** Use RPL_GLOBALUSERS */
#define RPL_GLOBALUSERS 266 /** I have no idea what this does. */
#define RPL_CURRENT_GLOBAL RPL_GLOBALUSERS /** Use RPL_GLOBALUSERS */
#define RPL_START_NETSTAT 267 /** I have no idea what this does. */
#define RPL_NETSTAT 268 /** I have no idea what this does. */
#define RPL_END_NETSTAT 269 /** I have no idea what this does. */
#define RPL_PRIVS 270 /** I have no idea what this does. */
#define RPL_SILELIST 271 /** I have no idea what this does. */
#define RPL_ENDOFSILELIST 272 /** I have no idea what this does. */
#define RPL_NOTIFY 273 /** I have no idea what this does. */
#define RPL_VCHANEXIST 276 /** I have no idea what this does. */
#define RPL_VCHANLIST 277 /** I have no idea what this does. */
#define RPL_VCHANHELP 278 /** I have no idea what this does. */
#define RPL_GLIST 280 /** I have no idea what this does. */
#define RPL_CHANINFO_KICKS 296 /** I have no idea what this does. */
#define RPL_END_CHANINFO 299 /** I have no idea what this does. */
#define RPL_NONE 300 /** RFC1459 */
#define RPL_AWAY 301 /** RFC1459 */
#define RPL_USERHOST 302 /** RFC1459 */
#define RPL_ISON 303 /** RFC1459 */
#define RPL_TEXT 304 /** I have no idea what this does. Supposedly deprecated? */
#define RPL_UNAWAY 305 /** RFC1459 */
#define RPL_NOWAWAY 306 /** RFC1459 */
#define RPL_WHOISUSER 311 /** RFC1459 */
#define RPL_WHOISSERVER 312 /** RFC1459 */
#define RPL_WHOISOPERATOR 313 /** RFC1459 */
#define RPL_WHOWASUSER 314 /** RFC1459 */
#define RPL_ENDOFWHO 315 /** RFC1459 */
#define RPL_WHOISCHANOP 316 /** RFC1459 */
#define RPL_WHOISIDLE 317 /** RFC1459 */
#define RPL_ENDOFWHOIS 318 /** RFC1459 */
#define RPL_WHOISCHANNELS 319 /** RFC1459 */
#define RPL_WHOISVIRT 320 /** I have no idea what this does. */
#define RPL_WHOIS_HIDDEN 320 /** I have no idea what this does. */
#define RPL_WHOISSPECIAL 320 /** I have no idea what this does. */
#define RPL_LISTSTART 321 /** RFC1459 */
#define RPL_LIST 322 /** RFC1459 */
#define RPL_LISTEND 323 /** RFC1459 */
#define RPL_CHANNELMODEIS 324 /** RFC1459 */
#define RPL_UNIQOPIS 325 /** RFC2812 */
#define RPL_NOCHANPASS 326 /** I have no idea what this does. */
#define RPL_CHPASSUNKNOWN 327 /** I have no idea what this does. */
#define RPL_CHANNEL_URL 328 /** I have no idea what this does. */
#define RPL_CREATIONTIME 329 /** I have no idea what this does. */
#define RPL_NOTOPIC 331 /** RFC1459 */
#define RPL_TOPIC 332 /** RFC1459 */
#define RPL_TOPICWHOTIME 333 /** I have no idea what this does. */
#define RPL_BADCHANPASS 339 /** I have no idea what this does. */
#define RPL_USERIP 340 /** I have no idea what this does. */
#define RPL_INVITING 341 /** RFC1459 */
#define RPL_SUMMONING 342 /** RFC1459 */
#define RPL_INVITED 345 /** I have no idea what this does. */
#define RPL_INVITELIST 346 /** RFC2812 */
#define RPL_ENDOFINVITELIST 347 /** RFC2812 */
#define RPL_EXCEPTLIST 348 /** RFC2812 */
#define RPL_ENDOFEXCEPTLIST 349 /** RFC2812 */
#define RPL_VERSION 351 /** RFC1459 */
#define RPL_WHOREPLY 352 /** RFC1459 */
#define RPL_NAMREPLY 353 /** RFC1459 */
#define RPL_WHOSPCRPL 354 /** I have no idea what this does. */
#define RPL_NAMREPLY_ 355 /** I have no idea what this does. */
#define RPL_KILLDONE 361 /** RFC1459 */
#define RPL_CLOSING 362 /** RFC1459 */
#define RPL_CLOSEEND 363 /** RFC1459 */
#define RPL_LINKS 364 /** RFC1459 */
#define RPL_ENDOFLINKS 365 /** RFC1459 */
#define RPL_ENDOFNAMES 366 /** RFC1459 */
#define RPL_BANLIST 367 /** RFC1459 */
#define RPL_ENDOFBANLIST 368 /** RFC1459 */
#define RPL_ENDOFWHOWAS 369 /** RFC1459 */
#define RPL_INFO 371 /** RFC1459 */
#define RPL_MOTD 372 /** RFC1459 */
#define RPL_INFOSTART 373 /** RFC1459 */
#define RPL_ENDOFINFO 374 /** RFC1459 */
#define RPL_MOTDSTART 375 /** RFC1459 */
#define RPL_ENDOFMOTD 376 /** RFC1459 */
#define RPL_YOUREOPER 381 /** RFC1459 */
#define RPL_REHASHING 382 /** RFC1459 */
#define RPL_YOURESERVICE 383 /** RFC2812 */
#define RPL_MYPORTIS 384 /** RFC1459 */
#define RPL_NOTOPERANYMORE 385 /** You are no longer a server operator */
#define RPL_ALIST 388 /** I have no idea what this does. */
#define RPL_ENDOFALIST 389 /** I have no idea what this does. */
#define RPL_TIME 391 /** RFC1459: TIME command response. <server> [possible extension data] :<time string>*/
#define RPL_USERSSTART 392 /** RFC1459 */
#define RPL_USERS 393 /** RFC1459 */
#define RPL_ENDOFUSERS 394 /** RFC1459 */
#define RPL_NOUSERS 395 /** I have no idea what this does. */
#define RPL_HOSTHIDDEN 396 /** Your hostname is now hidden. */
#define ERR_UNKNOWNERROR 400 /** An unknown error occured. */
#define ERR_NOSUCHNICK 401 /** RFC1459 */
#define ERR_NOSUCHSERVER 402 /** RFC1459 */
#define ERR_NOSUCHCHANNEL 403 /** RFC1459 */
#define ERR_CANNOTSENDTOCHAN 404 /** RFC1459 */
#define ERR_TOOMANYCHANNELS 405 /** RFC1459 */
#define ERR_WASNOSUCHNICK 406 /** RFC1459 */
#define ERR_TOOMANYTARGETS 407 /** RFC1459 */
#define ERR_NOSUCHSERVICE 408 /** RFC2812 */
#define ERR_NOORIGIN 409 /** RFC1459 */
#define ERR_NORECIPIENT 411 /** RFC1459 */
#define ERR_NOTEXTTOSEND 412 /** RFC1459 */
#define ERR_NOTOPLEVEL 413 /** RFC1459 */
#define ERR_WILDTOPLEVEL 414 /** RFC1459 */
#define ERR_BADMASK 415 /** RFC2812 */
#define ERR_TOOMANYMATCHES 416 /** I have no idea what this does. */
#define ERR_QUERYTOOLONG 416 /** I have no idea what this does. */
#define ERR_LENGTHTRUNCATED 419 /** I have no idea what this does. */
#define ERR_UNKNOWNCOMMAND 421 /** RFC1459 */
#define ERR_NOMOTD 422 /** RFC1459 */
#define ERR_NOADMININFO 423 /** RFC1459 */
#define ERR_FILEERROR 424 /** RFC1459 */
#define ERR_NOOPERMOTD 425 /** There is no operator MOTD. */
#define ERR_TOOMANYAWAY 429 /** I have no idea what this does. */
#define ERR_EVENTNICKCHANGE 430 /** Can not change nickname due to channel event. */
#define ERR_NONICKNAMEGIVEN 431 /** RFC1459: You didn't specify a nickname. */
#define ERR_ERRONEOUSNICKNAME 432 /** RFC1459: Nickname is reserved or otherwise invalid. */
#define ERR_ERRONEUSNICKNAME ERR_ERRONEOUSNICKNAME /** Use ERR_EERONEOUSNICKNAME instead. */
#define ERR_NICKNAMEINUSE 433 /** RFC1459: Already used nickname was passed to NICK */
#define ERR_NICKCOLLISION 436 /** RFC1459: A nickname collision was detected. */
#define ERR_UNAVAILRESOURCE 437 /** RFC2812: Target is temporarily unreachable. */
#define ERR_BANNICKCHANGE 437 /** "Ban nick change" */
#define ERR_TARGETTOOFAST 439 /** I have no idea what this does. */
#define RPL_INVTOOFAST ERR_TARGETTOOFAST
#define RPL_MSGTOOFAST ERR_TARGETTOOFAST
#define ERR_SERVICESDOWN 440 /** I have no idea what this does. */
#define ERR_USERNOTINCHANNEL 441 /** RFC1459 */
#define ERR_NOTONCHANNEL 442 /** RFC1459 */
#define ERR_USERONCHANNEL 443 /** RFC1459 */
#define ERR_NOLOGIN 444 /** RFC1459 */
#define ERR_SUMMONDISABLED 445 /** RFC1459 */
#define ERR_USERSDISABLED 446 /** RFC1459 */
#define ERR_NONICKCHANGE 447 /** I have no idea what this does. */
#define ERR_NOTIMPLEMENTED 449 /** I have no idea what this does. */
#define ERR_NOTREGISTERED 451 /** RFC1459: You need to be registered. */
#define ERR_IDCOLLISION 452 /** I have no idea what this does. */
#define ERR_NICKLOST 453 /** I have no idea what this does. */
#define ERR_HOSTILENAME 455 /** I have no idea what this does. */
#define ERR_ACCEPTFULL 456 /** I have no idea what this does. */
#define ERR_ACCEPTEXIST 457 /** I have no idea what this does. */
#define ERR_ACCEPTNOT 458 /** I have no idea what this does. */
#define ERR_NOHIDING 459 /** I have no idea what this does. */
#define ERR_NOTFORHALFOPS 460 /** I have no idea what this does. */
#define ERR_NEEDMOREPARAMS 461 /** RFC1459: Command requires more parameters. */
#define ERR_ALREADYREGISTERED 462 /** RFC1459: You're already registered. */
#define ERR_NOPERMFORHOST 463 /** RFC1459: Your host is blocked. */
#define ERR_PASSWDMISMATCH 464 /** RFC1459: Incorrect or missing server password. */
#define ERR_YOUREBANNEDCREEP 465 /** RFC1459: You're banned. */
#define ERR_YOUWILLBEBANNED 466 /** RFC1459: You will soon be banned. */
#define ERR_KEYSET 467 /** RFC1459: A key for this channel has already been set. */
#define ERR_LINKSET 469 /** I have no idea what this does. */
#define ERR_CHANNELISFULL 471 /** RFC1459: That channel is full. */
#define ERR_UNKNOWNMODE 472 /** RFC1459: That mode is unknown. */
#define ERR_INVITEONLYCHAN 473 /** RFC1459: That channel is invite-only. */
#define ERR_BANNEDFROMCHAN 474 /** RFC1459: You're banned from that channel. */
#define ERR_BADCHANNELKEY 475 /** RFC1459: Channel key was missing/incorrect. */
#define ERR_BADCHANMASK 476 /** RFC2812: That channel mask is invalid. */
#define ERR_NOCHANMODES 477 /** RFC2812: Channel does not support mode changes. */
#define ERR_BANLISTFULL 478 /** RFC2812: Channel access/ban list is full. */
#define ERR_BADCHANNAME 479 /** I have no idea what this does. */
#define ERR_LINKFAIL 479 /** I have no idea what this does. */
#define ERR_NOPRIVILEGES 481 /** RFC1459: You do not have the neccessary privledges. */
#define ERR_CHANOPRIVSNEEDED 482 /** RFC1459: You do not have the neccessary channel privledges. */
#define ERR_CANTKILLSERVER 483 /** RFC1459: You can not KILL a server. */
#define ERR_RESTRICTED 484 /** RFC2812: This connection is "restricted" */
#define ERR_UNIQOPRIVSNEEDED 485 /** RFC2812: That mode requires "channel creator" privledges. */
#define ERR_TSLESSCHAN 488 /** I have no idea what this does. */
#define ERR_NOOPERHOST 491 /** RFC1459: You can not become a server operator. */
#define ERR_NOSERVICEHOST 492 /** RFC1459 */
#define ERR_NOFEATURE 493 /** I have no idea what this does. */
#define ERR_BADFEATURE 494 /** I have no idea what this does. */
#define ERR_BADLOGTYPE 495 /** I have no idea what this does. */
#define ERR_BADLOGSYS 496 /** I have no idea what this does. */
#define ERR_BADLOGVALUE 497 /** I have no idea what this does. */
#define ERR_ISOPERLCHAN 498 /** I have no idea what this does. */
#define ERR_CHANOWNPRIVNEEDED 499 /** I have no idea what this does. */
#define ERR_UMODEUNKNOWNFLAG 501 /** RFC1459: This user mode flag is not recognized. */
#define ERR_USERSDONTMATCH 502 /** RFC1459: You can not mody/view other users' modes. */
#define ERR_GHOSTEDCLIENT 503 /** I have no idea what this does. */
#define ERR_USERNOTONSERV 504 /** I have no idea what this does. */
#define ERR_SILELISTFULL 511 /** I have no idea what this does. */
#define ERR_TOOMANYWATCH 512 /** I have no idea what this does. */
#define ERR_BADPING 513 /** Invalid PING response. */
#define ERR_NEEDPONG ERR_BADPING /** Use ERR_BADPING instead. */
#define ERR_BADEXPIRE 515 /** I have no idea what this does. */
#define ERR_DONTCHEAT 516 /** I have no idea what this does. */
#define ERR_DISABLED 517 /** I have no idea what this does. */
#define ERR_WHOSYNTAX 522 /** I have no idea what this does. */
#define ERR_WHOLIMEXCEED 523 /** I have no idea what this does. */
#define ERR_REMOTEPFX 525 /** I have no idea what this does. */
#define ERR_PFXUNROUTABLE 526 /** I have no idea what this does. */
#define ERR_BADHOSTMASK 550 /** I have no idea what this does. */
#define ERR_HOSTUNAVAIL 551 /** I have no idea what this does. */
#define ERR_USINGSLINE 552 /** I have no idea what this does. */
#define RPL_LOGON 600 /** I have no idea what this does. */
#define RPL_LOGOFF 601 /** I have no idea what this does. */
#define RPL_WATCHOFF 602 /** I have no idea what this does. */
#define RPL_WATCHSTAT 602 /** I have no idea what this does. */
#define RPL_NOWON 604 /** I have no idea what this does. */
#define RPL_NOWOFF 605 /** I have no idea what this does. */
#define RPL_WATCHLIST 606 /** I have no idea what this does. */
#define RPL_ENDOFWATCHLIST 607 /** I have no idea what this does. */
#define RPL_WATCHCLEAR 608 /** I have no idea what this does. */
#define RPL_ISLOCOP 611 /** I have no idea what this does. */
#define RPL_ISNOTOPER 612 /** I have no idea what this does. */
#define RPL_ENDOFISOPER 613 /** I have no idea what this does. */
#define RPL_DCCLIST 618 /** I have no idea what this does. */
#define RPL_OMOTDSTART 624 /** I have no idea what this does. */
#define RPL_OMOTD 625 /** I have no idea what this does. */
#define RPL_ENDOFO 626 /** I have no idea what this does. */
#define RPL_SETTINGS 630 /** I have no idea what this does. */
#define RPL_ENDOFSETTINGS 631 /** I have no idea what this does. */
#define RPL_TRACEROUTE_HOP 660 /** I have no idea what this does. */
#define RPL_TRACEROUTE_START 661 /** I have no idea what this does. */
#define RPL_MODECHANGEWARN 662 /** I have no idea what this does. */
#define RPL_CHANREDIR 663 /** I have no idea what this does. */
#define RPL_SERVMODEIS 664 /** I have no idea what this does. */
#define RPL_OTHERUMODEIS 665 /** I have no idea what this does. */
#define RPL_ENDOF_GENERIC 666 /** I have no idea what this does. */
#define RPL_WHOWASDETAILS 667 /** I have no idea what this does. */
#define RPL_STARTTLS 670 /** Proceed with SSL/TLS initialization */
#define RPL_WHOISSECURE 671 /** User is using a secure connection. */
#define RPL_UNKNOWNMODES 672 /** I have no idea what this does. */
#define RPL_CANNOTSETMODES 673 /** I have no idea what this does. */
#define RPL_LUSERSTAFF 678 /** I have no idea what this does. */
#define RPL_TIMEONSERVERIS 679 /** I have no idea what this does. */
#define RPL_NETWORKS 682 /** I have no idea what this does. */
#define RPL_YOURLANGUAGEIS 687 /** I have no idea what this does. */
#define RPL_LANGUAGE 688 /** I have no idea what this does. */
#define RPL_WHOISSTAFF 689 /** I have no idea what this does. */
#define RPL_WHOISLANGUAGE 690 /** I have no idea what this does. */
#define ERR_STARTTLS 691 /** An error occured setting up SSL/TLS server-side */
#define RPL_MODLIST 702 /** I have no idea what this does. */
#define RPL_ENDOFMODLIST 703 /** I have no idea what this does. */
#define RPL_HELPSTART 704 /** I have no idea what this does. */
#define RPL_HELPTXT 705 /** I have no idea what this does. */
#define RPL_ENDOFHELP 706 /** I have no idea what this does. */
#define RPL_ETRACEFULL 708 /** I have no idea what this does. */
#define RPL_ETRACE 709 /** I have no idea what this does. */
#define RPL_KNOCK 710 /** I have no idea what this does. */
#define RPL_KNOCKDLVR 711 /** I have no idea what this does. */
#define RPL_TOOMANYKNOCK 712 /** I have no idea what this does. */
#define RPL_CHANOPEN 713 /** I have no idea what this does. */
#define RPL_KNOCKONCHAN 714 /** I have no idea what this does. */
#define RPL_KNOCKDISABLED 715 /** I have no idea what this does. */
#define RPL_TARGUMODEG 716 /** I have no idea what this does. */
#define RPL_TARGNOTIFY 717 /** I have no idea what this does. */
#define RPL_UMODEGMSG 718 /** I have no idea what this does. */
//#define RPL_OMOTDSTART 720 /** I have no idea what this does. */
//#define RPL_OMOTD 721 /** I have no idea what this does. */
//#define RPL_ENDOFOMOTD 722 /** I have no idea what this does. */
#define RPL_NOPRIVS 723 /** I have no idea what this does. */
#define RPL_TESTMARK 724 /** I have no idea what this does. */
#define RPL_TESTLINE 725 /** I have no idea what this does. */
#define RPL_NOTESTLINE 726 /** I have no idea what this does. */
#define RPL_XINFO 771 /** I have no idea what this does. */
#define RPL_XINFOSTART 773 /** I have no idea what this does. */
#define RPL_XINFOEND 774 /** I have no idea what this does. */
#define RPL_CANNOTDOCOMMAND 972 /** I have no idea what this does. */
#define RPL_CANNOTCHANGEUMODE 973 /** I have no idea what this does. */
#define RPL_CANNOTCHANGECHANMODE 974 /** I have no idea what this does. */
#define RPL_CANNOTCHANGESERVERMODE 975 /** I have no idea what this does. */
#define RPL_CANNOTSENDTONICK 976 /** I have no idea what this does. */
#define RPL_UNKNOWNSERVERMODE 977 /** I have no idea what this does. */
#define RPL_SERVERMODELOCK 979 /** I have no idea what this does. */
#define RPL_BADCHARENCODING 980 /** I have no idea what this does. */
#define RPL_TOOMANYLANGUAGES 981 /** I have no idea what this does. */
#define RPL_NOLANGUAGE 982 /** I have no idea what this does. */
#define RPL_TEXTTOOSHORT 983 /** I have no idea what this does. */
#define RPL_NUMERIC_ERR 999 /** I have no idea what this does. */
#endif // SHORT_IRC_MACROS
#endif // SKIP_IRC_MACROS
#endif // _IRC_NUMERICS_H_HEADER

13
Jupiter/IRC_Server.cpp

@ -0,0 +1,13 @@
#include "IRC_Server.h"
#include <string>
struct SClient
{
Jupiter::Socket *sock;
};
struct Jupiter::IRC::Server::Data
{
Data();
~Data();
};

32
Jupiter/IRC_Server.h

@ -0,0 +1,32 @@
#if !defined _IRC_SERVER_H_HEADER
#define _IRC_SERVER_H_HEADER
#include "Thinker.h"
#include "TCPSocket.h"
#include "INIFile.h"
#include "IRC.h"
namespace Jupiter
{
namespace IRC
{
class Server : public Thinker
{
struct Data;
Data *data_;
class Client
{
};
class Channel
{
};
};
}
}
#endif // _IRC_SERVER_H_HEADER

60
Jupiter/InvalidIndex.h

@ -0,0 +1,60 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _INVALIDINDEX_H_HEADER
#define _INVALIDINDEX_H_HEADER
/**
* @file InvalidIndex.h
* @brief Defines some constants for invalid indexes for unsigned types.
*/
#if defined __cplusplus
#include <cstdint>
#include <climits>
namespace Jupiter
{
static const unsigned int INVALID_INDEX = UINT_MAX;
static const uint32_t INVALID_INDEX32 = UINT32_MAX;
static const uint64_t INVALID_INDEX64 = UINT64_MAX;
static const unsigned int ERROR_INDICATOR = INVALID_INDEX;
static const uint32_t ERROR_INDICATOR32 = INVALID_INDEX32;
static const uint64_t ERROR_INDICATOR64 = INVALID_INDEX32;
}
extern "C"
{
#else
#include <stdint.h>
#include <limits.h>
#endif // __cplusplus
static const unsigned int JUPITER_INVALID_INDEX = UINT_MAX;
static const uint32_t JUPITER_INVALID_INDEX32 = UINT32_MAX;
static const uint64_t JUPITER_INVALID_INDEX64 = UINT64_MAX;
static const unsigned int JUPITER_ERROR_INDICATOR = JUPITER_INVALID_INDEX;
static const uint32_t JUPITER_ERROR_INDICATOR32 = JUPITER_INVALID_INDEX32;
static const uint64_t JUPITER_ERROR_INDICATOR64 = JUPITER_INVALID_INDEX32;
#if defined __cplusplus
}
#endif // __cplusplus
#endif // _INVALIDINDEX_H_HEADER

18
Jupiter/Jupiter.cpp

@ -0,0 +1,18 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include "Jupiter.h"
extern "C"
{
const char *Jupiter_version = JUPITER_VERSION;
const char *Jupiter_copyright = "Copyright (C) 2013-2014 Justin James - All Rights Reserved.";
}
const char *Jupiter::version = Jupiter_version;
const char *Jupiter::copyright = Jupiter_copyright;

59
Jupiter/Jupiter.h

@ -0,0 +1,59 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined JUPITER_API
/**
* @file Jupiter.h
* @brief Defines JUPITER_API and provides metadata about the program.
* On anything other than Windows, JUPITER_API is defined as nothing, to prevent compiler errors.
*/
#if defined _WIN32
#if defined JUPITER_EXPORTS
#define JUPITER_API __declspec(dllexport)
#else // JUPITER_EXPORTS
#define JUPITER_API __declspec(dllimport)
#endif // JUPITER_EXPORTS
#else // _WIN32
#define JUPITER_API
#endif // _WIN32
#define JUPITER_VERSION "Jupiter 0.8" /** Version of this program at compile time. */
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
JUPITER_API extern const char *Jupiter_version; /** Jupiter version number at runtime */
JUPITER_API extern const char *Jupiter_copyright; /** Jupiter copyright notice */
#if defined __cplusplus
}
namespace Jupiter
{
JUPITER_API extern const char *version; /** @see Jupiter_version */
JUPITER_API extern const char *copyright; /** @see Jupiter_copyright */
}
#endif // __cplusplus
#endif // JUPITER_API

BIN
Jupiter/Jupiter.rc

Binary file not shown.

154
Jupiter/Jupiter.vcxproj

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{367CBCA8-6F27-484A-BC6C-2FC087FBB0C8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>IRCBot</RootNamespace>
<ProjectName>Jupiter</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis>
<IncludePath>C:\dev\OpenSSL\Win32\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\dev\OpenSSL\Win32\lib;$(LibraryPath)</LibraryPath>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;JUPITER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnablePREfast>false</EnablePREfast>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ShowProgress>NotSet</ShowProgress>
<Version>0.0</Version>
</Link>
<ProjectReference>
<LinkLibraryDependencies>
</LinkLibraryDependencies>
</ProjectReference>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Base64.cpp" />
<ClCompile Include="Base64C.c" />
<ClCompile Include="Command.cpp" />
<ClCompile Include="File.cpp" />
<ClCompile Include="Functions.c" />
<ClCompile Include="INIFile.cpp" />
<ClCompile Include="IRC.cpp" />
<ClCompile Include="IRC_Client.cpp" />
<ClCompile Include="IRC_Server.cpp" />
<ClCompile Include="Jupiter.cpp" />
<ClCompile Include="Plugin.cpp" />
<ClCompile Include="Queue.cpp" />
<ClCompile Include="Rehash.cpp" />
<ClCompile Include="SecureSocket.cpp" />
<ClCompile Include="Socket.cpp" />
<ClCompile Include="TCPSocket.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="UDPSocket.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ArrayList.h" />
<ClInclude Include="Base64.h" />
<ClInclude Include="Command.h" />
<ClInclude Include="CString.h" />
<ClInclude Include="CString_Imp.h" />
<ClInclude Include="DLList.h" />
<ClInclude Include="File.h" />
<ClInclude Include="InvalidIndex.h" />
<ClInclude Include="IRC.h" />
<ClInclude Include="IRC_Numerics.h" />
<ClInclude Include="IRC_Server.h" />
<ClInclude Include="Jupiter.h" />
<ClInclude Include="Functions.h" />
<ClInclude Include="INIFile.h" />
<ClInclude Include="IRC_Client.h" />
<ClInclude Include="List.h" />
<ClInclude Include="Plugin.h" />
<ClInclude Include="Queue.h" />
<ClInclude Include="Rehash.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SecureSocket.h" />
<ClInclude Include="SLList.h" />
<ClInclude Include="Socket.h" />
<ClInclude Include="String_Type.h" />
<ClInclude Include="TCPSocket.h" />
<ClInclude Include="Thinker.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="UDPSocket.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Jupiter.rc" />
</ItemGroup>
<ItemGroup>
<Library Include="..\..\..\OpenSSL\Win32\lib\VC\static\libeay32MD.lib" />
<Library Include="..\..\..\OpenSSL\Win32\lib\VC\static\ssleay32MD.lib" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

205
Jupiter/Jupiter.vcxproj.filters

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Lists">
<UniqueIdentifier>{1e778301-e8e9-4565-b651-8686ec19b419}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Sockets">
<UniqueIdentifier>{02e48221-98b3-4875-aa96-796a9aedc4b5}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\IRC">
<UniqueIdentifier>{a7ca0e66-d9b7-43e2-a3f8-d89744bd3c06}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Lists">
<UniqueIdentifier>{b0dabf12-3147-44f6-911e-01142cc4e3a4}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\IRC">
<UniqueIdentifier>{6f290a91-7cd8-495e-ae20-22c956fcfbcb}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Sockets">
<UniqueIdentifier>{95b491ba-ca51-4aad-bdb8-7fae054498d2}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Strings">
<UniqueIdentifier>{55c2d716-1fc1-42a3-8dc0-ef730ae338e4}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Files">
<UniqueIdentifier>{bd64544d-de91-47a1-afda-21e37a7e31e0}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Files">
<UniqueIdentifier>{10026b7d-c0ef-416c-ac1f-9e94064a404f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Object Extensions">
<UniqueIdentifier>{08dcc387-4b58-4f1f-b785-9565fe67f645}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Object Extensions">
<UniqueIdentifier>{37b5eaf6-0e4f-4609-8518-1b72f93aebe5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Functions.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Jupiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IRC.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="IRC_Client.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="IRC_Server.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="Queue.cpp">
<Filter>Source Files\Lists</Filter>
</ClCompile>
<ClCompile Include="TCPSocket.cpp">
<Filter>Source Files\Sockets</Filter>
</ClCompile>
<ClCompile Include="UDPSocket.cpp">
<Filter>Source Files\Sockets</Filter>
</ClCompile>
<ClCompile Include="Socket.cpp">
<Filter>Source Files\Sockets</Filter>
</ClCompile>
<ClCompile Include="SecureSocket.cpp">
<Filter>Source Files\Sockets</Filter>
</ClCompile>
<ClCompile Include="INIFile.cpp">
<Filter>Source Files\Files</Filter>
</ClCompile>
<ClCompile Include="Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="File.cpp">
<Filter>Source Files\Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Plugin.cpp">
<Filter>Source Files\Object Extensions</Filter>
</ClCompile>
<ClCompile Include="Rehash.cpp">
<Filter>Source Files\Object Extensions</Filter>
</ClCompile>
<ClCompile Include="Base64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Base64C.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Functions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Jupiter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="List.h">
<Filter>Header Files\Lists</Filter>
</ClInclude>
<ClInclude Include="Queue.h">
<Filter>Header Files\Lists</Filter>
</ClInclude>
<ClInclude Include="DLList.h">
<Filter>Header Files\Lists</Filter>
</ClInclude>
<ClInclude Include="SLList.h">
<Filter>Header Files\Lists</Filter>
</ClInclude>
<ClInclude Include="UDPSocket.h">
<Filter>Header Files\Sockets</Filter>
</ClInclude>
<ClInclude Include="TCPSocket.h">
<Filter>Header Files\Sockets</Filter>
</ClInclude>
<ClInclude Include="SecureSocket.h">
<Filter>Header Files\Sockets</Filter>
</ClInclude>
<ClInclude Include="Socket.h">
<Filter>Header Files\Sockets</Filter>
</ClInclude>
<ClInclude Include="IRC.h">
<Filter>Header Files\IRC</Filter>
</ClInclude>
<ClInclude Include="IRC_Client.h">
<Filter>Header Files\IRC</Filter>
</ClInclude>
<ClInclude Include="IRC_Server.h">
<Filter>Header Files\IRC</Filter>
</ClInclude>
<ClInclude Include="ArrayList.h">
<Filter>Header Files\Lists</Filter>
</ClInclude>
<ClInclude Include="CString.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="String_Type.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="CString_Imp.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="INIFile.h">
<Filter>Header Files\Files</Filter>
</ClInclude>
<ClInclude Include="Command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="File.h">
<Filter>Header Files\Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Base64.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Rehash.h">
<Filter>Header Files\Object Extensions</Filter>
</ClInclude>
<ClInclude Include="Plugin.h">
<Filter>Header Files\Object Extensions</Filter>
</ClInclude>
<ClInclude Include="Thinker.h">
<Filter>Header Files\Object Extensions</Filter>
</ClInclude>
<ClInclude Include="IRC_Numerics.h">
<Filter>Header Files\IRC</Filter>
</ClInclude>
<ClInclude Include="InvalidIndex.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Jupiter.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Library Include="..\..\..\OpenSSL\Win32\lib\VC\static\libeay32MD.lib">
<Filter>Resource Files</Filter>
</Library>
<Library Include="..\..\..\OpenSSL\Win32\lib\VC\static\ssleay32MD.lib">
<Filter>Resource Files</Filter>
</Library>
</ItemGroup>
</Project>

77
Jupiter/List.h

@ -0,0 +1,77 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _LIST_H_HEADER
#define _LIST_H_HEADER
#include "Jupiter.h"
/**
* @file List.h
* @brief Provides a generic List interface.
*/
namespace Jupiter
{
template<typename T> class List
{
public:
/**
* @brief Gets the data at a specified index.
*
* @param index Index of the data to get.
* @return Data stored at the specified index.
*/
virtual T *get(unsigned int index) const = 0;
/**
* @brief Removes the n'th Node in the list, and returns its contents.
*
* @param n Index of the node to remove.
* @return Contents of the node removed.
*/
virtual T *remove(unsigned int n) = 0;
/**
* @brief Adds data to the list at a specified index.
*
* @param data Data to add to the list.
* @param index Position in the list to add the data to.
*/
virtual void add(T *data, unsigned int index) = 0;
/**
* @brief Adds data to the list in an efficient manner.
*
* @param data Data to add to the list.
*/
virtual void add(T *data) = 0;
/**
* @brief Returns the size of the list.
*
* @return Number of nodes in the list.
*/
unsigned int size() const { return Jupiter::List<T>::length; };
protected:
unsigned int length = 0; /** Length (size) of the list. Returned by size(). Must be managed by extending classes. */
};
}
#endif // _LIST_H_HEADER

282
Jupiter/Plugin.cpp

@ -0,0 +1,282 @@
/**
* Copyright (C) 2014 Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <cstring>
#include <cstdio>
#if defined _WIN32
#include <Windows.h>
#define DIR_CHR '\\'
#define DEFAULT_PLUGINS_DIRECTORY "Plugins\\"
#else // _WIN32
#include <dlfcn.h>
#define DIR_CHR '/'
#define DEFAULT_PLUGINS_DIRECTORY "Plugins/"
#endif // _WIN32
#include "Plugin.h"
#include "Functions.h"
#include "ArrayList.h"
#include "CString.h"
Jupiter::CStringS pluginDir = DEFAULT_PLUGINS_DIRECTORY;
Jupiter::ArrayList<Jupiter::Plugin> _plugins;
Jupiter::ArrayList<Jupiter::Plugin> *Jupiter::plugins = &_plugins;
struct dlib;
Jupiter::ArrayList<dlib> _libList;
Jupiter::ArrayList<dlib> *libList = &_libList;
Jupiter::Plugin::~Plugin()
{
for (int i = _plugins.size(); i >= 0; i--) if (_plugins.get(i) == this) _plugins.remove(i);
}
struct dlib
{
Jupiter::Plugin *plugin = nullptr;
#if defined _WIN32
HMODULE lib = nullptr;
#else // _WIN32
void *lib = nullptr;
#endif // _WIN32
~dlib();
};
dlib::~dlib()
{
if (dlib::lib != nullptr)
{
#if defined _WIN32
FreeLibrary(dlib::lib);
#else // _WIN32
dlclose(dllib::lib);
#endif // _WIN32
}
}
void Jupiter::setPluginDirectory(const char *dir)
{
if (dir == nullptr) pluginDir = DEFAULT_PLUGINS_DIRECTORY;
else
{
pluginDir = dir;
if (pluginDir.size() > 0 && dir[pluginDir.size() - 1] != DIR_CHR) pluginDir += DIR_CHR;
}
}
const char *Jupiter::getPluginDirectory()
{
return pluginDir.c_str();
}
Jupiter::Plugin *Jupiter::loadPlugin(const char *pluginName)
{
#if defined _WIN32
char *fileName = new char[strlen(pluginName) + pluginDir.size() + 5];
sprintf(fileName, "%s%s.dll", pluginDir.c_str(), pluginName);
#else // _WIN32
char *fileName = new char[strlen(pluginName) + pluginDirLen + 4];
sprintf(fileName, "%s%s.so", pluginDir.c_str(), pluginName);
#endif // _WIN32
return Jupiter::loadPluginFile(fileName);
}
Jupiter::Plugin *Jupiter::loadPluginFile(const char *file)
{
dlib *dPlug = new dlib();
// Load the library
#if defined _WIN32
dPlug->lib = LoadLibraryA(file);
#else // _WIN32
dPlug->lib = dlopen(file, RTLD_LAZY);
#endif // _WIN32
if (dPlug->lib == nullptr) goto fail;
// Get the "getPlugin" function
typedef Jupiter::Plugin *(*func_type)(void);
#if defined _WIN32
func_type func = (func_type) GetProcAddress(dPlug->lib, "getPlugin");
#else // _WIN32
func_type func = (func_type)dlsym(dPlug->lib, "getPlugin");
#endif // _WIN32
if (func == nullptr) goto fail;
dPlug->plugin = func();
if (dPlug->plugin == nullptr) goto fail;
libList->add(dPlug);
_plugins.add(dPlug->plugin);
return dPlug->plugin;
fail:
delete dPlug;
return nullptr;
}
bool Jupiter::freePlugin(unsigned int index)
{
if (index < _plugins.size())
{
// Do not free() the plugin; plugin gets free'd by FreeLibrary().
_plugins.remove(index);
dlib *dPlug = libList->remove(index);
typedef void (*func_type)(void);
#if defined _WIN32
func_type func = (func_type)GetProcAddress(dPlug->lib, "unload");
#else // _WIN32
func_type func = (func_type)dlsym(dPlug->lib, "unload");
#endif // _WIN32
if (func != nullptr) func();
delete dPlug;
return true;
}
return false;
}
bool Jupiter::freePlugin(Jupiter::Plugin *plugin)
{
if (plugin == nullptr) return false;
for (int i = _plugins.size() - 1; i >= 0; i--) if (_plugins.get(i) == plugin) return Jupiter::freePlugin(i);
return false;
}
bool Jupiter::freePlugin(const char *pluginName)
{
if (pluginName == nullptr) return false;
for (int i = _plugins.size() - 1; i >= 0; i--) if (strmatchi(pluginName, _plugins.get(i)->getName())) return Jupiter::freePlugin(i);
return false;
}
Jupiter::Plugin *Jupiter::getPlugin(unsigned int index)
{
if (index < _plugins.size()) return _plugins.get(index);
return nullptr;
}
Jupiter::Plugin *Jupiter::getPlugin(const char *pluginName)
{
Jupiter::Plugin *p;
for (int i = _plugins.size() - 1; i >= 0; i--)
{
p = _plugins.get(i);
if (strmatchi(pluginName, p->getName())) return p;
}
return nullptr;
}
// Event Placeholders
void Jupiter::Plugin::OnConnect(Jupiter::IRC::Client *)
{
return;
}
void Jupiter::Plugin::OnDisconnect(Jupiter::IRC::Client *)
{
return;
}
void Jupiter::Plugin::OnReconnectAttempt(Jupiter::IRC::Client *, bool)
{
return;
}
int Jupiter::Plugin::OnRehash()
{
return 0;
}
void Jupiter::Plugin::OnRaw(Jupiter::IRC::Client *, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnNumeric(Jupiter::IRC::Client *, long int, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnError(Jupiter::IRC::Client *, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnChat(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnNotice(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnServerNotice(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnCTCP(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnAction(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnInvite(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnJoin(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnPart(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnNick(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnKick(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnQuit(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnMode(Jupiter::IRC::Client *, const Jupiter::StringType &, const Jupiter::StringType &, const Jupiter::StringType &)
{
return;
}
void Jupiter::Plugin::OnThink(Jupiter::IRC::Client *)
{
return;
}
int Jupiter::Plugin::think()
{
return 0;
}

306
Jupiter/Plugin.h

@ -0,0 +1,306 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _PLUGIN_H_HEADER
#define _PLUGIN_H_HEADER
/**
* @file Plugin.h
* @brief Provides a hot-swapable plugin system.
*/
#include "ArrayList.h"
#include "Thinker.h"
#include "CString.h"
#include "Rehash.h"
namespace Jupiter
{
/** Forward declaration */
namespace IRC { class Client; }
/**
* @brief Provides the basis for plugin interfacing.
*/
class JUPITER_API Plugin : public Jupiter::Thinker, public Jupiter::Rehashable
{
public:
/**
* @brief This is called when a connection has been successfully established.
* The current implementation calls this after the MOTD.
*/
virtual void OnConnect(Jupiter::IRC::Client *server);
/**
* @brief This is called when at the end of disconnect().
* This is called upon any connection failure or error.
*/
virtual void OnDisconnect(Jupiter::IRC::Client *server);
/**
* @brief This is called when at the end of reconnect().
*
* @param successConnect Used to determine if a connection was successfully established.
* @see connect().
*/
virtual void OnReconnectAttempt(Jupiter::IRC::Client *server, bool successConnect);
/**
* @brief This is called when rehash() is called.
* @see Jupiter::Rehashable::OnRehash().
*
* @return 0 if no error occurs, a postive integer if an error occurs, or a negative integer if an error occurs and the object should be deleted.
*/
virtual int OnRehash();
/**
* @brief This is called after a message has been normally processed.
* This always happens last. All other hooks will be called before this.
*
* @param raw The raw message.
*/
virtual void OnRaw(Jupiter::IRC::Client *server, const Jupiter::StringType &raw);
/**
* @brief This is called after an IRC numeric has been processed.
*
* @param raw The raw message.
*/
virtual void OnNumeric(Jupiter::IRC::Client *server, long int numeric, const Jupiter::StringType &raw);
/**
* @brief This is called when an ERROR is received.
* This indicates a connection termination, and thus, disconnect() is called immediately after this.
*
* @param message Message sent by the server.
*/
virtual void OnError(Jupiter::IRC::Client *server, const Jupiter::StringType &message);
/**
* @brief This is called when a chat message is received.
*
* @param channel String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnChat(Jupiter::IRC::Client *server, const Jupiter::StringType &channel, const Jupiter::StringType &nick, const Jupiter::StringType &message);
/**
* @brief This is called when a notice is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnNotice(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &sender, const Jupiter::StringType &message);
/**
* @brief This is called when a server notice is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the sender.
* @param message String containing the message sent.
*/
virtual void OnServerNotice(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &sender, const Jupiter::StringType &message);
/**
* @brief This is called when a CTCP message is received.
*
* @param channel String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnCTCP(Jupiter::IRC::Client *server, const Jupiter::StringType &channel, const Jupiter::StringType &nick, const Jupiter::StringType &message);
/**
* @brief This is called when an action message is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnAction(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &nick, const Jupiter::StringType &message);
/**
* @brief This is called when an invite is received.
*
* @param chan String containing the destination of the message.
* @param inviter String containing the nickname of the inviter.
* @param invited String containing the nickname of the user invited.
*/
virtual void OnInvite(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &inviter, const Jupiter::StringType &invited);
/**
* @brief This is called when a chat message is received.
*
* @param chan String containing the destination of the message.
* @param nick String containing the nickname of the sender.
* @param message String containing the message sent.
*/
virtual void OnJoin(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &nick);
/**
* @brief This is called when a user parts a channel.
*
* @param chan String containing the channel parted from.
* @param nick String containing the nickname of the user.
* @param reason String containing the reason for parting, or nullptr if none is specified.
*/
virtual void OnPart(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &nick, const Jupiter::StringType &reason);
/**
* @brief This is called when a user changes their nickname.
*
* @param oldnick String containing the old nickname of the user.
* @param newnick String containing the new nickname of the user.
*/
virtual void OnNick(Jupiter::IRC::Client *server, const Jupiter::StringType &oldnick, const Jupiter::StringType &newnick);
/**
* @brief This is called when a user is kicked from a channel.
*
* @param chan String containing the channel kicked from.
* @param kicker String containing the nickname of the kicker.
* @param kicked String containing the nickname of the user kicked.
* @param reason String containing the reason for the kick, or nullptr if none is specified.
*/
virtual void OnKick(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &kicker, const Jupiter::StringType &kicked, const Jupiter::StringType &reason);
/**
* @brief This is called when a user quits the server.
*
* @param nick String containing the nickname of the user.
* @param message String containing the reason for quiting.
*/
virtual void OnQuit(Jupiter::IRC::Client *server, const Jupiter::StringType &nick, const Jupiter::StringType &message);
/**
* @brief This is called when a channel mode is changed.
*
* @param chan String containing the affected channel.
* @param nick String containing the nickname of the user.
* @param modeString String containing the modes changed.
*/
virtual void OnMode(Jupiter::IRC::Client *server, const Jupiter::StringType &chan, const Jupiter::StringType &nick, const Jupiter::StringType &modeString);
/**
* @brief This is called when a server "thinks".
*
* @param server Server that's thinking.
*/
virtual void OnThink(Jupiter::IRC::Client *server);
/**
* @brief Makes the Plugin "think". This does nothing, unless overloaded.
* This method should return an error other than 0 if you want the plugin to be released.
*
* @return 0 when no error occurs, an error otherwise.
*/
virtual int think();
/**
* @brief Returns the name of the plugin.
*
* @return String containing the name of the plugin.
*/
virtual const char *getName() = 0;
/**
* @brief Destructor for Plugin class.
*/
virtual ~Plugin();
};
/** Plugin management functions */
/** The list containing pointers to plugins */
JUPITER_API extern Jupiter::ArrayList<Jupiter::Plugin> *plugins;
/**
* @brief Sets the directory to look in for plugins.
* Note: This DOES NOT copy the input string.
*
* @param dir Directory to look for plugins in.
*/
JUPITER_API void setPluginDirectory(const char *dir);
/**
* @brief Returns the current plugin directory.
*
* @return String containing the directory which is prepended to module load attempts.
*/
JUPITER_API const char *getPluginDirectory();
/**
* @brief Loads a module, appending .so or .dll as appropriate for the operating system.
*
* @param pluginName The name of the plugin to load.
* @return A pointer to the plugin that was loaded on success, nullptr otherwise.
*/
JUPITER_API Jupiter::Plugin *loadPlugin(const char *pluginName);
/**
* @brief Loads a module based on a true file name.
*
* @param file File to attempt to load as a plugin.
* @return A pointer to the plugin that was loaded on success, nullptr otherwise.
*/
JUPITER_API Jupiter::Plugin *loadPluginFile(const char *file);
/**
* @brief Unloads a module and removes it from the module list, based on its index.
*
* @param index Index of the module.
* @return True if a module was unloaded, false otherwise.
*/
JUPITER_API bool freePlugin(unsigned int index);
/**
* @brief Unloads a module and removes it from the module list, based on its data.
*
* @param plugin Pointer to the plugin to unload.
* @return True if a module was unloaded, false otherwise.
*/
JUPITER_API bool freePlugin(Jupiter::Plugin *plugin);
/**
* @brief Unloads a module and removes it from the module list, based on its name.
* Note: This function accepts wildcard strings.
*
* @param pluginName Name of the module to unload.
* @return True if a module was unloaded, false otherwise.
*/
JUPITER_API bool freePlugin(const char *pluginName);
/**
* @brief Fetches a plugin from the list and returns it, based on its index.
*
* @param index Index of the module to return.
* @return A module on success, nullptr otherwise.
*/
JUPITER_API Jupiter::Plugin *getPlugin(unsigned int index);
/**
* @brief Fetches a plugin from the list and returns it, based on its name.
*
* @param pluginName String containing the name of the plugin.
* @return A module on success, nullptr otherwise.
*/
JUPITER_API Jupiter::Plugin *getPlugin(const char *pluginName);
}
#endif // _PLUGIN_H_HEADER

59
Jupiter/Queue.cpp

@ -0,0 +1,59 @@
#include "Queue.h"
struct Jupiter::Queue::Data
{
Data *next;
void *data;
};
Jupiter::Queue::Queue()
{
Jupiter::Queue::end = new Jupiter::Queue::Data();
Jupiter::Queue::end->next = nullptr;
Jupiter::Queue::head = new Jupiter::Queue::Data();
Jupiter::Queue::head->next = Jupiter::Queue::end;
Jupiter::Queue::head->data = nullptr;
Jupiter::Queue::length = 0;
}
Jupiter::Queue::~Queue()
{
Jupiter::Queue::Data *p;
Jupiter::Queue::Data *c = head;
do
{
p = c;
c = c->next;
delete p;
}
while (c != nullptr);
}
void Jupiter::Queue::enqueue(void *data)
{
Jupiter::Queue::Data *nEnd = new Jupiter::Queue::Data();
nEnd->next = nullptr;
end->data = data;
end->next = nEnd;
end = nEnd;
Jupiter::Queue::length++;
}
void *Jupiter::Queue::dequeue()
{
if (Jupiter::Queue::length > 0)
{
Jupiter::Queue::Data *tmp = Jupiter::Queue::head->next;
Jupiter::Queue::head->next = tmp->next;
void *data = tmp->data;
delete tmp;
Jupiter::Queue::length--;
return data;
}
return nullptr;
}
unsigned int Jupiter::Queue::size() const
{
return Jupiter::Queue::length;
}

79
Jupiter/Queue.h

@ -0,0 +1,79 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _QUEUE_H_HEADER
#define _QUEUE_H_HEADER
#include "Jupiter.h"
/**
* @file Queue.h
* @brief Provides a simple and efficient queue.
*/
namespace Jupiter
{
/**
* @brief Provides a simple and efficient queue.
*/
class JUPITER_API Queue
{
public:
/**
* @brief Adds data to the end of the Queue.
*
* @param data Pointer to the data to add.
*/
void enqueue(void *data);
/**
* @brief Removes and returns data from the front of the Queue.
*
* @return Data in the front of the Queue.
*/
void *dequeue();
/**
* @brief Returns the number of elements waiting for processing in the Queue.
*
* @return Number of elements in the Queue.
*/
unsigned int size() const;
/**
* @brief Default constructor for the Queue class.
*/
Queue();
/**
* @brief Destructor for the Queue class.
* Note: This does not delete data which was added to the queue.
*/
~Queue();
/** Private members */
private:
struct Data;
Data *head;
Data *end;
unsigned int length;
};
}
#endif // _QUEUE_H_HEADER

130
Jupiter/Rehash.cpp

@ -0,0 +1,130 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include "Rehash.h"
#include "DLList.h"
/**
* Considerations:
* It may be worth-while making rehashables aware of which node they're in, or integrating them into their own node?
*/
/** Wrapper class to add rehashable functions. */
class RehashFunction : public Jupiter::Rehashable
{
public:
int(*function)(void);
int OnRehash() { return function(); };
RehashFunction(int(*func)(void)) { RehashFunction::function = func; };
};
/** List of Rehashable objects */
Jupiter::DLList<Jupiter::Rehashable> rehashables;
/** List of RehashFunction objects */
Jupiter::DLList<RehashFunction> rehashFunctions;
Jupiter::Rehashable::Rehashable()
{
rehashables.add(this);
}
Jupiter::Rehashable::Rehashable(const Jupiter::Rehashable &)
{
rehashables.add(this);
}
Jupiter::Rehashable::~Rehashable()
{
if (rehashables.size() != 0)
{
for (Jupiter::DLList<Jupiter::Rehashable>::Node *n = rehashables.getNode(0); n != nullptr; n = n->next)
{
if (n->data == this)
{
rehashables.remove(n);
break;
}
}
}
}
unsigned int Jupiter::rehash()
{
if (rehashables.size() == 0) return 0;
unsigned int total = 0;
int r;
for (Jupiter::DLList<Jupiter::Rehashable>::Node *n = rehashables.getNode(0); n != nullptr; n = n->next)
{
r = n->data->OnRehash();
if (r != 0)
{
total++;
if (r < 0) delete n->data;
}
}
return total;
}
unsigned int Jupiter::getRehashableCount()
{
return rehashables.size();
}
void Jupiter::addOnRehash(int(*function)(void))
{
rehashFunctions.add(new RehashFunction(function));
}
bool Jupiter::removeOnRehash(int(*function)(void))
{
if (rehashFunctions.size() == 0) return false;
for (Jupiter::DLList<RehashFunction>::Node *n = rehashFunctions.getNode(0); n != nullptr; n = n->next)
{
if (n->data->function == function)
{
delete rehashFunctions.remove(n);
return true;
}
}
return false;
}
unsigned int Jupiter::removeAllOnRehash()
{
unsigned int r = rehashFunctions.size();
while (rehashFunctions.size() != 0) delete rehashFunctions.remove(unsigned int(0));
return r;
}
// C forward interfaces
extern "C" unsigned int Jupiter_rehash()
{
return Jupiter::rehash();
}
extern "C" unsigned int Jupiter_getRehashableCount()
{
return Jupiter::getRehashableCount();
}
extern "C" void Jupiter_addOnRehash(int(*function)(void))
{
return Jupiter::addOnRehash(function);
}
extern "C" bool Jupiter_removeOnRehash(int(*function)(void))
{
return Jupiter::removeOnRehash(function);
}
extern "C" unsigned int Jupiter_removeAllOnRehash()
{
return Jupiter::removeAllOnRehash();
}

147
Jupiter/Rehash.h

@ -0,0 +1,147 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _REHASH_H_HEADER
#define _REHASH_H_HEADER
/**
* @file Rehash.h
* @brief Provides a C++ rehash system, which is also accessable through a C interface.
*/
#include "Jupiter.h"
#if defined __cplusplus
namespace Jupiter
{
class JUPITER_API Rehashable
{
public:
/**
* @brief Rehashes an object's status.
*
* @return 0 if no error occurs, a postive integer if an error occurs, or a negative integer if an error occurs and the object should be deleted.
*/
virtual int OnRehash() = 0;
/**
* @brief Default constructor for the Rehashable class.
*/
Rehashable();
/**
* @brief Copy constructor for the Rehashable class.
*/
Rehashable(const Rehashable &);
/**
* @brief Destructor for the Rehashable class.
*/
virtual ~Rehashable();
}; // Jupiter::Rehashable class
/**
* @brief Calls OnRehash() on every rehashable object.
*
* @return Number of objects which returned an error.
*/
JUPITER_API unsigned int rehash();
/**
* @brief Fetches the number of rehashable objects.
*
* @return Number of rehashable objects.
*/
JUPITER_API unsigned int getRehashableCount();
/**
* @brief Adds a function to be called during the rehash process.
*
* @param function Function to call (@see Jupiter::Rehashable::OnRehash()).
*/
JUPITER_API void addOnRehash(int(*function)(void));
/**
* @brief Removes a function from the rehash list.
*
* @param function Function to remove.
* @return True if a function was removed, false otherwise.
*/
JUPITER_API bool removeOnRehash(int(*function)(void));
/**
* @brief Removes all functions from the rehash list.
* Note: This should be called during application clean-up.
*
* @return Number of functions removed.
*/
JUPITER_API unsigned int removeAllOnRehash();
} // Jupiter namespace
extern "C"
{
#else
#include <stdbool.h> // bool type
#endif // __cplusplus
/**
* @brief Calls OnRehash() on every rehashable object.
*
* @return Number of objects which returned an error.
*/
JUPITER_API unsigned int Jupiter_rehash();
/**
* @brief Fetches the number of rehashable objects.
*
* @return Number of rehashable objects.
*/
JUPITER_API unsigned int Jupiter_getRehashableCount();
/**
* @brief Adds a function to be called during the rehash process.
*
* @param function Function to call (@see Jupiter::Rehashable::OnRehash()).
*/
JUPITER_API void Jupiter_addOnRehash(int(*function)(void));
/**
* @brief Removes a function from the rehash list.
*
* @param function Function to remove.
* @return True if a function was removed, false otherwise.
*/
JUPITER_API bool Jupiter_removeOnRehash(int(*function)(void));
/**
* @brief Removes all functions from the rehash list.
* Note: This should be called during application clean-up.
*
* @return Number of functions removed.
*/
JUPITER_API unsigned int Jupiter_removeAllOnRehash();
#if defined __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // _REHASH_H_HEADER

216
Jupiter/SLList.h

@ -0,0 +1,216 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _SLLIST_H_HEADER
#define _SLLIST_H_HEADER
#include "Jupiter.h"
#include "List.h"
/**
* @file SLList.h
* @brief Provides a generic Singly Linked List implementation using the List interface.
*/
namespace Jupiter
{
/**
* @brief Provides a Singly Linked List implementation using the List interface.
*/
template<typename T> class SLList : public List<T>
{
public:
/**
* @brief Stores a pointer to data, and a pointer to the next node in the list.
*/
struct Node
{
Node *next = nullptr;
T *data = nullptr;
};
/**
* @brief Returns the n'th Node in the list.
*
* @param n Index of the node to return.
* @return n'th Node in the list.
*/
Node *getNode(unsigned int n) const;
/**
* @brief Gets the data at a specified index.
*
* @param index Index of the data to get.
* @return Data stored at the specified index.
*/
T *get(unsigned int index) const;
/**
* @brief Removes the n'th Node in the list, and returns its contents.
*
* @param n Index of the node to remove.
* @return Contents of the node removed.
*/
T *remove(unsigned int n);
/**
* @brief Removes the next node in the list.
*
* @param data Node that preceeds the node to be removed.
* @return Contents of the node removed if the node exists, nullptr otherwise.
*/
T *removeNext(Node *data);
/**
* @brief Adds data to the list at a specified index.
*
* @param data Data to add to the list.
* @param index Position in the list to add the data to.
*/
void add(T *data, unsigned int index);
/**
* @brief Adds data to the front of the list.
*
* @param data Data to add to the list.
*/
void add(T *data);
/**
* @brief Default constructor for the SLList class.
*/
SLList();
/**
* @brief Copy constructor for the SLList class.
*/
SLList(const SLList<T> &);
/**
* @brief Destructor for the SLList class.
* Note: This does not delete data added to the list.
*/
~SLList();
/** Private members */
private:
Node *head;
};
}
// Implementation
template<typename T> Jupiter::SLList<T>::SLList()
{
Jupiter::SLList<T>::head = new Jupiter::SLList<T>::Node();
Jupiter::List<T>::length = 0;
}
template<typename T> Jupiter::SLList<T>::SLList(const Jupiter::SLList<T> &source)
{
Jupiter::SLList<T>::head = new Jupiter::SLList<T>::Node();
Jupiter::SLList<T>::Node *sourceNode = source.head;
head->data = sourceNode->data;
sourceNode = sourceNode->next;
Jupiter::SLList<T>::Node *n = Jupiter::SLList<T>::head;
while (sourceNode != nullptr)
{
n->next = new Jupiter::SLList<T>::Node();
n = n->next;
n->data = sourceNode->data;
sourceNode = sourceNode->next;
}
Jupiter::List<T>::length = source.length;
}
template<typename T> Jupiter::SLList<T>::~SLList()
{
Jupiter::SLList<T>::Node *p;
Jupiter::SLList<T>::Node *c = head;
do
{
p = c;
c = c->next;
delete p;
} while (c != nullptr);
}
template<typename T> typename Jupiter::SLList<T>::Node *Jupiter::SLList<T>::getNode(unsigned int index) const
{
Jupiter::SLList<T>::Node *t = head->next;
for (unsigned int i = 0; i != index; i++) t = t->next;
return t;
}
template<typename T> T *Jupiter::SLList<T>::get(unsigned int index)
{
return Jupiter::SLList<T>::getNode(index)->data;
}
template<typename T> const T *Jupiter::SLList<T>::get(unsigned int index) const
{
return Jupiter::SLList<T>::getNode(index)->data;
}
template<typename T> T *Jupiter::SLList<T>::remove(unsigned int index)
{
Jupiter::SLList<T>::Node *t = head;
for (unsigned int i = 0; i != index; i++) t = t->next;
Jupiter::SLList<T>::Node *t2 = t->next;
T *r = t2->data;
delete t2;
Jupiter::List<T>::length--;
return r;
}
template<typename T> T *Jupiter::SLList<T>::removeNext(Jupiter::SLList<T>::Node *data)
{
Jupiter::SLList<T>::Node *t = data->next;
if (t == nullptr) return nullptr;
T *r = t->data;
data->next = t->next;
delete t;
Jupiter::List<T>::length--;
return r;
}
template<typename T> void Jupiter::SLList<T>::add(T *data, unsigned int index)
{
Jupiter::SLList<T>::Node *n = new Jupiter::SLList<T>::Node();
n->data = data;
Jupiter::SLList<T>::Node *t = Jupiter::SLList<T>::head;
for (unsigned int i = 0; i < index; i++) t = t->next;
n->next = t->next;
t->next = n;
Jupiter::List<T>::length++;
}
template<typename T> void Jupiter::SLList<T>::add(T *data)
{
Jupiter::SLList<T>::Node *n = new Jupiter::SLList<T>::Node();
n->data = data;
n->next = Jupiter::SLList<T>::head->next;
Jupiter::SLList<T>::head->next = n;
Jupiter::List<T>::length++;
}
#endif // _SLLIST_H_HEADER

229
Jupiter/SecureSocket.cpp

@ -0,0 +1,229 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <utility> // std::move
#include "SecureSocket.h"
#include <openssl/ssl.h> // OpenSSL SSL functions
#include <openssl/err.h> // OpenSSL SSL errors
struct Jupiter::SecureSocket::SSLData
{
SSL *handle = nullptr;
SSL_CTX *context = nullptr;
const SSL_METHOD *method = nullptr;
Jupiter::SecureSocket::EncryptionMethod eMethod = ANY;
char *cert = nullptr;
char *key = nullptr;
~SSLData();
};
Jupiter::SecureSocket::SSLData::~SSLData()
{
if (Jupiter::SecureSocket::SSLData::handle != nullptr)
{
if (SSL_shutdown(Jupiter::SecureSocket::SSLData::handle) == 0) SSL_shutdown(Jupiter::SecureSocket::SSLData::handle);
SSL_free(Jupiter::SecureSocket::SSLData::handle);
}
if (Jupiter::SecureSocket::SSLData::context != nullptr) SSL_CTX_free(Jupiter::SecureSocket::SSLData::context);
if (Jupiter::SecureSocket::SSLData::cert != nullptr) delete[] Jupiter::SecureSocket::SSLData::cert;
if (Jupiter::SecureSocket::SSLData::key != nullptr) delete[] Jupiter::SecureSocket::SSLData::key;
}
Jupiter::SecureSocket::SecureSocket() : Jupiter::Socket()
{
Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData();
}
Jupiter::SecureSocket::SecureSocket(size_t bufferSize) : Jupiter::Socket(bufferSize)
{
Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData();
}
Jupiter::SecureSocket::SecureSocket(Jupiter::Socket &&source) : Jupiter::Socket(std::move(source))
{
Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData();
}
Jupiter::SecureSocket::SecureSocket(Jupiter::SecureSocket &&source) : Jupiter::Socket(std::move(source))
{
Jupiter::SecureSocket::SSLdata_ = source.SSLdata_;
source.SSLdata_ = nullptr;
}
Jupiter::SecureSocket::~SecureSocket()
{
if (Jupiter::SecureSocket::SSLdata_ != nullptr) delete Jupiter::SecureSocket::SSLdata_;
}
Jupiter::SecureSocket *Jupiter::SecureSocket::acceptConnection()
{
int tSock = SSL_accept(Jupiter::SecureSocket::SSLdata_->handle);
if (tSock > 0)
{
SecureSocket *r = new SecureSocket(Jupiter::SecureSocket::getBufferSize());
r->setDescriptor(tSock);
r->setType(this->getType());
r->setProtocol(this->getProtocol());
return r;
}
return nullptr;
}
bool Jupiter::SecureSocket::bindToPort(const char *hostname, unsigned short iPort, bool andListen)
{
return Jupiter::Socket::bindToPort(hostname, iPort, andListen);
}
void Jupiter::SecureSocket::closeSocket()
{
if (Jupiter::SecureSocket::SSLdata_ != nullptr)
{
Jupiter::Socket::closeSocket();
delete Jupiter::SecureSocket::SSLdata_;
Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData();
}
}
const SSL_METHOD *translateEncryptionMethod(Jupiter::SecureSocket::EncryptionMethod method)
{
switch (method)
{
case Jupiter::SecureSocket::EncryptionMethod::SSL3:
return SSLv3_method();
case Jupiter::SecureSocket::EncryptionMethod::TLS1:
return TLSv1_method();
case Jupiter::SecureSocket::EncryptionMethod::TLS1_1:
return TLSv1_1_method();
case Jupiter::SecureSocket::EncryptionMethod::TLS1_2:
return TLSv1_2_method();
case Jupiter::SecureSocket::EncryptionMethod::DTLS1:
return DTLSv1_method();
case Jupiter::SecureSocket::EncryptionMethod::ANY:
return SSLv23_method();
default:
return nullptr;
}
}
const char *Jupiter::SecureSocket::getCipherName() const
{
return SSL_CIPHER_get_name(SSL_get_current_cipher(Jupiter::SecureSocket::SSLdata_->handle));
}
Jupiter::SecureSocket::EncryptionMethod Jupiter::SecureSocket::getMethod() const
{
return Jupiter::SecureSocket::SSLdata_->eMethod;
}
void Jupiter::SecureSocket::setMethod(Jupiter::SecureSocket::EncryptionMethod method)
{
Jupiter::SecureSocket::SSLdata_->eMethod = method;
}
bool loadCertificate(SSL_CTX *context, const char *cert, const char *key)
{
if (SSL_CTX_load_verify_locations(context, cert, key) != 1) ERR_print_errors_fp(stderr);
if (SSL_CTX_set_default_verify_paths(context) != 1) ERR_print_errors_fp(stderr);
if (SSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
if (SSL_CTX_use_PrivateKey_file(context, key, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return false;
}
if (!SSL_CTX_check_private_key(context)) return false;
return true;
}
void Jupiter::SecureSocket::setCertificate(const char *cert, const char *key)
{
Jupiter::SecureSocket::SSLdata_->cert = new char[strlen(cert) + 1];
Jupiter::SecureSocket::SSLdata_->key = new char[strlen(key) + 1];
strcpy(Jupiter::SecureSocket::SSLdata_->cert, cert);
strcpy(Jupiter::SecureSocket::SSLdata_->key, key);
}
void Jupiter::SecureSocket::setCertificate(const char *pem)
{
Jupiter::SecureSocket::setCertificate(pem, pem);
}
bool Jupiter::SecureSocket::connectToHost(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort)
{
return Jupiter::Socket::connectToHost(hostname, iPort, clientAddress, clientPort) && this->initSSL();
}
int Jupiter::SecureSocket::peek()
{
int r = SSL_peek(Jupiter::SecureSocket::SSLdata_->handle, (char *) this->getBuffer(), this->getBufferSize()-1);
if (r >= 0) ((char *) this->getBuffer())[r] = 0;
return r;
}
int Jupiter::SecureSocket::recv()
{
if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) return -1;
int r = SSL_read(Jupiter::SecureSocket::SSLdata_->handle, (char *) this->getBuffer(), this->getBufferSize()-1);
if (r >= 0) ((char *) this->getBuffer())[r] = 0;
return r;
}
int Jupiter::SecureSocket::send(const char *data, size_t datalen)
{
return SSL_write(Jupiter::SecureSocket::SSLdata_->handle, data, datalen);
}
int Jupiter::SecureSocket::send(const char *message)
{
return Jupiter::SecureSocket::send(message, strlen(message));
}
bool Jupiter::SecureSocket::initSSL()
{
SSL_load_error_strings();
SSL_library_init();
Jupiter::SecureSocket::SSLdata_->method = translateEncryptionMethod(Jupiter::SecureSocket::SSLdata_->eMethod);
if (Jupiter::SecureSocket::SSLdata_->method == nullptr) return false;
Jupiter::SecureSocket::SSLdata_->context = SSL_CTX_new(Jupiter::SecureSocket::SSLdata_->method);
if (Jupiter::SecureSocket::SSLdata_->context == nullptr)
{
ERR_print_errors_fp(stderr);
return false;
}
if (Jupiter::SecureSocket::SSLdata_->cert != nullptr) loadCertificate(Jupiter::SecureSocket::SSLdata_->context, Jupiter::SecureSocket::SSLdata_->cert, Jupiter::SecureSocket::SSLdata_->key);
Jupiter::SecureSocket::SSLdata_->handle = SSL_new(Jupiter::SecureSocket::SSLdata_->context);
if (Jupiter::SecureSocket::SSLdata_->handle == nullptr)
{
ERR_print_errors_fp(stderr);
return false;
}
if (SSL_set_fd(Jupiter::SecureSocket::SSLdata_->handle, this->getDescriptor()) == 0)
{
ERR_print_errors_fp(stderr);
return false;
}
if (SSL_set_tlsext_host_name(Jupiter::SecureSocket::SSLdata_->handle, this->getHostname()) != 1) // This is potentially redundant, but no documentation has been found.
{
ERR_print_errors_fp(stderr);
return false;
}
int t = SSL_connect(Jupiter::SecureSocket::SSLdata_->handle);
if (t != 1)
{
ERR_print_errors_fp(stderr);
return false;
}
return true;
}

214
Jupiter/SecureSocket.h

@ -0,0 +1,214 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _SECURESOCKET_H_HEADER
#define _SECURESOCKET_H_HEADER
#include "Socket.h"
/**
* @file SecureSocket.h
* @brief Provides an OpenSSL implementation on the Socket interface.
*/
namespace Jupiter
{
/**
* @brief Implements TLS/SSL support using SSL on the Socket interface.
* Numerous functions here use various OpenSSL functions. Therefore, some
* functions will return values which correspond to the OpenSSL functions,
* as opposed to the standard socket functions. In general however, output
* return values should be similar.
*/
class JUPITER_API SecureSocket : public Socket
{
public:
/**
* @brief Enumerator translating to various SSL/TLS protocols.
* Used in getMethod() and setMethod().
*/
enum EncryptionMethod
{
SSL3 = 1, /** SSL 3.0 - Unrecommended */
TLS1 = 2, /** TLS 1.0 - Unrecommended */
TLS1_1 = 3, /** TLS 1.1 */
TLS1_2 = 4, /** TLS 1.2 */
DTLS1 = 5, /** DTLS 1.0 */
ANY = 126, /** Attempt to use any of the above encryption methods (generally the most secure available between both client and server) */
END = 127 /** END OF ENUM */
};
/**
* @brief Returns the name of the cipher currently in use.
* @return Name of cipher currently in use, or "NONE" if none is in use.
*/
const char *getCipherName() const;
/**
* @brief Returns the encryption method that the socket attempts to use.
* This is ANY by default.
* @return Encrpytion method that the socket attempts to use.
*/
EncryptionMethod getMethod() const;
/**
* @brief Sets the encryption method to be used when connecting.
*/
void setMethod(EncryptionMethod method);
/**
* @brief Loads a certificate and key for use.
*
* @param cert String containing file location of certificate.
* @param key String containing file location of private key.
* @return True on success, false otherwise.
*/
void setCertificate(const char *cert, const char *key);
/**
* @brief Loads a certificate and key for use.
*
* @param pem Combined certificate/key file.
* @return True on success, false otherwise.
*/
void setCertificate(const char *pem);
/**
* @brief Interface to provide simple connection establishing.
*
* @param hostname String containing hostname of server to connect to.
* @param iPort Port to connect on.
* @param Address for client to bind to.
* @return True on success, false otherwise.
*/
virtual bool connectToHost(const char *hostname, unsigned short iPort, const char *clientAddress = nullptr, unsigned short clientPort = 0);
/**
* @brief Interface to provide simple binding to ports.
*
* @param hostname String containing hostname to bind to.
* @param iPort Port to bind to.
* @param andListen True if listen() should be called, false otherwise.
* @return True on success, false otherwise.
*/
virtual bool bindToPort(const char *hostname, unsigned short iPort, bool andListen = true);
/**
* @brief Accepts an incoming connection for the port bound to.
*
* @return A valid SecureSocket on success, nullptr otherwise.
*/
virtual SecureSocket *acceptConnection();
/**
* @brief Closes the socket.
*/
virtual void closeSocket();
/**
* @brief Writes new data from the socket to the buffer, without removing it from the socket queue.
* The data written by this function will always end with a null character, which is not counted in the returned value.
*
* @return Number of bytes received on success, less than or equal to 0 otherwise.
* Note: Refer to SSL_read() for detailed return values.
*/
virtual int peek();
/**
* @brief Writes new data from the socket to the buffer.
* The data written by this function will always end with a null character, which is not counted in the returned value.
*
* @return Number of bytes received on success, less than or equal to 0 otherwise.
* Note: Refer to SSL_read() for detailed return values.
*/
virtual int recv();
/**
* @brief Sends data across the socket.
*
* @param data String containing the data to be send.
* @param datalen The size of the data to be sent, in chars.
* @return Number of bytes sent on success, less than or equal to 0 otherwise.
* Note: Refer to SSL_write() for detailed return values.
*/
virtual int send(const char *data, size_t datalen);
/**
* @brief Sends a null-terminated string of data across the socket.
*
* @param String containing the null-terminated data to send.
* @return Number of bytes sent on success, less than or equal to 0 otherwise.
* Note: Refer to SSL_write() for detailed return values.
*/
virtual int send(const char *msg);
/**
* @brief Initializes SSL on the socket.
* Note: This is only relevant when elevating an existing Socket to a SecureSocket.
*
* @return True on success, false otherwise.
*/
bool initSSL();
/**
* @brief Default constructor for the SecureSocket class.
* This constructor will set the buffer size to 4096 chars.
*/
SecureSocket();
/**
* @brief Copying a Socket is forbidden.
*/
SecureSocket(const SecureSocket &) = delete;
/**
* @brief Constructor for the SecureSocket class which allows for the setting of a specific buffer size.
*
* @param bufferSize Size of the buffer to allocate, measured in chars.
*/
SecureSocket(size_t bufferSize);
/**
* @brief Socket move constructor for the SecureSocket class.
* Note: initSSL() must be called immediately.
*
* @param source Socket to move data from.
*/
SecureSocket(Jupiter::Socket &&source);
/**
* @brief SecureSocket move constructor for the SecureSocket class.
*
* @param source SecureSocket to move data from.
*/
SecureSocket(Jupiter::SecureSocket &&source);
/**
* @brief Destructor for the SecureSocket class.
*/
virtual ~SecureSocket();
/** Private members */
private:
struct SSLData;
SSLData *SSLdata_;
};
}
#endif // _SECURESOCKET_H_HEADER

564
Jupiter/Socket.cpp

@ -0,0 +1,564 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <cstdio>
#if defined _WIN32
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
bool socketInit = false;
#else // _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstring>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
typedef int SOCKET;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#endif // _WIN32
#include "Socket.h"
#include "Functions.h" // makestr()
int cSend(SOCKET s, const char *buf, int len, int flags)
{
return send(s, buf, len, flags);
}
int cRecv(SOCKET s, char *buf, int len, int flags)
{
return recv(s, buf, len, flags);
}
struct Jupiter::Socket::Data
{
SOCKET rawSock;
unsigned short port;
char *host;
char *buff;
size_t bufflen;
unsigned long blockMode;
int sockType;
int sockProto;
Data(char *buffer, size_t bufferSize);
Data(const Data &);
~Data();
};
Jupiter::Socket::Data::Data(char *buffer, size_t bufferSize)
{
Jupiter::Socket::Data::buff = buffer;
Jupiter::Socket::Data::bufflen = bufferSize;
Jupiter::Socket::Data::port = 0;
Jupiter::Socket::Data::rawSock = 0;
Jupiter::Socket::Data::blockMode = 0;
Jupiter::Socket::Data::sockType = SOCK_RAW;
Jupiter::Socket::Data::sockProto = IPPROTO_RAW;
Jupiter::Socket::Data::host = nullptr;
for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0;
}
Jupiter::Socket::Data::Data(const Data &source)
{
Jupiter::Socket::Data::bufflen = source.bufflen;
Jupiter::Socket::Data::buff = new char[Jupiter::Socket::Data::bufflen];
Jupiter::Socket::Data::port = source.port;
Jupiter::Socket::Data::rawSock = source.rawSock;
Jupiter::Socket::Data::blockMode = source.blockMode;
Jupiter::Socket::Data::sockType = source.sockType;
Jupiter::Socket::Data::sockProto = source.sockProto;
Jupiter::Socket::Data::host = source.host;
if (Jupiter::Socket::Data::host != nullptr) Jupiter::Socket::Data::host = makestr(Jupiter::Socket::Data::host);
for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0;
}
Jupiter::Socket::Data::~Data()
{
if (Jupiter::Socket::Data::buff != nullptr)
{
delete[] Jupiter::Socket::Data::buff;
Jupiter::Socket::Data::buff = nullptr;
}
if (Jupiter::Socket::Data::host != nullptr)
{
delete[] Jupiter::Socket::Data::host;
Jupiter::Socket::Data::host = nullptr;
}
}
Jupiter::Socket::Socket() : Jupiter::Socket::Socket(4096)
{
}
Jupiter::Socket::Socket(size_t bufferSize)
{
Jupiter::Socket::data_ = new Jupiter::Socket::Data(new char[bufferSize], bufferSize);
}
Jupiter::Socket::Socket(Jupiter::Socket &&source)
{
Jupiter::Socket::data_ = source.data_;
source.data_ = nullptr;
}
Jupiter::Socket::Socket(char *buffer, size_t bufferSize)
{
Jupiter::Socket::data_ = new Jupiter::Socket::Data(buffer, bufferSize);
}
Jupiter::Socket::~Socket()
{
if (Jupiter::Socket::data_ != nullptr)
{
if (Jupiter::Socket::data_->rawSock > 0)
{
Jupiter::Socket::closeSocket();
}
delete Jupiter::Socket::data_;
}
}
int Jupiter::Socket::getDescriptor() const
{
return Jupiter::Socket::data_->rawSock;
}
void Jupiter::Socket::setDescriptor(int descriptor)
{
Jupiter::Socket::data_->rawSock = descriptor;
}
void Jupiter::Socket::setType(int type)
{
Jupiter::Socket::data_->sockType = type;
}
void Jupiter::Socket::setProtocol(int proto)
{
Jupiter::Socket::data_->sockProto = proto;
}
int Jupiter::Socket::getType() const
{
return Jupiter::Socket::data_->sockType;
}
int Jupiter::Socket::getProtocol() const
{
return Jupiter::Socket::data_->sockProto;
}
bool Jupiter::Socket::connectToHost(addrinfo *info)
{
#if defined _WIN32
if (!socketInit && !Jupiter::Socket::init()) return false;
#endif // _WIN32
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;
return true;
}
bool Jupiter::Socket::connectToHost(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort)
{
#if defined _WIN32
if (!socketInit && !Jupiter::Socket::init()) return false;
#endif // _WIN32
Jupiter::Socket::data_->host = new char[strlen(hostname)+1];
strcpy(Jupiter::Socket::data_->host, hostname);
Jupiter::Socket::data_->port = iPort;
int i = 0;
static char portString[256];
sprintf(portString, "%u", Jupiter::Socket::data_->port);
addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host, portString);
while (info != nullptr)
{
addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i);
if (ainfo == nullptr)
{
Jupiter::Socket::freeAddrInfo(info);
return false;
}
sockaddr *asock = ainfo->ai_addr;
Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) continue;
if (clientAddress != nullptr) this->bindToPort(clientAddress, clientPort, false);
if (connect(Jupiter::Socket::data_->rawSock, asock, ainfo->ai_addrlen) == SOCKET_ERROR)
{
i++;
continue;
}
Jupiter::Socket::freeAddrInfo(info);
return true;
}
return false;
}
bool Jupiter::Socket::bindToPort(const char *hostname, unsigned short iPort, bool andListen)
{
#if defined _WIN32
if (!socketInit && !Jupiter::Socket::init()) return false;
#endif // _WIN32
Jupiter::Socket::data_->host = new char[strlen(hostname)+1];
strcpy(Jupiter::Socket::data_->host, hostname);
Jupiter::Socket::data_->port = iPort;
int i = 0;
static char portString[256];
sprintf(portString, "%u", Jupiter::Socket::data_->port);
addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host, portString);
while (info != nullptr)
{
addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i);
if (ainfo == nullptr)
{
Jupiter::Socket::freeAddrInfo(info);
return false;
}
Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || bind(Jupiter::Socket::data_->rawSock, ainfo->ai_addr, ainfo->ai_addrlen) == SOCKET_ERROR)
{
i++;
continue;
}
Jupiter::Socket::freeAddrInfo(info);
if (andListen && Jupiter::Socket::data_->sockType == SOCK_STREAM && listen(Jupiter::Socket::data_->rawSock, SOMAXCONN) == SOCKET_ERROR) return false;
return true;
}
return false;
}
void Jupiter::Socket::closeSocket()
{
if (Jupiter::Socket::data_ != nullptr)
{
shutdown(Jupiter::Socket::data_->rawSock, 2);
#if defined _WIN32
closesocket(Jupiter::Socket::data_->rawSock);
#else // _WIN32
close(Jupiter::Socket::data_->rawSock);
#endif // _WIN32
Jupiter::Socket::data_->rawSock = 0;
}
}
addrinfo *Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) // static
{
addrinfo *ptr;
if (getaddrinfo(hostname, port, nullptr, &ptr)) return nullptr;
return ptr;
}
addrinfo *Jupiter::Socket::getStaticAddrInfo(const char *hostname, const char *port) // static
{
static addrinfo *ptr = nullptr;
if (ptr != nullptr) freeaddrinfo(ptr);
ptr = Jupiter::Socket::getAddrInfo(hostname, port);
return ptr;
}
void Jupiter::Socket::freeAddrInfo(addrinfo *info) // static
{
freeaddrinfo(info);
}
addrinfo *Jupiter::Socket::getAddrInfo(addrinfo *addr, int result) // static
{
addrinfo *ptr = addr;
for (int i = 0; i < result && ptr != nullptr; i++) ptr = ptr->ai_next;
return ptr;
}
char *Jupiter::Socket::resolveAddress(const addrinfo *addr) // static
{
char *resolved = new char[NI_MAXHOST];
getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
return resolved;
}
char *Jupiter::Socket::resolveAddress(addrinfo *addr, int result) // static
{
addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result);
if (ptr == nullptr) return nullptr;
return Jupiter::Socket::resolveAddress(ptr);
}
char *Jupiter::Socket::resolveAddress(const char *hostname, int result) // static
{
addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0);
if (info == nullptr) return nullptr;
return Jupiter::Socket::resolveAddress(info, result);
}
char *Jupiter::Socket::resolveHostname(addrinfo *addr) // static
{
char *resolved = new char[NI_MAXHOST];
getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, 0);
return resolved;
}
char *Jupiter::Socket::resolveHostname(addrinfo *addr, int result) // static
{
addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result);
if (ptr == nullptr) return nullptr;
return Jupiter::Socket::resolveHostname(ptr);
}
char *Jupiter::Socket::resolveHostname(const char *hostname, int result) // static
{
addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0);
if (info == nullptr) return nullptr;
return Jupiter::Socket::resolveHostname(info, result);
}
Jupiter::Socket *Jupiter::Socket::acceptConnection()
{
SOCKET tSock = accept(Socket::data_->rawSock, 0, 0);
if (tSock != INVALID_SOCKET)
{
Socket *r = new Socket(Jupiter::Socket::data_->bufflen);
r->data_->rawSock = tSock;
r->data_->sockType = Jupiter::Socket::data_->sockType;
r->data_->sockProto = Jupiter::Socket::data_->sockProto;
return r;
}
return nullptr;
}
bool Jupiter::Socket::setReadTimeout(unsigned long milliseconds)
{
#if defined _WIN32
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const char *)milliseconds, sizeof(milliseconds)) == 0;
#else // _WIN32
timeval time;
time.tv_sec = milliseconds / 1000;
time.tv_usec = (milliseconds % 1000) * 1000;
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const void *) &time, sizeof(time)) == 0;
#endif // _WIN32
}
bool Jupiter::Socket::setSendTimeout(unsigned long milliseconds)
{
#if defined _WIN32
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const char *)milliseconds, sizeof(milliseconds)) == 0;
#else // _WIN32
timeval time;
time.tv_sec = milliseconds / 1000;
time.tv_usec = (milliseconds % 1000) * 1000;
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const void *) &time, sizeof(time)) == 0;
#endif // _WIN32
}
bool Jupiter::Socket::setTimeout(unsigned long milliseconds)
{
if (Jupiter::Socket::setReadTimeout(milliseconds) && Jupiter::Socket::setSendTimeout(milliseconds)) return true;
return false;
}
bool Jupiter::Socket::setBlocking(bool mode)
{
Jupiter::Socket::data_->blockMode = !mode;
#if defined _WIN32
return ioctlsocket(Jupiter::Socket::data_->rawSock, FIONBIO, &Jupiter::Socket::data_->blockMode) == 0;
#else // _WIN32
int flags = fcntl(Jupiter::Socket::data_->rawSock, F_GETFL, 0);
if (flags < 0) return 0;
flags = Jupiter::Socket::data_->blockMode ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK);
return fcntl(Jupiter::Socket::data_->rawSock, F_SETFL, flags) == 0;
#endif // _WIN32
}
bool Jupiter::Socket::getBlockingMode() const
{
return !Jupiter::Socket::data_->blockMode;
}
const char *Jupiter::Socket::getHost() const
{
return Jupiter::Socket::data_->host;
}
unsigned short Jupiter::Socket::getPort() const
{
return Jupiter::Socket::data_->port;
}
const char *Jupiter::Socket::getBuffer() const
{
return Jupiter::Socket::data_->buff;
}
void Jupiter::Socket::setBuffer(char *buffer, size_t size)
{
if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff;
Jupiter::Socket::data_->bufflen = size;
Jupiter::Socket::data_->buff = buffer;
}
char *Jupiter::Socket::setBufferSize(size_t size)
{
if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff;
Jupiter::Socket::data_->bufflen = size;
Jupiter::Socket::data_->buff = new char[Jupiter::Socket::data_->bufflen];
return Jupiter::Socket::data_->buff;
}
unsigned int Jupiter::Socket::getBufferSize() const
{
return Jupiter::Socket::data_->bufflen;
}
const char *Jupiter::Socket::getData()
{
if (this->recv() > 0) return this->getBuffer();
return nullptr;
}
const char *Jupiter::Socket::getHostname() const
{
return Jupiter::Socket::data_->host;
}
const char *Jupiter::Socket::getLocalHostname() // static
{
static char localHostname[NI_MAXHOST];
gethostname(localHostname, NI_MAXHOST);
return localHostname;
}
void Jupiter::Socket::clearBuffer()
{
for (unsigned int i = 0; i < Jupiter::Socket::data_->bufflen; i++) Jupiter::Socket::data_->buff[i] = 0;
}
int Jupiter::Socket::send(const char *data, size_t datalen)
{
return cSend(Jupiter::Socket::data_->rawSock, data, datalen, 0);
}
int Jupiter::Socket::send(const char *msg)
{
return Jupiter::Socket::send(msg, strlen(msg));
}
int Jupiter::Socket::sendTo(const addrinfo *info, const char *data, size_t datalen)
{
return sendto(Jupiter::Socket::data_->rawSock, data, datalen, 0, info->ai_addr, info->ai_addrlen);
}
int Jupiter::Socket::sendTo(const addrinfo *info, const char *msg)
{
return sendto(Jupiter::Socket::data_->rawSock, msg, strlen(msg), 0, info->ai_addr, info->ai_addrlen);
}
int Jupiter::Socket::sendData(const char *data, size_t datalen)
{
return this->send(data, datalen);
}
int Jupiter::Socket::sendData(const char *msg)
{
return this->send(msg);
}
int Jupiter::Socket::peek()
{
int r = cRecv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen-1, MSG_PEEK);
if (r >= 0) Jupiter::Socket::data_->buff[r] = 0;
return r;
}
int Jupiter::Socket::peekFrom(addrinfo *info)
{
if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr);
socklen_t len = info->ai_addrlen;
if (len <= 0)
{
info->ai_addr = new sockaddr();
len = sizeof(sockaddr);
}
int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, MSG_PEEK, info->ai_addr, &len);
if (r >= 0)
{
Jupiter::Socket::data_->buff[r] = 0;
info->ai_addrlen = len;
info->ai_canonname = nullptr;
info->ai_family = info->ai_addr->sa_family;
info->ai_flags = 0;
info->ai_next = nullptr;
info->ai_protocol = this->getProtocol();
info->ai_socktype = this->getType();
}
return r;
}
int Jupiter::Socket::recv()
{
int r = cRecv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen-1, 0);
if (r >= 0) Jupiter::Socket::data_->buff[r] = 0;
return r;
}
int Jupiter::Socket::recvFrom(addrinfo *info)
{
if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr);
memset(info, 0, sizeof(addrinfo));
info->ai_addr = new sockaddr();
socklen_t len = sizeof(sockaddr);
int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen-1, 0, info->ai_addr, &len);
if (r >= 0)
{
Jupiter::Socket::data_->buff[r] = 0;
info->ai_addrlen = len;
info->ai_family = info->ai_addr->sa_family;
info->ai_protocol = this->getProtocol();
info->ai_socktype = this->getType();
}
return r;
}
int Jupiter::Socket::receive()
{
return this->recv();
}
int Jupiter::Socket::getLastError() // static
{
#if defined _WIN32
int lastError = WSAGetLastError();
#else // _WIN32
int lastError = errno;
#endif // _WIN32
return lastError;
}
bool Jupiter::Socket::init() // static
{
#if defined _WIN32 // _WIN32
WSADATA wsadata;
if (WSAStartup(0x0202, &wsadata)) return false;
if (wsadata.wVersion != 0x0202)
{
WSACleanup();
return false;
}
socketInit = true;
#endif // _WIN32
return true;
}
bool Jupiter::Socket::cleanup() // static
{
#if defined _WIN32 // _WIN32
WSACleanup();
#endif // _WIN32
return true;
}

491
Jupiter/Socket.h

@ -0,0 +1,491 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _SOCKET_H_HEADER
#define _SOCKET_H_HEADER
/**
* @file Socket.h
* @brief Provides cross-platform socket interaction.
*/
#include <cstring>
#include "Jupiter.h"
struct addrinfo;
namespace Jupiter
{
/**
* @brief Provides a cross-platform interface for sockets.
* Note: This class SHOULD NOT be instantiated by itself.
* By default, this class creates a RAW socket, meaning TCP,
* UDP, and other protocol support requires this class to be
* extended. Extensions for UDP, TCP, and TLS/SSL are available
* in UDPSocket.h, TCPSocket.h, and SecureSocket.h, respectively.
*/
class JUPITER_API Socket
{
protected:
/**
* @brief Used by class extensions to get the socket descriptor.
*
* @return A raw socket descriptor.
*/
int getDescriptor() const;
/**
* @brief Used by class extensions to set the appropriate socket descriptor.
*
* @param descript Socket descriptor.
*/
void setDescriptor(int descript);
public:
/**
* @brief Sets the socket type. Primarily intended for use by class extensions.
*
* @param type Socket type to use.
*/
void setType(int type);
/**
* @brief Sets the protocol to be used by the socket. Primarily intended for use by class extensions.
*
* @param proto Socket type to use.
*/
void setProtocol(int proto);
/**
* @brief Resolves and stores address information in an addrinfo struct.
* The addrinfo returned by this function should be freed by freeAddrInfo().
*
* @param host String containing the hostname of the target.
* @param port String containing the target port.
* @return Pointer to a NULL-terminated linked list of addrinfo on success, nullptr otherwise.
*/
static addrinfo *getAddrInfo(const char *hostname, const char *port);
/**
* @brief Resolves and stores address information in an addrinfo struct.
* Unlike the function getAddrInfo, this function stores the returned addrinfo
* as static, meaning that any subsequent calls will overwrite the previous call.
*
* @param host String containing the hostname of the target.
* @param port String containing the target port.
* @return Pointer to a NULL-terminated linked list of addrinfo on success, nullptr otherwise.
*/
static addrinfo *getStaticAddrInfo(const char *hostname, const char *port);
/**
* @brief Frees the resources associated with an addrinfo struct.
*
* @param info Pointer to the addrinfo to be freed.
*/
static void freeAddrInfo(addrinfo *info);
/**
* @brief Returns the N'th addrinfo in a linked list of addrinfo.
* This function does not allocate any memory.
*
* @param addr Head addrinfo pointer.
* @param N Position of the addrinfo in the list to return.
* @return N'th addrinfo pointed to by addr.
*/
static addrinfo *getAddrInfo(addrinfo *addr, int N);
/**
* @brief Returns the text representation of an addrinfo's stored address.
*
* @param addr Address info containing IP address.
* @return String containing the text representation of the stored address on success, nullptr otherwise.
*/
static char *resolveAddress(const addrinfo *addr);
/**
* @brief Returns the text representation of an addrinfo's stored address.
*
* @param addr Address info containing IP address.
* @param result Which result to return.
* @return String containing the text representation of the stored address on success, nullptr otherwise.
*/
static char *resolveAddress(addrinfo *addr, int result);
/**
* @brief Resolves a hostname to an IP address.
*
* @param hostname Hostname to resolve.
* @param result Which resolution result to return.
* @return String containing the text representation of the resolved address on success, nullptr otherwise.
*/
static char *resolveAddress(const char *hostname, int result);
/**
* @brief Resolves an address to a hostname. (Reverse DNS)
*
* @param addr Address info containing IP address.
* @return String containing the hostname of the stored address on success, nullptr otherwise.
*/
static char *resolveHostname(addrinfo *addr);
/**
* @brief Resolves an address to a hostname. (Reverse DNS)
*
* @param addr Address info containing IP address.
* @param result Which result to return.
* @return String containing the hostname of the stored address on success, nullptr otherwise.
*/
static char *resolveHostname(addrinfo *addr, int result);
/**
* @brief Resolves an address to a hostname. (Reverse DNS)
*
* @param hostname Address to resolve.
* @param result Which resolution result to return.
* @return String containing the hostname of the resolved address on success, nullptr otherwise.
*/
static char *resolveHostname(const char *hostname, int result);
/**
* @brief Interface to provide simple connection establishing.
* Note: When using this method, the hostname and port are NOT stored; thus getHost(), getHostname(),
* and getPort() should not be called. This is used solely to initialize the raw sockets.
*
* @param info addrinfo containing the information required to initialize the socket and attempt a connection.
* @return True on success, false otherwise.
*/
virtual bool connectToHost(addrinfo *info);
/**
* @brief Interface to provide simple connection establishing.
*
* @param hostname String containing hostname of server to connect to.
* @param iPort Port to connect on.
* @param clientHostname Optional parameter to specify the address for socket to bind to.
* @param clientPort Optional parameter to specify the port for socket to bind to.
* @return True on success, false otherwise.
*/
virtual bool connectToHost(const char *hostname, unsigned short iPort, const char *clientHostname = nullptr, unsigned short clientPort = 0);
/**
* @brief Interface to provide simple binding to ports.
*
* @param hostname String containing hostname to bind to.
* @param iPort Port to bind to.
* @param andListen True if listen() should be called, false otherwise.
* @return True on success, false otherwise.
*/
virtual bool bindToPort(const char *hostname, unsigned short iPort, bool andListen = true);
/**
* @brief Accepts an incoming connection for the port bound to.
*
* @return A valid Socket on success, nullptr otherwise.
*/
virtual Socket *acceptConnection();
/**
* @brief Sets the timeout for recv() in milliseconds.
* Note: This only affects blocking sockets.
*
* @param milliseconds Desired amount of time for a timeout for recv(), in milliseconds.
* @return True on success, false otherwise.
*/
bool setReadTimeout(unsigned long milliseconds);
/**
* @brief Sets the timeout for send() in milliseconds.
* Note: This only affects blocking sockets.
*
* @param milliseconds Desired amount of time for a timeout for send(), in milliseconds.
* @return True on success, false otherwise.
*/
bool setSendTimeout(unsigned long milliseconds);
/**
* @brief Calls setReadTimeout() and setSendTimeout().
* Note: This only affects blocking sockets.
*
* @param milliseconds Desired amount of time for timeout, in milliseconds.
* @return True on complete success, false otherwise.
*/
bool setTimeout(unsigned long milliseconds);
/**
* @brief Sets the blocking mode.
*
* @param mode True if the socket should be blocking, false otherwise.
* @return True on success, false otherwise.
*/
bool setBlocking(bool mode);
/**
* @brief Returns the blocking mode.
*
* @return True if the socket is blocking, false otherwise.
*/
bool getBlockingMode() const;
/**
* @brief Closes the socket.
*/
virtual void closeSocket();
/**
* @brief Returns the hostname that the socket is connected to or listening to.
*
* @return String containing the hostname.
*/
const char *getHost() const;
/**
* @brief Returns the port which the Socket is connected to or listening to.
*
* @return Port number.
*/
unsigned short getPort() const;
/**
* @brief Returns the type of the socket.
*
* @return Type of the socket.
*/
int getType() const;
/**
* @brief Returns the protocol being used by the socket.
*
* @return Protocol of the socket.
*/
int getProtocol() const;
/**
* @brief Returns the buffer.
*
* @return Buffer.
*/
const char *getBuffer() const;
/**
* @brief Assigns a new buffer.
*
* @param buffer The new buffer to use.
* @param size The size of the new buffer.
*/
void setBuffer(char *buffer, size_t size);
/**
* @brief Creates a new buffer.
*
* @param size The size of the buffer to be made.
* @return The newly created buffer.
*/
char *setBufferSize(size_t size);
/**
* @brief Returns the size of the socket buffer.
*
* @return Size of the buffer.
*/
unsigned int getBufferSize() const;
/**
* @brief Copies any new socket data to the buffer and returns it.
*
* @return Socket buffer if new data is successfully received, nullptr otherwise.
*/
const char *getData();
/**
* @brief Returns the hostname of the server that the socket is connected to.
* Note: This is the same as getHost().
*
* @return String containing the hostname.
*/
const char *getHostname() const;
/**
* @brief Returns the local hostname of the local machine.
* Note: This allocated static memory, and should be copied for storage.
*
* @return String containing the hostname.
*/
static const char *getLocalHostname();
/**
* @brief Sets every byte in the buffer to 0.
*/
void clearBuffer();
/**
* @brief Writes new data from the socket to the buffer, without removing it from the socket queue.
* The data written by this function will always end with a null character, which is not counted in the returned value.
*
* @return Number of bytes written to buffer on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int peek();
/**
* @brief Writes new data from the socket to the buffer, without removing it from the socket queue.
* The data written by this function will always end with a null character, which is not counted in the returned value.
* A valid addrinfo object can be created using generateInfo().
*
* @param info Optional pointer to a valid addrinfo object to store the sender's information in.
* @return Number of bytes written to buffer on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int peekFrom(addrinfo *info);
/**
* @brief Writes new data from the socket to the buffer.
* The data written by this function will always end with a null character, which is not counted in the returned value.
*
* @return Number of bytes written to buffer on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int recv();
/**
* @brief Writes new data from the socket to the buffer.
* The data written by this function will always end with a null character, which is not counted in the returned value.
* A valid addrinfo object can be created using Use generateInfo().
*
* @param info Optional pointer to a valid addrinfo object to store the sender's information in.
* @return Number of bytes written to buffer on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int recvFrom(addrinfo *info);
int receive(); /** @see recv() */
/**
* @brief Sends data across the socket.
*
* @param data String containing the data to be send.
* @param datalen The size of the data to be sent, in chars.
* @return Number of bytes sent on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int send(const char *data, size_t datalen);
/**
* @brief Sends a null-terminated string of data across the socket.
*
* @param String containing the null-terminated data to send.
* @return Number of bytes sent on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int send(const char *msg);
/**
* @brief Sends data across the socket.
*
* @param info addrinfo containing the address information of the recipient.
* @param data String containing the data to be send.
* @param datalen The size of the data to be sent, in chars.
* @return Number of bytes sent on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int sendTo(const addrinfo *info, const char *data, size_t datalen);
/**
* @brief Sends a null-terminated string of data across the socket.
*
* @param info addrinfo containing the address information of the recipient.
* @param String containing the null-terminated data to send.
* @return Number of bytes sent on success, SOCKET_ERROR (-1) otherwise.
* Note: Any returned value less than or equal to 0 should be treated as an error.
*/
virtual int sendTo(const addrinfo *info, const char *msg);
int sendData(const char *data, size_t datalen); /** @see send() */
int sendData(const char *msg); /** @see send() */
/**
* @brief Returns the last error.
* On Windows, this currently just calls and returns WSAGetLastError().
* On other operating systems (UNIX), this returns errno.
* @return Error code.
*/
static int getLastError();
/**
* @brief Initializes any one-time background requirements for the Socket class to operate.
* In particular, this initializes WSA on Windows, required for any Socket operations.
* On Linux, however, this simply returns true.
* @return True on success, false otherwise.
*/
static bool init();
/**
* @brief Cleans up background requirements for the Socket class to operate.
* In particular, this cleans up WSA on Windows.
* On Linux, however, this simply returns true.
* @return True on success, false otherwise.
*/
static bool cleanup();
/**
* @brief Default constructor for the Socket class.
* This constructor will set the buffer size to 4096 chars.
*/
Socket();
/**
* @brief Copying a Socket is forbidden.
*/
Socket(const Socket &) = delete;
/**
* @brief Constructor for the Socket class which allows for the setting of a specific buffer size.
*
* @param bufferSize Size of the buffer to allocate, measured in chars.
*/
Socket(size_t bufferSize);
/**
* @brief Move constructor for the Socket class.
*
* @param Source Socket to move data from.
*/
Socket(Socket &&source);
/**
* @brief Constructor for the Socket class which allows for the use of a pre-existing buffer.
*
* @param buffer Buffer.
* @param bufferSize Size of the buffer.
*/
Socket(char *buffer, size_t bufferSize);
/**
* @brief Destructor for the Socket class.
*/
virtual ~Socket();
/** Private members */
private:
struct Data;
Data *data_;
};
}
#endif // _SOCKET_H_HEADER

258
Jupiter/String_Type.h

@ -0,0 +1,258 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _STRING_TYPE_H_HEADER
#define _STRING_TYPE_H_HEADER
#include "Jupiter.h"
#include <string> // std::basic_string<T> type
/**
* @file String_Type.h
* @brief Provides the basis for String types, of any implementation.
* Note: Some methods are commented out. This means that they should be implemented, but could not be put declared in this template (return of abstract type).
*/
namespace Jupiter
{
template<typename T = char> class String_Type
{
public:
/**
* @brief Returns a C-Style string version of the String.
*
* @return C-Style string representation of the String.
*/
virtual const T *c_str() const = 0;
/**
* @brief Returns the number of elements in the String.
*
* @return Number of elements in the string.
*/
virtual size_t size() const = 0;
/**
* @brief Compares another string against the String.
*
* @param in String to compare against.
* @return 0 if the strings are equal, negative if the first mismatched character is greater in the String, or positive if it's less.
*/
virtual int compare(const String_Type<T> &in) const = 0;
virtual int compare(const std::basic_string<T> &in) const = 0;
virtual int compare(const T *in) const = 0;
virtual int compare(const T in) const = 0;
/**
* @brief Checks if the strings are equal.
* Note: Case sensitive.
*
* @param in String to compare against.
* @return True if the contents of the strings are equal, false otherwise.
*/
virtual bool equals(const String_Type<T> &in) const = 0;
virtual bool equals(const std::basic_string<T> &in) const = 0;
virtual bool equals(const T *in) const = 0;
virtual bool equals(const T in) const = 0;
/**
* @brief Checks if the strings are equal.
* Note: Case insensitive. Returns false for any type other than char and wchar_t.
*
* @param in String to compare against.
* @return True if the contents of the strings are equal, false otherwise.
*/
virtual bool equalsi(const String_Type<T> &in) const = 0;
virtual bool equalsi(const std::basic_string<T> &in) const = 0;
virtual bool equalsi(const T *in) const = 0;
virtual bool equalsi(const T in) const = 0;
/**
* @brief Checks if the String matches a wildcard format.
* Note: Case sensitive.
*
* @param format Format that the string is compared against.
* @return True if the String matches the wildcard format, false otherwise.
*/
virtual bool match(const String_Type<T> &format) const = 0;
virtual bool match(const std::basic_string<T> &format) const = 0;
virtual bool match(const T *format) const = 0;
/**
* @brief Checks if the CString matches a wildcard format.
* Note: Case insensitive. Returns false for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @return True if the CString matches the wildcard format, false otherwise.
*/
virtual bool matchi(const String_Type<T> &format) const = 0;
virtual bool matchi(const std::basic_string<T> &format) const = 0;
virtual bool matchi(const T *format) const = 0;
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
virtual size_t format(const String_Type<T> &format, ...) = 0;
virtual size_t format(const std::basic_string<T> &format, ...) = 0;
virtual size_t format(const T *format, ...) = 0;
virtual size_t vformat(const T *format, va_list args) = 0;
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
*/
virtual size_t aformat(const String_Type<T> &format, ...) = 0;
virtual size_t aformat(const std::basic_string<T> &format, ...) = 0;
virtual size_t aformat(const T *format, ...) = 0;
virtual size_t avformat(const T *format, va_list args) = 0;
/**
* @brief Counts the number of token deliminated words.
*
* @param whitespace A string of tokens used to deliminate words.
* @return Number of words found.
*/
virtual unsigned int wordCount(const T *whitespace) const = 0;
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
//virtual String_Type<T> substring(size_t pos, size_t length) const = 0;
//String_Type<T> substr(size_t pos, size_t length) { return this->substring(pos, length); }
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
//virtual String_Type<T> getWord(size_t pos, T *whitespace) const = 0;
/**
* @brief Copies the data from the input string to the String.
*
* @param in String containing the data to be copied.
* @return New size of the String.
*/
virtual size_t set(const String_Type<T> &in) = 0;
virtual size_t set(const std::basic_string<T> &in) = 0;
virtual size_t set(const T *in) = 0;
virtual size_t set(const T in) = 0;
/**
* @brief Copies the data from the input string and concatenates it to the end of String.
*
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
virtual size_t concat(const String_Type<T> &in) = 0;
virtual size_t concat(const std::basic_string<T> &in) = 0;
virtual size_t concat(const T *in) = 0;
virtual size_t concat(const T in) = 0;
/**
* @brief Truncates the string by a specified number of elements.
*
* @param n Number of elements to remove from the tail.
* @return New size of the String.
*/
virtual size_t truncate(size_t n) = 0;
/**
* @brief Fetches an element from the string.
*
* @param index Index of the element to return.
* @return The element located at the specified index.
*/
virtual T &get(size_t index) const = 0;
/** Access operator */
inline T &operator[](size_t index) { return this->get(index); };
// Mutative operators.
// Note: All extending classes must overload operator= for its own type.
inline String_Type<T> &operator+=(const String_Type<T> &right) { this->concat(right); return *this; };
inline String_Type<T> &operator+=(const std::basic_string<T> &right) { this->concat(right); return *this; };
inline String_Type<T> &operator+=(const T *right) { this->concat(right); return *this; };
inline String_Type<T> &operator+=(const T right) { this->concat(right); return *this; };
inline String_Type<T> &operator-=(size_t right) { this->truncate(right); return *this; };
inline String_Type<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline String_Type<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline String_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline String_Type<T> &operator=(const T right) { this->set(right); return *this; };
// Comparative operators.
inline bool operator==(const String_Type<T> &right)const{ return this->equals(right); }
inline bool operator==(const std::basic_string<T> &right)const{ return this->equals(right); }
inline bool operator==(const T *right)const{ return this->equals(right); }
inline bool operator==(const T right)const{ return this->equals(right); }
inline bool operator!=(const String_Type<T> &right)const{ return !operator==(right); }
inline bool operator!=(const std::basic_string<T> &right)const{ return !operator==(right); }
inline bool operator!=(const T *right)const{ return !operator==(right); }
inline bool operator!=(const T right)const{ return !operator==(right); }
inline bool operator<(const String_Type<T> &right)const{ return this->compare(right) < 0; }
inline bool operator<(const std::basic_string<T> &right)const{ return this->compare(right) < 0; }
inline bool operator<(const T *right)const{ return this->compare(right) < 0; }
inline bool operator<(const T right)const{ return this->compare(right) < 0; }
inline bool operator>(const String_Type<T> &right)const{ return this->compare(right) > 0; }
inline bool operator>(const std::basic_string<T> &right)const{ return this->compare(right) > 0; }
inline bool operator>(const T *right)const{ return this->compare(right) > 0; }
inline bool operator>(const T right)const{ return this->compare(right) > 0; }
inline bool operator<=(const String_Type<T> &right)const{ return !operator>(right); }
inline bool operator<=(const std::basic_string<T> &right)const{ return !operator>(right); }
inline bool operator<=(const T *right)const{ return !operator>(right); }
inline bool operator<=(const T right)const{ return !operator>(right); }
inline bool operator>=(const String_Type<T> &right)const{ return !operator<(right); }
inline bool operator>=(const std::basic_string<T> &right)const{ return !operator<(right); }
inline bool operator>=(const T *right)const{ return !operator<(right); }
inline bool operator>=(const T right)const{ return !operator<(right); }
/**
* The following constructors should exist:
* A default constructor
* A copy constructor for the same class.
* A copy constructor for String_Type.
* A copy constructor for std::basic_string<T>.
* A copy constructor for C-style strings.
*/
};
/** Generic String Type */
typedef String_Type<char> StringType;
/** Generic Wide String Type */
typedef String_Type<wchar_t> WStringType;
}
#endif // _STRING_TYPE_H_HEADER

62
Jupiter/TCPSocket.cpp

@ -0,0 +1,62 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include <utility> // std::move
#include "TCPSocket.h"
#if defined _WIN32
#include <WinSock2.h>
#else // _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#endif // _WIN32
void setSocketTCP(Jupiter::Socket *sock)
{
sock->setType(SOCK_STREAM);
sock->setProtocol(IPPROTO_IP);
}
/** TCPSocket Implementation */
Jupiter::TCPSocket::TCPSocket() : Socket()
{
setSocketTCP(this);
}
Jupiter::TCPSocket::TCPSocket(size_t bufferSize) : Socket(bufferSize)
{
setSocketTCP(this);
}
Jupiter::TCPSocket::TCPSocket(Jupiter::Socket &&source) : Socket(std::move(source))
{
setSocketTCP(this);
}
/** SecureTCPSocket Implementation */
Jupiter::SecureTCPSocket::SecureTCPSocket() : SecureSocket()
{
setSocketTCP(this);
}
Jupiter::SecureTCPSocket::SecureTCPSocket(size_t bufferSize) : SecureSocket(bufferSize)
{
setSocketTCP(this);
}
Jupiter::SecureTCPSocket::SecureTCPSocket(Jupiter::Socket &&source) : SecureSocket(std::move(source))
{
setSocketTCP(this);
}
Jupiter::SecureTCPSocket::SecureTCPSocket(Jupiter::SecureSocket &&source) : SecureSocket(std::move(source))
{
setSocketTCP(this);
}

61
Jupiter/TCPSocket.h

@ -0,0 +1,61 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _TCPSOCKET_H_HEADER
#define _TCPSOCKET_H_HEADER
/**
* @file TCPSocket.h
* @brief Provides TCP socket interaction.
*/
#include "Jupiter.h"
#include "Socket.h"
#include "SecureSocket.h"
namespace Jupiter
{
/**
* @brief Provides TCP/IP support using sockets.
* @see Socket
*/
class JUPITER_API TCPSocket : public Socket
{
public:
TCPSocket();
TCPSocket(const TCPSocket &) = delete;
TCPSocket(size_t bufferSize);
TCPSocket(Jupiter::Socket &&source);
};
/**
* @brief Provides TCP/IP support using sockets and OpenSSL.
* @see SecureSocket
*/
class JUPITER_API SecureTCPSocket : public SecureSocket
{
public:
SecureTCPSocket();
SecureTCPSocket(const SecureTCPSocket &) = delete;
SecureTCPSocket(size_t bufferSize);
SecureTCPSocket(Jupiter::Socket &&source);
SecureTCPSocket(Jupiter::SecureSocket &&source);
};
}
#endif // _TCPSOCKET_H_HEADER

54
Jupiter/Thinker.h

@ -0,0 +1,54 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _THINKER_H_HEADER
#define _THINKER_H_HEADER
/**
* @file Thinker.h
* @brief Provides the Thinker abstract interface.
*/
#include "Jupiter.h"
namespace Jupiter
{
/**
* @brief Provides an abstract interface with a think() method.
* The Thinker interface is intended for objects that need to be regularly
* processed by some sort of Thinker manager. Thinkers should return 1 if no
* real error occurs, but do no require future processing.
*/
class JUPITER_API Thinker
{
public:
/**
* @brief Makes an object think. Should return 0 if no error occurs.
*
* @return Error number.
*/
virtual int think() = 0;
/**
* @brief Virtual destructor for the "Thinker" interface. Does nothing.
*/
virtual ~Thinker() {}
};
}
#endif // _THINKER_H_HEADER

148
Jupiter/Timer.cpp

@ -0,0 +1,148 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include "Timer.h"
#include "DLList.h"
Jupiter::DLList<Jupiter::Timer> timers;
/** Deallocates timers when the library is unloaded. */
struct TimerKiller
{
~TimerKiller();
} timerKiller;
TimerKiller::~TimerKiller()
{
killTimers();
}
struct Jupiter::Timer::Data
{
void (*function)(unsigned int, void *);
void (*functionNoParams)(unsigned int);
void *parameters;
time_t nextCall;
time_t delay;
int iterations;
};
Jupiter::Timer::Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate)
{
Jupiter::Timer::data_ = new Jupiter::Timer::Data();
Jupiter::Timer::data_->function = function;
Jupiter::Timer::data_->functionNoParams = nullptr;
Jupiter::Timer::data_->parameters = parameters;
Jupiter::Timer::data_->iterations = iterations;
Jupiter::Timer::data_->delay = timeDelay;
Jupiter::Timer::data_->nextCall = immediate ? time(0) : time(0) + timeDelay;
timers.add(this);
}
Jupiter::Timer::Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int), bool immediate)
{
Jupiter::Timer::data_ = new Jupiter::Timer::Data();
Jupiter::Timer::data_->function = nullptr;
Jupiter::Timer::data_->functionNoParams = function;
Jupiter::Timer::data_->parameters = nullptr;
Jupiter::Timer::data_->iterations = iterations;
Jupiter::Timer::data_->delay = timeDelay;
Jupiter::Timer::data_->nextCall = immediate ? time(0) : time(0) + timeDelay;
timers.add(this);
}
Jupiter::Timer::~Timer()
{
delete Jupiter::Timer::data_;
}
int Jupiter::Timer::think()
{
if (Jupiter::Timer::data_->nextCall <= time(0))
{
int killMe = 0;
if (Jupiter::Timer::data_->iterations != 0 && --Jupiter::Timer::data_->iterations == 0) killMe = 1;
if (Jupiter::Timer::data_->function != nullptr) Jupiter::Timer::data_->function(Jupiter::Timer::data_->iterations, Jupiter::Timer::data_->parameters);
else Jupiter::Timer::data_->functionNoParams(Jupiter::Timer::data_->iterations);
Jupiter::Timer::data_->nextCall = Jupiter::Timer::data_->delay + time(0);
return killMe;
}
return 0;
}
bool Jupiter::Timer::removeFromList()
{
if (timers.size() == 0) return false;
for (Jupiter::DLList<Jupiter::Timer>::Node *n = timers.getNode(0); n != nullptr; n = n->next)
{
if (n->data == this)
{
timers.remove(n);
return true;
}
}
return false;
}
bool Jupiter::Timer::kill()
{
if (Jupiter::Timer::removeFromList())
{
delete this;
return true;
}
delete this;
return false;
}
extern "C" void addTimer(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int, void *), void *parameters)
{
new Jupiter::Timer(iterations, timeDelay, function, parameters, immediate);
}
extern "C" void addTimerNoParams(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int))
{
new Jupiter::Timer(iterations, timeDelay, function, immediate);
}
extern "C" unsigned int totalTimers()
{
return timers.size();
}
extern "C" unsigned int checkTimers()
{
unsigned int r = 0;
Jupiter::Timer *t;
Jupiter::DLList<Jupiter::Timer>::Node *o;
Jupiter::DLList<Jupiter::Timer>::Node *n = timers.size() == 0 ? nullptr : timers.getNode(0);
while (n != nullptr)
{
t = n->data;
if (t->think() != 0)
{
o = n;
n = n->next;
delete timers.remove(o);
r++;
}
else n = n->next;
}
return r;
}
extern "C" unsigned int killTimers()
{
unsigned int r = timers.size();
while (timers.size() != 0) delete timers.remove(unsigned int(0));
return r;
}

191
Jupiter/Timer.h

@ -0,0 +1,191 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _TIMER_H_HEADER
#define _TIMER_H_HEADER
/**
* @file Timer.h
* @brief Provides an timed event system.
*/
#include "Jupiter.h"
#if defined __cplusplus
#include <ctime>
#include "Thinker.h"
namespace Jupiter
{
/**
* @brief Provides an interface for adding timed events.
*/
class JUPITER_API Timer : public Thinker
{
public:
/**
* @brief Checks if the timed function should be called, and calls it if neccessary.
* Note: This is primarily used internally by checkTimers().
*
* @return 0 if the function still has more iterations to call, a number otherwise.
*/
int think();
/**
* @brief Removes the timer from the timer list, without destroying it.
* Note: You MUST delete the timer later yourself after calling this.
*
* @return True if the timer was removed from the list, false otherwise.
*/
bool removeFromList();
/**
* @brief Immediately destroys the timer and removes it from the timer list.
*
* @return True if the timer was removed from the list, false otherwise.
*/
bool kill();
/**
* @brief Constructs a timer and adds itself to the timer list.
* Note: This assumes infinite iterations, with as little time delay as possible.
*
* @param function Function for the timer to call.
* @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(void(*function)(unsigned int, void *), void *parameters, bool immediate = false) : Timer(unsigned int(0), time_t(0), function, parameters, immediate) {}
/**
* @brief Constructs a timer and adds itself to the timer list.
* Note: This assumes infinite iterations, with as little time delay as possible.
*
* @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(void(*function)(unsigned int), bool immediate = false) : Timer(unsigned int(0), time_t(0), function, immediate) {}
/**
* @brief Constructs a timer and adds itself to the timer list.
* Note: This assumes infinite iterations.
*
* @param timeDelay Delay in seconds between executions of the timed function.
* @param function Function for the timer to call.
* @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate = false) : Timer(unsigned int(0), timeDelay, function, parameters, immediate) {}
/**
* @brief Constructs a timer and adds itself to the timer list.
* Note: This assumes infinite iterations.
*
* @param timeDelay Delay in seconds between executions of the timed function.
* @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(time_t timeDelay, void(*function)(unsigned int), bool immediate = false) : Timer(unsigned int(0), timeDelay, function, immediate) {}
/**
* @brief Constructs a timer and adds itself to the timer list.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer should execute indefinitely.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param function Function for the timer to call.
* @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate = false);
/**
* @brief Constructs a timer and adds itself to the timer list.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer should execute indefinitely.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check.
*/
Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int), bool immediate = false);
/**
* @brief Destructor for the Timer class.
*/
~Timer();
/** Private data members */
private:
struct Data;
Data *data_;
};
}
extern "C"
{
#else
#include <stdbool.h>
#include <time.h>
#endif // _cplusplus
/**
* @brief Creates a timer.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer is indefinite.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param immediate True if the function should be execute on the next check.
* @param function Function for the timer to call.
* @param parameters Parameters to pass to the function.
*/
JUPITER_API void addTimer(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int, void *), void *parameters);
/**
* @brief Creates a timer.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer is indefinite.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param immediate True if the function should be execute on the next check.
* @param function Function for the timer to call.
*/
JUPITER_API void addTimerNoParams(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int));
/**
* @brief Fetches the number of active timers.
*
* @return Total number of timers active.
*/
JUPITER_API unsigned int totalTimers();
/**
* @brief Calls think() for every timer, and removes them if neccessary.
*
* @return Total number of timers removed.
*/
JUPITER_API unsigned int checkTimers();
/**
* @brief Immediately destroys all timers.
*
* @return Total number of timers removed.
*/
JUPITER_API unsigned int killTimers();
#if defined __cplusplus
}
#endif // __cplusplus
#endif // _TIMER_H_HEADER

22
Jupiter/UDPSocket.cpp

@ -0,0 +1,22 @@
/**
* Copyright (C) Justin James - All Rights Reserved.
* Unauthorized use or copying of this file via any medium is strictly prohibited.
* This document is proprietary and confidential.
* This document should be immediately destroyed unless given explicit permission by Justin James.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include "UDPSocket.h"
#if defined _WIN32
#include <WinSock2.h>
#else // _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#endif // _WIN32
Jupiter::UDPSocket::UDPSocket()
{
this->setType(SOCK_DGRAM);
this->setProtocol(IPPROTO_UDP);
}

43
Jupiter/UDPSocket.h

@ -0,0 +1,43 @@
/**
* Copyright (C) 2013-2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _UDPSOCKET_H_HEADER
#define _UDPSOCKET_H_HEADER
/**
* @file UDPSocket.h
* @brief Provides UDP socket interaction.
*/
#include "Jupiter.h"
#include "Socket.h"
namespace Jupiter
{
/**
* @brief Provides UDP/IP support using sockets.
* @see Socket
*/
class JUPITER_API UDPSocket : public Socket
{
public:
UDPSocket();
};
}
#endif // _UDPSOCKET_H_HEADER

14
Jupiter/resource.h

@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Jupiter.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

BIN
Release/Jupiter.lib

Binary file not shown.

51
Tester/Test.cpp

@ -0,0 +1,51 @@
#include <chrono>
#include <string>
#include "../Jupiter/Functions.h"
#include "../Jupiter/CString.h"
#include "../Jupiter/File.h"
#include "../Jupiter/Base64.h"
#include "../Jupiter/InvalidIndex.h"
const char *tString = "ZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMGZOMG";
const char *tStringL = "zomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomgzomg";
Jupiter::CStringL lString = "message message message message message message message message message message message message message message message \r\n\r\nmessage message message message message message \rmessage message message\n message message message message message message message message message message message message message message message message message message message message message message message message message message message message message ";
Jupiter::CStringL tString2;
int test()
{
return Jupiter::strlen(tString2.c_str());
//return strmatch("ZOMG ?SS CHEEKS! LOLOLOLOL", "ZOMG ASS CHEEKS! LOLOLOLOL");
}
int test2()
{
return ::strlen(tString2.c_str());
//return strmatchi("ZOMG ?SS CHEEKS! LOLOLOLOL", "ZOMG ASS CHEEKS! LOLOLOLOL");
}
char *randgen(size_t size)
{
char *r = new char[size + 1];
r[size] = 0;
while (size > 0)
{
size--;
r[size] = rand() % 255 + 1;
}
return r;
}
using namespace Jupiter;
int main()
{
printf("%u - %u - %llu" ENDL, INVALID_INDEX, INVALID_INDEX32, INVALID_INDEX64);
printf("%u - %u - %llu" ENDL, UINT_MAX, UINT32_MAX, UINT64_MAX);
#if defined _WIN32
system("pause");
#endif // _WIN32
return 0;
}

87
Tester/Tester.vcxproj

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0F041791-1047-4C6A-A4C1-814E6957D5EB}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Tester</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Test.cpp" />
</ItemGroup>
<ItemGroup>
<Library Include="..\Release\Jupiter.lib" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

27
Tester/Tester.vcxproj.filters

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="..\Release\Jupiter.lib">
<Filter>Resource Files</Filter>
</Library>
</ItemGroup>
</Project>
Loading…
Cancel
Save