Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
14 KiB

  1. //========= Copyright � 1996-2010, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose: Header for CWebAPIResponse objects
  4. //
  5. //=============================================================================
  6. #ifndef WEBAPI_RESPONSE_H
  7. #define WEBAPI_RESPONSE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "tier0/memdbgon.h"
  12. namespace GCSDK
  13. {
  14. enum EWebAPIOutputFormat
  15. {
  16. k_EWebAPIOutputFormat_JSON = 1,
  17. k_EWebAPIOutputFormat_XML = 2,
  18. k_EWebAPIOutputFormat_VDF = 3,
  19. k_EWebAPIOutputFormat_ParameterEncoding = 4,
  20. };
  21. enum EWebAPIValueType
  22. {
  23. // Object is the initial value
  24. k_EWebAPIValueType_Object = 0,
  25. k_EWebAPIValueType_Int32 = 1,
  26. k_EWebAPIValueType_Int64 = 2,
  27. k_EWebAPIValueType_UInt32 = 3,
  28. k_EWebAPIValueType_UInt64 = 4,
  29. k_EWebAPIValueType_Double = 5,
  30. k_EWebAPIValueType_String = 6,
  31. k_EWebAPIValueType_BinaryBlob = 7,
  32. k_EWebAPIValueType_Bool = 8,
  33. k_EWebAPIValueType_Null = 9,
  34. k_EWebAPIValueType_NumericArray = 10,
  35. };
  36. class CWebAPIValues;
  37. class CWebAPIResponse
  38. {
  39. public:
  40. CWebAPIResponse();
  41. ~CWebAPIResponse();
  42. // Set the HTTP status code for the response
  43. void SetStatusCode( EHTTPStatusCode eStatusCode ) { m_eStatusCode = eStatusCode; }
  44. // Set how many seconds until this response expires
  45. void SetExpirationSeconds( uint32 unExpirationSeconds ) { m_unExpirationSeconds = unExpirationSeconds; }
  46. // Set when this response was last modified
  47. void SetLastModified( RTime32 rtLastModified ) { m_rtLastModified = rtLastModified; }
  48. // Get the status code for the response
  49. EHTTPStatusCode GetStatusCode() { return m_eStatusCode; }
  50. // Get how many seconds until this response expires
  51. uint32 GetExpirationSeconds() { return m_unExpirationSeconds; }
  52. // Get when the response was last modified
  53. RTime32 GetLastModified() { return m_rtLastModified; }
  54. // extended arrays include their element name as an object in JSON and VDF output formats
  55. void SetExtendedArrays( bool bExtendedArrays ) { m_bExtendedArrays = bExtendedArrays; }
  56. bool HasExtendedArrays() const { return m_bExtendedArrays; }
  57. // Outputs formatted data to buffer
  58. bool BEmitFormattedOutput( EWebAPIOutputFormat eFormat, CUtlBuffer &outputBuffer, size_t unMaxResultSize );
  59. // Resets the response to be empty
  60. void Clear();
  61. // Create the root value element in the response
  62. CWebAPIValues *CreateRootValue( const char *pchName );
  63. CWebAPIValues *GetRootValue() { return m_pValues; }
  64. private:
  65. // Emits JSON formatted representation of response
  66. bool BEmitJSON( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
  67. // Emits KeyValues .vdf style formatted representation of response
  68. bool BEmitVDF( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
  69. // Emits XML formatted representation of response
  70. bool BEmitXML( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
  71. // parameter encoding, as used in a lot of open standards
  72. bool BEmitParameterEncoding( CUtlBuffer &outputBuffer );
  73. CWebAPIValues *m_pValues;
  74. EHTTPStatusCode m_eStatusCode;
  75. uint32 m_unExpirationSeconds;
  76. RTime32 m_rtLastModified;
  77. bool m_bExtendedArrays;
  78. };
  79. class CWebAPIValues
  80. {
  81. public:
  82. CWebAPIValues( CWebAPIValues *pParent, const char *pchName, EWebAPIValueType eValueType, const char *pchArrayElementNames = NULL );
  83. ~CWebAPIValues();
  84. //
  85. // Child node handling
  86. //
  87. // Create a child object of this node, all children of the resultant
  88. // object must be named.
  89. CWebAPIValues *CreateChildObject( const char *pchName );
  90. // Add a child object to the array, this should only be called on objects that are of the array type
  91. CWebAPIValues *AddChildObjectToArray();
  92. // Add a child array to the array, this should only be called on objects that are of the array type
  93. CWebAPIValues *AddChildArrayToArray( const char * pchArrayElementNames );
  94. // Create a child array of this node. Note that array nodes can only
  95. // have un-named children, in XML the pchArrayElementNames value will be used
  96. // as the element name for each of the children of the array, in JSON it will simply
  97. // be a numerically indexed [] array.
  98. CWebAPIValues *CreateChildArray( const char *pchName, const char *pchArrayElementNames );
  99. // Find first matching child by name, O(N) on number of children, this class isn't designed for searching
  100. CWebAPIValues * FindChild( const char *pchName );
  101. const CWebAPIValues * FindChild( const char *pchName ) const { return const_cast<CWebAPIValues *>(this)->FindChild( pchName ); }
  102. // Get the first child of this node
  103. CWebAPIValues * GetFirstChild();
  104. const CWebAPIValues * GetFirstChild() const { return m_pFirstChild; }
  105. // Call this on the returned value from GetFirstChild() or a previous GetNextChild() call to
  106. // proceed to the next child of the parent GetFirstChild() was originally called on.
  107. CWebAPIValues * GetNextChild();
  108. const CWebAPIValues * GetNextChild() const { return m_pNextPeer; }
  109. // Returns the parent of this node or NULL if this is the root of a tree
  110. CWebAPIValues * GetParent();
  111. const CWebAPIValues * GetParent() const { return m_pParent; }
  112. // Deletes the child with the given name - no-op if no child by that name
  113. void DeleteChild( const char *pchName );
  114. //
  115. // Setters
  116. //
  117. // Set string value
  118. void SetStringValue( const char *pchValue );
  119. // Set int32 value
  120. void SetInt32Value( int32 nValue );
  121. // Set uint32 value
  122. void SetUInt32Value( uint32 unValue );
  123. // Set int64 value
  124. void SetInt64Value ( int64 lValue );
  125. // Set uint64 value
  126. void SetUInt64Value( uint64 ulValue );
  127. // Set double value
  128. void SetDoubleValue( double flValue );
  129. // Set binary blob value
  130. void SetBinaryValue( uint8 *pValue, uint32 unBytes );
  131. // Set boolean value
  132. void SetBoolValue( bool bValue );
  133. // Set boolean value
  134. void SetNullValue( );
  135. //
  136. // Accessors
  137. //
  138. // Get the name of the current node
  139. const char *GetName() const { return m_pchName; }
  140. // get the name of the elements of this numeric array (if this is an array)
  141. const char *GetElementName() const { return m_pchArrayChildElementName; }
  142. // Get the type currently held by the node
  143. EWebAPIValueType GetType() const;
  144. // returns true if this is an object
  145. bool IsObject() const { return GetType() == k_EWebAPIValueType_Object; }
  146. // returns true if this is an object
  147. bool IsArray() const { return GetType() == k_EWebAPIValueType_NumericArray; }
  148. // Get int32 value
  149. int32 GetInt32Value() const;
  150. // Get uint32 value
  151. uint32 GetUInt32Value() const;
  152. // Get int64 value
  153. int64 GetInt64Value() const;
  154. // Get uint64 value
  155. uint64 GetUInt64Value() const;
  156. // Get double value
  157. double GetDoubleValue() const;
  158. // Get string value
  159. void GetStringValue( CUtlString &stringOut ) const;
  160. // Get binary blob value
  161. void GetBinaryValue( CUtlBuffer &bufferOut ) const;
  162. // Get bool value
  163. bool GetBoolValue() const;
  164. // Get Null value
  165. bool IsNullValue() const { return GetType() == k_EWebAPIValueType_Null; }
  166. //
  167. // Child Setters
  168. //
  169. // Set string value
  170. void SetChildStringValue( const char *pchChildName, const char *pchValue );
  171. // Set int32 value
  172. void SetChildInt32Value( const char *pchChildName, int32 nValue );
  173. // Set uint32 value
  174. void SetChildUInt32Value( const char *pchChildName, uint32 unValue );
  175. // Set int64 value
  176. void SetChildInt64Value ( const char *pchChildName, int64 lValue );
  177. // Set uint64 value
  178. void SetChildUInt64Value( const char *pchChildName, uint64 ulValue );
  179. // Set double value
  180. void SetChildDoubleValue( const char *pchChildName, double flValue );
  181. // Set binary blob value
  182. void SetChildBinaryValue( const char *pchChildName, uint8 *pValue, uint32 unBytes );
  183. // Set boolean value
  184. void SetChildBoolValue( const char *pchChildName, bool bValue );
  185. // Set null value
  186. void SetChildNullValue( const char *pchChildName );
  187. //
  188. // Accessors
  189. //
  190. // Get int32 value
  191. int32 GetChildInt32Value( const char *pchChildName, int32 nDefault = 0 ) const;
  192. // Get uint32 value
  193. uint32 GetChildUInt32Value( const char *pchChildName, uint32 unDefault = 0 ) const;
  194. // Get int64 value
  195. int64 GetChildInt64Value( const char *pchChildName, int64 lDefault = 0 ) const;
  196. // Get uint64 value
  197. uint64 GetChildUInt64Value( const char *pchChildName, uint64 ulDefault = 0 ) const;
  198. // Get double value
  199. double GetChildDoubleValue( const char *pchChildName, double flDefault = 0 ) const;
  200. // Get string value
  201. void GetChildStringValue( CUtlString &stringOut, const char *pchChildName, const char *pchDefault ) const;
  202. // Get binary blob value (returns false if the child wasn't found)
  203. bool BGetChildBinaryValue( CUtlBuffer &bufferOut, const char *pchChildName ) const;
  204. // Get bool value
  205. bool GetChildBoolValue( const char *pchChildName, bool bDefault = false ) const;
  206. // get null value
  207. bool IsChildNullValue( const char *pchChildName ) const;
  208. //
  209. // Output methods
  210. //
  211. // Emits JSON formatted representation of response
  212. static bool BEmitJSONRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer, int nTabLevel, size_t unMaxResultSize, bool bIncludeArrayElementName = true );
  213. // Emits KeyValues .vdf style formatted representation of response
  214. static bool BEmitVDFRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer, int nTabLevel, uint32 nArrayElement, size_t unMaxResultSize, bool bIncludeArrayElementName = true );
  215. // Emits XML formatted representation of response
  216. static bool BEmitXMLRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer,int nTabLevel, size_t unMaxResultSize );
  217. //
  218. // Parsing methods
  219. //
  220. // parses JSON into a tree of CWebAPIValues nodes.
  221. static CWebAPIValues * ParseJSON( CUtlBuffer &inputBuffer );
  222. static CWebAPIValues * ParseJSON( const char *pchJSONString );
  223. //
  224. // Utility methods
  225. //
  226. // copies the children and type from the specified node into this node
  227. void CopyFrom( const CWebAPIValues *pSource );
  228. #ifdef DBGFLAG_VALIDATE
  229. void Validate( CValidator &validator, const char *pchName, bool bTopLevelNode = true, bool bValidatePeers = true );
  230. #endif // DBGFLAG_VALIDATE
  231. private:
  232. // sets the name of the node when constructing or copying
  233. void SetName( const char * pchName );
  234. // Clears any existing value, freeing memory if needed
  235. void ClearValue();
  236. // Assert that we don't have any child nodes, this is used when setting a native type value. We don't
  237. // support having both our own value and children. You are either an array of more values, or you are a value yourself.
  238. void AssertNoChildren();
  239. // Internal helper for creating children
  240. CWebAPIValues *CreateChildInternal( const char *pchName, EWebAPIValueType eValueType, const char *pchArrayElementNames = NULL );
  241. // Name of this node
  242. char *m_pchName;
  243. // Data value contained in this node
  244. EWebAPIValueType m_eValueType;
  245. struct WebAPIBinaryValue_t
  246. {
  247. uint8 *m_pData;
  248. uint32 m_unBytes;
  249. };
  250. union
  251. {
  252. int32 m_nValue;
  253. int64 m_lValue;
  254. uint32 m_unValue;
  255. uint64 m_ulValue;
  256. double m_flValue;
  257. char *m_pchValue;
  258. bool m_bValue;
  259. char *m_pchArrayChildElementName;
  260. WebAPIBinaryValue_t m_BinaryValue;
  261. };
  262. CWebAPIValues * m_pFirstChild;
  263. CWebAPIValues * m_pLastChild;
  264. CWebAPIValues * m_pNextPeer;
  265. CWebAPIValues * m_pParent;
  266. };
  267. #define FOR_EACH_WEBAPI_CHILD( pParentParam, pChildParam ) \
  268. for( CWebAPIValues *pChildParam = pParentParam->GetFirstChild(); pChildParam != NULL; pChildParam = pChildParam->GetNextChild() )
  269. //-----------------------------------------------------------------------------
  270. // Purpose: KeyValues wrapper that automatically deletes itself on close
  271. //-----------------------------------------------------------------------------
  272. class CWebAPIValuesAD
  273. {
  274. public:
  275. CWebAPIValuesAD()
  276. {
  277. m_pwav = NULL;
  278. }
  279. // create a webapivalues object of the object type
  280. CWebAPIValuesAD( const char *pchName )
  281. {
  282. m_pwav = new CWebAPIValues( NULL, pchName, k_EWebAPIValueType_Object );
  283. }
  284. // create a webapivalues object of the array type
  285. CWebAPIValuesAD( const char *pchName, const char *pchArrayElementName )
  286. {
  287. m_pwav = new CWebAPIValues( NULL, pchName, k_EWebAPIValueType_NumericArray, pchArrayElementName );
  288. }
  289. CWebAPIValuesAD( const CWebAPIValuesAD &rhs )
  290. {
  291. m_pwav = NULL;
  292. Copy( rhs.m_pwav );
  293. }
  294. CWebAPIValuesAD( const CWebAPIValues *pwav )
  295. {
  296. m_pwav = NULL;
  297. Copy( pwav );
  298. }
  299. ~CWebAPIValuesAD()
  300. {
  301. delete m_pwav;
  302. }
  303. CWebAPIValues *operator->() { if ( !m_pwav ) m_pwav = new CWebAPIValues( NULL, "root", k_EWebAPIValueType_Object ); return m_pwav; }
  304. operator CWebAPIValues *() { if ( !m_pwav ) m_pwav = new CWebAPIValues( NULL, "root", k_EWebAPIValueType_Object ); return m_pwav; }
  305. operator const CWebAPIValues *() const { return m_pwav; }
  306. CWebAPIValuesAD & operator= ( const CWebAPIValuesAD &rhs )
  307. {
  308. Copy( rhs.m_pwav );
  309. return *this;
  310. }
  311. void Take( CWebAPIValues *pwav )
  312. {
  313. if ( pwav )
  314. {
  315. delete m_pwav;
  316. m_pwav = pwav;
  317. }
  318. else if ( m_pwav )
  319. {
  320. delete m_pwav;
  321. m_pwav = NULL;
  322. }
  323. }
  324. void Copy( const CWebAPIValues *pwav )
  325. {
  326. if ( m_pwav )
  327. delete m_pwav;
  328. if ( pwav )
  329. {
  330. if( pwav->IsArray() )
  331. m_pwav = new CWebAPIValues( NULL, pwav->GetName(), k_EWebAPIValueType_NumericArray, pwav->GetElementName() );
  332. else
  333. m_pwav = new CWebAPIValues( NULL, pwav->GetName(), k_EWebAPIValueType_Object );
  334. m_pwav->CopyFrom( pwav );
  335. }
  336. else
  337. m_pwav = NULL;
  338. }
  339. #ifdef DBGFLAG_VALIDATE
  340. void Validate( CValidator &validator, const char *pchName, bool bTopLevelNode = true, bool bValidatePeers = true )
  341. {
  342. ValidatePtr( m_pwav );
  343. }
  344. #endif // DBGFLAG_VALIDATE
  345. private:
  346. CWebAPIValues *operator=(CWebAPIValues *); // use Take() or Copy()
  347. CWebAPIValues *m_pwav;
  348. };
  349. // use to decode binary values
  350. uint32 Base64Decode( const uint8 *pubData, uint32 cubData, uint8 *pubDest, uint32 cubDest );
  351. bool Base64Encode( uint8 *pubData, uint32 cubData, uint8 *pubDest, uint32 cubDest );
  352. }
  353. #include "tier0/memdbgoff.h"
  354. #endif // WEBAPI_RESPONSE_H