PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/raknet/RakString.h

https://gitlab.com/computerphilly/openblox
C Header | 354 lines | 150 code | 82 blank | 122 comment | 1 complexity | e3106016f89303ecca6b81c266b31dca MD5 | raw file
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #ifndef __RAK_STRING_H
  11. #define __RAK_STRING_H
  12. #include "Export.h"
  13. #include "DS_List.h"
  14. #include "RakNetTypes.h" // int64_t
  15. #include <stdio.h>
  16. #include "stdarg.h"
  17. #ifdef _WIN32
  18. #include "WindowsIncludes.h"
  19. #endif
  20. namespace RakNet
  21. {
  22. /// Forward declarations
  23. class SimpleMutex;
  24. class BitStream;
  25. /// \brief String class
  26. /// \details Has the following improvements over std::string
  27. /// -Reference counting: Suitable to store in lists
  28. /// -Variadic assignment operator
  29. /// -Doesn't cause linker errors
  30. class RAK_DLL_EXPORT RakString
  31. {
  32. public:
  33. // Constructors
  34. RakString();
  35. RakString(char input);
  36. RakString(unsigned char input);
  37. RakString(const unsigned char *format, ...);
  38. RakString(const char *format, ...);
  39. ~RakString();
  40. RakString( const RakString & rhs);
  41. /// Implicit return of const char*
  42. operator const char* () const {return sharedString->c_str;}
  43. /// Same as std::string::c_str
  44. const char *C_String(void) const {return sharedString->c_str;}
  45. // Lets you modify the string. Do not make the string longer - however, you can make it shorter, or change the contents.
  46. // Pointer is only valid in the scope of RakString itself
  47. char *C_StringUnsafe(void) {Clone(); return sharedString->c_str;}
  48. /// Assigment operators
  49. RakString& operator = ( const RakString& rhs );
  50. RakString& operator = ( const char *str );
  51. RakString& operator = ( char *str );
  52. RakString& operator = ( const unsigned char *str );
  53. RakString& operator = ( char unsigned *str );
  54. RakString& operator = ( const char c );
  55. /// Concatenation
  56. RakString& operator +=( const RakString& rhs);
  57. RakString& operator += ( const char *str );
  58. RakString& operator += ( char *str );
  59. RakString& operator += ( const unsigned char *str );
  60. RakString& operator += ( char unsigned *str );
  61. RakString& operator += ( const char c );
  62. /// Character index. Do not use to change the string however.
  63. unsigned char operator[] ( const unsigned int position ) const;
  64. #ifdef _WIN32
  65. // Return as Wide char
  66. // Deallocate with DeallocWideChar
  67. WCHAR * ToWideChar(void);
  68. void DeallocWideChar(WCHAR * w);
  69. void FromWideChar(const wchar_t *source);
  70. static RakNet::RakString FromWideChar_S(const wchar_t *source);
  71. #endif
  72. /// String class find replacement
  73. /// Searches the string for the content specified in stringToFind and returns the position of the first occurrence in the string.
  74. /// Search only includes characters on or after position pos, ignoring any possible occurrences in previous locations.
  75. /// \param[in] stringToFind The string to find inside of this object's string
  76. /// \param[in] pos The position in the string to start the search
  77. /// \return Returns the position of the first occurrence in the string.
  78. size_t Find(const char *stringToFind,size_t pos = 0 );
  79. /// Equality
  80. bool operator==(const RakString &rhs) const;
  81. bool operator==(const char *str) const;
  82. bool operator==(char *str) const;
  83. // Comparison
  84. bool operator < ( const RakString& right ) const;
  85. bool operator <= ( const RakString& right ) const;
  86. bool operator > ( const RakString& right ) const;
  87. bool operator >= ( const RakString& right ) const;
  88. /// Inequality
  89. bool operator!=(const RakString &rhs) const;
  90. bool operator!=(const char *str) const;
  91. bool operator!=(char *str) const;
  92. /// Change all characters to lowercase
  93. const char * ToLower(void);
  94. /// Change all characters to uppercase
  95. const char * ToUpper(void);
  96. /// Set the value of the string
  97. void Set(const char *format, ...);
  98. /// Sets a copy of a substring of str as the new content. The substring is the portion of str
  99. /// that begins at the character position pos and takes up to n characters
  100. /// (it takes less than n if the end of str is reached before).
  101. /// \param[in] str The string to copy in
  102. /// \param[in] pos The position on str to start the copy
  103. /// \param[in] n How many chars to copy
  104. /// \return Returns the string, note that the current string is set to that value as well
  105. RakString Assign(const char *str,size_t pos, size_t n );
  106. /// Returns if the string is empty. Also, C_String() would return ""
  107. bool IsEmpty(void) const;
  108. /// Returns the length of the string
  109. size_t GetLength(void) const;
  110. size_t GetLengthUTF8(void) const;
  111. /// Replace character(s) in starting at index, for count, with c
  112. void Replace(unsigned index, unsigned count, unsigned char c);
  113. /// Replace character at index with c
  114. void SetChar( unsigned index, unsigned char c );
  115. /// Replace character at index with string s
  116. void SetChar( unsigned index, RakNet::RakString s );
  117. /// Make sure string is no longer than \a length
  118. void Truncate(unsigned int length);
  119. void TruncateUTF8(unsigned int length);
  120. // Gets the substring starting at index for count characters
  121. RakString SubStr(unsigned int index, unsigned int count) const;
  122. /// Erase characters out of the string at index for count
  123. void Erase(unsigned int index, unsigned int count);
  124. /// Set the first instance of c with a NULL terminator
  125. void TerminateAtFirstCharacter(char c);
  126. /// Set the last instance of c with a NULL terminator
  127. void TerminateAtLastCharacter(char c);
  128. void StartAfterFirstCharacter(char c);
  129. void StartAfterLastCharacter(char c);
  130. /// Returns how many occurances there are of \a c in the string
  131. int GetCharacterCount(char c);
  132. /// Remove all instances of c
  133. void RemoveCharacter(char c);
  134. /// Create a RakString with a value, without doing printf style parsing
  135. /// Equivalent to assignment operator
  136. static RakNet::RakString NonVariadic(const char *str);
  137. /// Hash the string into an unsigned int
  138. static unsigned long ToInteger(const char *str);
  139. static unsigned long ToInteger(const RakString &rs);
  140. /// \brief Read an integer out of a substring
  141. /// \param[in] str The string
  142. /// \param[in] pos The position on str where the integer starts
  143. /// \param[in] n How many chars to copy
  144. static int ReadIntFromSubstring(const char *str, size_t pos, size_t n);
  145. // Like strncat, but for a fixed length
  146. void AppendBytes(const char *bytes, unsigned int count);
  147. /// Compare strings (case sensitive)
  148. int StrCmp(const RakString &rhs) const;
  149. /// Compare strings (case sensitive), up to num characters
  150. int StrNCmp(const RakString &rhs, size_t num) const;
  151. /// Compare strings (not case sensitive)
  152. int StrICmp(const RakString &rhs) const;
  153. /// Clear the string
  154. void Clear(void);
  155. /// Print the string to the screen
  156. void Printf(void);
  157. /// Print the string to a file
  158. void FPrintf(FILE *fp);
  159. /// Does the given IP address match the IP address encoded into this string, accounting for wildcards?
  160. bool IPAddressMatch(const char *IP);
  161. /// Does the string contain non-printable characters other than spaces?
  162. bool ContainsNonprintableExceptSpaces(void) const;
  163. /// Is this a valid email address?
  164. bool IsEmailAddress(void) const;
  165. /// URL Encode the string. See http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4029/
  166. RakNet::RakString& URLEncode(void);
  167. /// URL decode the string
  168. RakNet::RakString& URLDecode(void);
  169. /// https://servers.api.rackspacecloud.com/v1.0 to https://, servers.api.rackspacecloud.com, /v1.0
  170. void SplitURI(RakNet::RakString &header, RakNet::RakString &domain, RakNet::RakString &path);
  171. /// Scan for quote, double quote, and backslash and prepend with backslash
  172. RakNet::RakString& SQLEscape(void);
  173. /// Format as a POST command that can be sent to a webserver
  174. /// \param[in] uri For example, masterserver2.raknet.com/testServer
  175. /// \param[in] contentType For example, text/plain; charset=UTF-8
  176. /// \param[in] body Body of the post
  177. /// \return Formatted string
  178. static RakNet::RakString FormatForPOST(const char* uri, const char* contentType, const char* body, const char* extraHeaders="");
  179. static RakNet::RakString FormatForPUT(const char* uri, const char* contentType, const char* body, const char* extraHeaders="");
  180. /// Format as a GET command that can be sent to a webserver
  181. /// \param[in] uri For example, masterserver2.raknet.com/testServer?__gameId=comprehensivePCGame
  182. /// \return Formatted string
  183. static RakNet::RakString FormatForGET(const char* uri, const char* extraHeaders="");
  184. /// Format as a DELETE command that can be sent to a webserver
  185. /// \param[in] uri For example, masterserver2.raknet.com/testServer?__gameId=comprehensivePCGame&__rowId=1
  186. /// \return Formatted string
  187. static RakNet::RakString FormatForDELETE(const char* uri, const char* extraHeaders="");
  188. /// Fix to be a file path, ending with /
  189. RakNet::RakString& MakeFilePath(void);
  190. /// RakString uses a freeList of old no-longer used strings
  191. /// Call this function to clear this memory on shutdown
  192. static void FreeMemory(void);
  193. /// \internal
  194. static void FreeMemoryNoMutex(void);
  195. /// Serialize to a bitstream, uncompressed (slightly faster)
  196. /// \param[out] bs Bitstream to serialize to
  197. void Serialize(BitStream *bs) const;
  198. /// Static version of the Serialize function
  199. static void Serialize(const char *str, BitStream *bs);
  200. /// Serialize to a bitstream, compressed (better bandwidth usage)
  201. /// \param[out] bs Bitstream to serialize to
  202. /// \param[in] languageId languageId to pass to the StringCompressor class
  203. /// \param[in] writeLanguageId encode the languageId variable in the stream. If false, 0 is assumed, and DeserializeCompressed will not look for this variable in the stream (saves bandwidth)
  204. /// \pre StringCompressor::AddReference must have been called to instantiate the class (Happens automatically from RakPeer::Startup())
  205. void SerializeCompressed(BitStream *bs, uint8_t languageId=0, bool writeLanguageId=false) const;
  206. /// Static version of the SerializeCompressed function
  207. static void SerializeCompressed(const char *str, BitStream *bs, uint8_t languageId=0, bool writeLanguageId=false);
  208. /// Deserialize what was written by Serialize
  209. /// \param[in] bs Bitstream to serialize from
  210. /// \return true if the deserialization was successful
  211. bool Deserialize(BitStream *bs);
  212. /// Static version of the Deserialize() function
  213. static bool Deserialize(char *str, BitStream *bs);
  214. /// Deserialize compressed string, written by SerializeCompressed
  215. /// \param[in] bs Bitstream to serialize from
  216. /// \param[in] readLanguageId If true, looks for the variable langaugeId in the data stream. Must match what was passed to SerializeCompressed
  217. /// \return true if the deserialization was successful
  218. /// \pre StringCompressor::AddReference must have been called to instantiate the class (Happens automatically from RakPeer::Startup())
  219. bool DeserializeCompressed(BitStream *bs, bool readLanguageId=false);
  220. /// Static version of the DeserializeCompressed() function
  221. static bool DeserializeCompressed(char *str, BitStream *bs, bool readLanguageId=false);
  222. static const char *ToString(int64_t i);
  223. static const char *ToString(uint64_t i);
  224. /// \internal
  225. static size_t GetSizeToAllocate(size_t bytes)
  226. {
  227. const size_t smallStringSize = 128-sizeof(unsigned int)-sizeof(size_t)-sizeof(char*)*2;
  228. if (bytes<=smallStringSize)
  229. return smallStringSize;
  230. else
  231. return bytes*2;
  232. }
  233. /// \internal
  234. struct SharedString
  235. {
  236. SimpleMutex *refCountMutex;
  237. unsigned int refCount;
  238. size_t bytesUsed;
  239. char *bigString;
  240. char *c_str;
  241. char smallString[128-sizeof(unsigned int)-sizeof(size_t)-sizeof(char*)*2];
  242. };
  243. /// \internal
  244. RakString( SharedString *_sharedString );
  245. /// \internal
  246. SharedString *sharedString;
  247. // static SimpleMutex poolMutex;
  248. // static DataStructures::MemoryPool<SharedString> pool;
  249. /// \internal
  250. static SharedString emptyString;
  251. //static SharedString *sharedStringFreeList;
  252. //static unsigned int sharedStringFreeListAllocationCount;
  253. /// \internal
  254. /// List of free objects to reduce memory reallocations
  255. static DataStructures::List<SharedString*> freeList;
  256. static int RakStringComp( RakString const &key, RakString const &data );
  257. static void LockMutex(void);
  258. static void UnlockMutex(void);
  259. protected:
  260. static RakNet::RakString FormatForPUTOrPost(const char* type, const char* uri, const char* contentType, const char* body, const char* extraHeaders);
  261. void Allocate(size_t len);
  262. void Assign(const char *str);
  263. void Assign(const char *str, va_list ap);
  264. void Clone(void);
  265. void Free(void);
  266. unsigned char ToLower(unsigned char c);
  267. unsigned char ToUpper(unsigned char c);
  268. void Realloc(SharedString *sharedString, size_t bytes);
  269. };
  270. }
  271. const RakNet::RakString RAK_DLL_EXPORT operator+(const RakNet::RakString &lhs, const RakNet::RakString &rhs);
  272. #endif