csgo-2018-source/public/gcsdk/webapi_response.h

473 lines
13 KiB
C
Raw Permalink Normal View History

2021-07-24 21:11:47 -07:00
//========= Copyright <20> 1996-2010, Valve LLC, All rights reserved. ============
//
// Purpose: Header for CWebAPIResponse objects
//
//=============================================================================
#ifndef WEBAPI_RESPONSE_H
#define WEBAPI_RESPONSE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/memdbgon.h"
namespace GCSDK
{
enum EWebAPIOutputFormat
{
k_EWebAPIOutputFormat_JSON = 1,
k_EWebAPIOutputFormat_XML = 2,
k_EWebAPIOutputFormat_VDF = 3,
k_EWebAPIOutputFormat_ParameterEncoding = 4,
};
enum EWebAPIValueType
{
// Object is the initial value
k_EWebAPIValueType_Object = 0,
k_EWebAPIValueType_Int32 = 1,
k_EWebAPIValueType_Int64 = 2,
k_EWebAPIValueType_UInt32 = 3,
k_EWebAPIValueType_UInt64 = 4,
k_EWebAPIValueType_Double = 5,
k_EWebAPIValueType_String = 6,
k_EWebAPIValueType_BinaryBlob = 7,
k_EWebAPIValueType_Bool = 8,
k_EWebAPIValueType_Null = 9,
k_EWebAPIValueType_NumericArray = 10,
};
class CWebAPIValues;
class CWebAPIResponse
{
public:
CWebAPIResponse();
~CWebAPIResponse();
// Set the HTTP status code for the response
void SetStatusCode( EHTTPStatusCode eStatusCode ) { m_eStatusCode = eStatusCode; }
// Set how many seconds until this response expires
void SetExpirationSeconds( uint32 unExpirationSeconds ) { m_unExpirationSeconds = unExpirationSeconds; }
// Set when this response was last modified
void SetLastModified( RTime32 rtLastModified ) { m_rtLastModified = rtLastModified; }
// Get the status code for the response
EHTTPStatusCode GetStatusCode() { return m_eStatusCode; }
// Get how many seconds until this response expires
uint32 GetExpirationSeconds() { return m_unExpirationSeconds; }
// Get when the response was last modified
RTime32 GetLastModified() { return m_rtLastModified; }
// extended arrays include their element name as an object in JSON and VDF output formats
void SetExtendedArrays( bool bExtendedArrays ) { m_bExtendedArrays = bExtendedArrays; }
bool HasExtendedArrays() const { return m_bExtendedArrays; }
// Outputs formatted data to buffer
bool BEmitFormattedOutput( EWebAPIOutputFormat eFormat, CUtlBuffer &outputBuffer, size_t unMaxResultSize );
// Resets the response to be empty
void Clear();
// Create the root value element in the response
CWebAPIValues *CreateRootValue( const char *pchName );
CWebAPIValues *GetRootValue() { return m_pValues; }
private:
// Emits JSON formatted representation of response
bool BEmitJSON( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
// Emits KeyValues .vdf style formatted representation of response
bool BEmitVDF( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
// Emits XML formatted representation of response
bool BEmitXML( CUtlBuffer &outputBuffer, size_t unMaxResultSize );
// parameter encoding, as used in a lot of open standards
bool BEmitParameterEncoding( CUtlBuffer &outputBuffer );
CWebAPIValues *m_pValues;
EHTTPStatusCode m_eStatusCode;
uint32 m_unExpirationSeconds;
RTime32 m_rtLastModified;
bool m_bExtendedArrays;
};
class CWebAPIValues
{
public:
CWebAPIValues( CWebAPIValues *pParent, const char *pchName, EWebAPIValueType eValueType, const char *pchArrayElementNames = NULL );
~CWebAPIValues();
//
// Child node handling
//
// Create a child object of this node, all children of the resultant
// object must be named.
CWebAPIValues *CreateChildObject( const char *pchName );
// Add a child object to the array, this should only be called on objects that are of the array type
CWebAPIValues *AddChildObjectToArray();
// Add a child array to the array, this should only be called on objects that are of the array type
CWebAPIValues *AddChildArrayToArray( const char * pchArrayElementNames );
// Create a child array of this node. Note that array nodes can only
// have un-named children, in XML the pchArrayElementNames value will be used
// as the element name for each of the children of the array, in JSON it will simply
// be a numerically indexed [] array.
CWebAPIValues *CreateChildArray( const char *pchName, const char *pchArrayElementNames );
// Find first matching child by name, O(N) on number of children, this class isn't designed for searching
CWebAPIValues * FindChild( const char *pchName );
const CWebAPIValues * FindChild( const char *pchName ) const { return const_cast<CWebAPIValues *>(this)->FindChild( pchName ); }
// Get the first child of this node
CWebAPIValues * GetFirstChild();
const CWebAPIValues * GetFirstChild() const { return m_pFirstChild; }
// Call this on the returned value from GetFirstChild() or a previous GetNextChild() call to
// proceed to the next child of the parent GetFirstChild() was originally called on.
CWebAPIValues * GetNextChild();
const CWebAPIValues * GetNextChild() const { return m_pNextPeer; }
// Returns the parent of this node or NULL if this is the root of a tree
CWebAPIValues * GetParent();
const CWebAPIValues * GetParent() const { return m_pParent; }
// Deletes the child with the given name - no-op if no child by that name
void DeleteChild( const char *pchName );
//
// Setters
//
// Set string value
void SetStringValue( const char *pchValue );
// Set int32 value
void SetInt32Value( int32 nValue );
// Set uint32 value
void SetUInt32Value( uint32 unValue );
// Set int64 value
void SetInt64Value ( int64 lValue );
// Set uint64 value
void SetUInt64Value( uint64 ulValue );
// Set double value
void SetDoubleValue( double flValue );
// Set binary blob value
void SetBinaryValue( uint8 *pValue, uint32 unBytes );
// Set boolean value
void SetBoolValue( bool bValue );
// Set boolean value
void SetNullValue( );
//
// Accessors
//
// Get the name of the current node
const char *GetName() const { return m_pchName; }
// get the name of the elements of this numeric array (if this is an array)
const char *GetElementName() const { return m_pchArrayChildElementName; }
// Get the type currently held by the node
EWebAPIValueType GetType() const;
// returns true if this is an object
bool IsObject() const { return GetType() == k_EWebAPIValueType_Object; }
// returns true if this is an object
bool IsArray() const { return GetType() == k_EWebAPIValueType_NumericArray; }
// Get int32 value
int32 GetInt32Value() const;
// Get uint32 value
uint32 GetUInt32Value() const;
// Get int64 value
int64 GetInt64Value() const;
// Get uint64 value
uint64 GetUInt64Value() const;
// Get double value
double GetDoubleValue() const;
// Get string value
void GetStringValue( CUtlString &stringOut ) const;
// Get binary blob value
void GetBinaryValue( CUtlBuffer &bufferOut ) const;
// Get bool value
bool GetBoolValue() const;
// Get Null value
bool IsNullValue() const { return GetType() == k_EWebAPIValueType_Null; }
//
// Child Setters
//
// Set string value
void SetChildStringValue( const char *pchChildName, const char *pchValue );
// Set int32 value
void SetChildInt32Value( const char *pchChildName, int32 nValue );
// Set uint32 value
void SetChildUInt32Value( const char *pchChildName, uint32 unValue );
// Set int64 value
void SetChildInt64Value ( const char *pchChildName, int64 lValue );
// Set uint64 value
void SetChildUInt64Value( const char *pchChildName, uint64 ulValue );
// Set double value
void SetChildDoubleValue( const char *pchChildName, double flValue );
// Set binary blob value
void SetChildBinaryValue( const char *pchChildName, uint8 *pValue, uint32 unBytes );
// Set boolean value
void SetChildBoolValue( const char *pchChildName, bool bValue );
// Set null value
void SetChildNullValue( const char *pchChildName );
//
// Accessors
//
// Get int32 value
int32 GetChildInt32Value( const char *pchChildName, int32 nDefault = 0 ) const;
// Get uint32 value
uint32 GetChildUInt32Value( const char *pchChildName, uint32 unDefault = 0 ) const;
// Get int64 value
int64 GetChildInt64Value( const char *pchChildName, int64 lDefault = 0 ) const;
// Get uint64 value
uint64 GetChildUInt64Value( const char *pchChildName, uint64 ulDefault = 0 ) const;
// Get double value
double GetChildDoubleValue( const char *pchChildName, double flDefault = 0 ) const;
// Get string value
void GetChildStringValue( CUtlString &stringOut, const char *pchChildName, const char *pchDefault ) const;
// Get binary blob value (returns false if the child wasn't found)
bool BGetChildBinaryValue( CUtlBuffer &bufferOut, const char *pchChildName ) const;
// Get bool value
bool GetChildBoolValue( const char *pchChildName, bool bDefault = false ) const;
// get null value
bool IsChildNullValue( const char *pchChildName ) const;
//
// Output methods
//
// Emits JSON formatted representation of response
static bool BEmitJSONRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer, int nTabLevel, size_t unMaxResultSize, bool bIncludeArrayElementName = true );
// Emits KeyValues .vdf style formatted representation of response
static bool BEmitVDFRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer, int nTabLevel, uint32 nArrayElement, size_t unMaxResultSize, bool bIncludeArrayElementName = true );
// Emits XML formatted representation of response
static bool BEmitXMLRecursive( CWebAPIValues *pCurrent, CUtlBuffer &outputBuffer,int nTabLevel, size_t unMaxResultSize );
//
// Parsing methods
//
// parses JSON into a tree of CWebAPIValues nodes.
static CWebAPIValues * ParseJSON( CUtlBuffer &inputBuffer );
static CWebAPIValues * ParseJSON( const char *pchJSONString );
//
// Utility methods
//
// copies the children and type from the specified node into this node
void CopyFrom( const CWebAPIValues *pSource );
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, const char *pchName, bool bTopLevelNode = true, bool bValidatePeers = true );
#endif // DBGFLAG_VALIDATE
private:
// sets the name of the node when constructing or copying
void SetName( const char * pchName );
// Clears any existing value, freeing memory if needed
void ClearValue();
// Assert that we don't have any child nodes, this is used when setting a native type value. We don't
// support having both our own value and children. You are either an array of more values, or you are a value yourself.
void AssertNoChildren();
// Internal helper for creating children
CWebAPIValues *CreateChildInternal( const char *pchName, EWebAPIValueType eValueType, const char *pchArrayElementNames = NULL );
// Name of this node
char *m_pchName;
// Data value contained in this node
EWebAPIValueType m_eValueType;
struct WebAPIBinaryValue_t
{
uint8 *m_pData;
uint32 m_unBytes;
};
union
{
int32 m_nValue;
int64 m_lValue;
uint32 m_unValue;
uint64 m_ulValue;
double m_flValue;
char *m_pchValue;
bool m_bValue;
char *m_pchArrayChildElementName;
WebAPIBinaryValue_t m_BinaryValue;
};
CWebAPIValues * m_pFirstChild;
CWebAPIValues * m_pLastChild;
CWebAPIValues * m_pNextPeer;
CWebAPIValues * m_pParent;
};
#define FOR_EACH_WEBAPI_CHILD( pParentParam, pChildParam ) \
for( CWebAPIValues *pChildParam = pParentParam->GetFirstChild(); pChildParam != NULL; pChildParam = pChildParam->GetNextChild() )
//-----------------------------------------------------------------------------
// Purpose: KeyValues wrapper that automatically deletes itself on close
//-----------------------------------------------------------------------------
class CWebAPIValuesAD
{
public:
CWebAPIValuesAD()
{
m_pwav = NULL;
}
// create a webapivalues object of the object type
CWebAPIValuesAD( const char *pchName )
{
m_pwav = new CWebAPIValues( NULL, pchName, k_EWebAPIValueType_Object );
}
// create a webapivalues object of the array type
CWebAPIValuesAD( const char *pchName, const char *pchArrayElementName )
{
m_pwav = new CWebAPIValues( NULL, pchName, k_EWebAPIValueType_NumericArray, pchArrayElementName );
}
CWebAPIValuesAD( const CWebAPIValuesAD &rhs )
{
m_pwav = NULL;
Copy( rhs.m_pwav );
}
CWebAPIValuesAD( const CWebAPIValues *pwav )
{
m_pwav = NULL;
Copy( pwav );
}
~CWebAPIValuesAD()
{
delete m_pwav;
}
CWebAPIValues *operator->() { if ( !m_pwav ) m_pwav = new CWebAPIValues( NULL, "root", k_EWebAPIValueType_Object ); return m_pwav; }
operator CWebAPIValues *() { if ( !m_pwav ) m_pwav = new CWebAPIValues( NULL, "root", k_EWebAPIValueType_Object ); return m_pwav; }
operator const CWebAPIValues *() const { return m_pwav; }
CWebAPIValuesAD & operator= ( const CWebAPIValuesAD &rhs )
{
Copy( rhs.m_pwav );
return *this;
}
void Take( CWebAPIValues *pwav )
{
if ( pwav )
{
delete m_pwav;
m_pwav = pwav;
}
else if ( m_pwav )
{
delete m_pwav;
m_pwav = NULL;
}
}
void Copy( const CWebAPIValues *pwav )
{
if ( m_pwav )
delete m_pwav;
if ( pwav )
{
if( pwav->IsArray() )
m_pwav = new CWebAPIValues( NULL, pwav->GetName(), k_EWebAPIValueType_NumericArray, pwav->GetElementName() );
else
m_pwav = new CWebAPIValues( NULL, pwav->GetName(), k_EWebAPIValueType_Object );
m_pwav->CopyFrom( pwav );
}
else
m_pwav = NULL;
}
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, const char *pchName, bool bTopLevelNode = true, bool bValidatePeers = true )
{
ValidatePtr( m_pwav );
}
#endif // DBGFLAG_VALIDATE
private:
CWebAPIValues *operator=(CWebAPIValues *); // use Take() or Copy()
CWebAPIValues *m_pwav;
};
// use to decode binary values
uint32 Base64Decode( const uint8 *pubData, uint32 cubData, uint8 *pubDest, uint32 cubDest );
bool Base64Encode( uint8 *pubData, uint32 cubData, uint8 *pubDest, uint32 cubDest );
}
#include "tier0/memdbgoff.h"
#endif // WEBAPI_RESPONSE_H