Added support for getting/setting protobuf enum values with Pb*Int natives (nobug, r=asherkin).
authorNicholas Hastings <skamonkey@gmail.com>
Tue Apr 16 11:33:36 2013 -0400 (2013-04-16)
changeset 3896cb7537c1da4d
parent 3895 dc3a6be3a306
child 3897 cf4356fd3524
Added support for getting/setting protobuf enum values with Pb*Int natives (nobug, r=asherkin).
core/UserMessagePBHelpers.h
core/smn_protobuf.cpp
plugins/include/protobuf.inc
     1.1 --- a/core/UserMessagePBHelpers.h	Mon Apr 15 07:22:23 2013 -0400
     1.2 +++ b/core/UserMessagePBHelpers.h	Tue Apr 16 11:33:36 2013 -0400
     1.3 @@ -56,6 +56,15 @@
     1.4  		return false; \
     1.5  	}
     1.6  
     1.7 +#define CHECK_FIELD_TYPE3(type1, type2, type3) \
     1.8 +	protobuf::FieldDescriptor::CppType fieldType = field->cpp_type(); \
     1.9 +	if (fieldType != protobuf::FieldDescriptor::CPPTYPE_##type1       \
    1.10 +		&& fieldType != protobuf::FieldDescriptor::CPPTYPE_##type2 \
    1.11 +		&& fieldType != protobuf::FieldDescriptor::CPPTYPE_##type3) \
    1.12 +	{                 \
    1.13 +		return false; \
    1.14 +	}
    1.15 +
    1.16  #define CHECK_FIELD_REPEATED() \
    1.17  	if (field->label() != protobuf::FieldDescriptor::LABEL_REPEATED) \
    1.18  	{                 \
    1.19 @@ -316,74 +325,114 @@
    1.20  		return true;
    1.21  	}
    1.22  
    1.23 -	inline bool GetInt32OrUnsigned(const char *pszFieldName, int32 *out)
    1.24 +	inline bool GetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 *out)
    1.25  	{
    1.26  		GETCHECK_FIELD();
    1.27 -		CHECK_FIELD_TYPE2(INT32, UINT32);
    1.28 +		CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
    1.29  		CHECK_FIELD_NOT_REPEATED();
    1.30  
    1.31  		if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
    1.32  			*out = (int32)msg->GetReflection()->GetUInt32(*msg, field);
    1.33 -		else
    1.34 +		else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
    1.35  			*out = msg->GetReflection()->GetInt32(*msg, field);
    1.36 +		else // CPPTYPE_ENUM
    1.37 +			*out = msg->GetReflection()->GetEnum(*msg, field)->number();
    1.38  
    1.39  		return true;	
    1.40  	}
    1.41  
    1.42 -	inline bool SetInt32OrUnsigned(const char *pszFieldName, int32 value)
    1.43 +	inline bool SetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
    1.44  	{
    1.45  		GETCHECK_FIELD();
    1.46 -		CHECK_FIELD_TYPE2(INT32, UINT32);
    1.47 +		CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
    1.48  		CHECK_FIELD_NOT_REPEATED();
    1.49  
    1.50  		if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
    1.51 +		{
    1.52  			msg->GetReflection()->SetUInt32(msg, field, (uint32)value);
    1.53 -		else
    1.54 +		}
    1.55 +		else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
    1.56 +		{
    1.57  			msg->GetReflection()->SetInt32(msg, field, value);
    1.58 +		}
    1.59 +		else // CPPTYPE_ENUM
    1.60 +		{
    1.61 +			const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
    1.62 +			if (!pEnumValue)
    1.63 +				return false;
    1.64 +
    1.65 +			msg->GetReflection()->SetEnum(msg, field, pEnumValue);
    1.66 +		}
    1.67  
    1.68  		return true;
    1.69  	}
    1.70  
    1.71 -	inline bool GetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 *out)
    1.72 +	inline bool GetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 *out)
    1.73  	{
    1.74  		GETCHECK_FIELD();
    1.75 -		CHECK_FIELD_TYPE2(INT32, UINT32);
    1.76 +		CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
    1.77  		CHECK_FIELD_REPEATED();
    1.78  		CHECK_REPEATED_ELEMENT(index);
    1.79  		
    1.80  		if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
    1.81  			*out = (int32)msg->GetReflection()->GetRepeatedUInt32(*msg, field, index);
    1.82 -		else
    1.83 +		else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
    1.84  			*out = msg->GetReflection()->GetRepeatedInt32(*msg, field, index);
    1.85 +		else // CPPTYPE_ENUM
    1.86 +			*out = msg->GetReflection()->GetRepeatedEnum(*msg, field, index)->number();
    1.87  
    1.88  		return true;
    1.89  	}
    1.90  
    1.91 -	inline bool SetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 value)
    1.92 +	inline bool SetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 value)
    1.93  	{
    1.94  		GETCHECK_FIELD();
    1.95 -		CHECK_FIELD_TYPE2(INT32, UINT32);
    1.96 +		CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
    1.97  		CHECK_FIELD_REPEATED();
    1.98  		CHECK_REPEATED_ELEMENT(index);
    1.99  		
   1.100  		if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
   1.101 +		{
   1.102  			msg->GetReflection()->SetRepeatedUInt32(msg, field, index, (uint32)value);
   1.103 -		else
   1.104 +		}
   1.105 +		else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
   1.106 +		{
   1.107  			msg->GetReflection()->SetRepeatedInt32(msg, field, index, value);
   1.108 +		}
   1.109 +		else // CPPTYPE_ENUM
   1.110 +		{
   1.111 +			const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
   1.112 +			if (!pEnumValue)
   1.113 +				return false;
   1.114 +
   1.115 +			msg->GetReflection()->SetRepeatedEnum(msg, field, index, pEnumValue);
   1.116 +		}
   1.117  
   1.118  		return true;
   1.119  	}
   1.120  
   1.121 -	inline bool AddInt32OrUnsigned(const char *pszFieldName, int32 value)
   1.122 +	inline bool AddInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
   1.123  	{
   1.124  		GETCHECK_FIELD();
   1.125 -		CHECK_FIELD_TYPE2(INT32, UINT32);
   1.126 +		CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
   1.127  		CHECK_FIELD_REPEATED();
   1.128  
   1.129  		if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
   1.130 +		{
   1.131  			msg->GetReflection()->AddUInt32(msg, field, (uint32)value);
   1.132 -		else
   1.133 +		}
   1.134 +		else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
   1.135 +		{
   1.136  			msg->GetReflection()->AddInt32(msg, field, value);
   1.137 +		}
   1.138 +		else // CPPTYPE_ENUM
   1.139 +		{
   1.140 +			const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
   1.141 +			if (!pEnumValue)
   1.142 +				return false;
   1.143 +
   1.144 +			msg->GetReflection()->AddEnum(msg, field, pEnumValue);
   1.145 +		}
   1.146  
   1.147  		return true;
   1.148  	}
     2.1 --- a/core/smn_protobuf.cpp	Mon Apr 15 07:22:23 2013 -0400
     2.2 +++ b/core/smn_protobuf.cpp	Tue Apr 16 11:33:36 2013 -0400
     2.3 @@ -70,14 +70,14 @@
     2.4  	int index = params[0] >= 3 ? params[3] : -1;
     2.5  	if (index < 0)
     2.6  	{
     2.7 -		if (!msg->GetInt32OrUnsigned(strField, &ret))
     2.8 +		if (!msg->GetInt32OrUnsignedOrEnum(strField, &ret))
     2.9  		{
    2.10  			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
    2.11  		}
    2.12  	}
    2.13  	else
    2.14  	{
    2.15 -		if (!msg->GetRepeatedInt32OrUnsigned(strField, index, &ret))
    2.16 +		if (!msg->GetRepeatedInt32OrUnsignedOrEnum(strField, index, &ret))
    2.17  		{
    2.18  			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
    2.19  		}
    2.20 @@ -314,7 +314,7 @@
    2.21  	GET_FIELD_NAME_OR_ERR();
    2.22  
    2.23  	int ret;
    2.24 -	if (!msg->GetRepeatedInt32OrUnsigned(strField, params[3], &ret))
    2.25 +	if (!msg->GetRepeatedInt32OrUnsignedOrEnum(strField, params[3], &ret))
    2.26  	{
    2.27  		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
    2.28  	}
    2.29 @@ -458,14 +458,14 @@
    2.30  	int index = params[0] >= 4 ? params[4] : -1;
    2.31  	if (index < 0)
    2.32  	{
    2.33 -		if (!msg->SetInt32OrUnsigned(strField, params[3]))
    2.34 +		if (!msg->SetInt32OrUnsignedOrEnum(strField, params[3]))
    2.35  		{
    2.36  			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
    2.37  		}
    2.38  	}
    2.39  	else
    2.40  	{
    2.41 -		if (!msg->SetRepeatedInt32OrUnsigned(strField, index, params[3]))
    2.42 +		if (!msg->SetRepeatedInt32OrUnsignedOrEnum(strField, index, params[3]))
    2.43  		{
    2.44  			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
    2.45  		}
    2.46 @@ -703,7 +703,7 @@
    2.47  	GET_MSG_FROM_HANDLE_OR_ERR();
    2.48  	GET_FIELD_NAME_OR_ERR();
    2.49  
    2.50 -	if (!msg->AddInt32OrUnsigned(strField, params[3]))
    2.51 +	if (!msg->AddInt32OrUnsignedOrEnum(strField, params[3]))
    2.52  	{
    2.53  		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
    2.54  	}
     3.1 --- a/plugins/include/protobuf.inc	Mon Apr 15 07:22:23 2013 -0400
     3.2 +++ b/plugins/include/protobuf.inc	Tue Apr 16 11:33:36 2013 -0400
     3.3 @@ -38,7 +38,7 @@
     3.4  #define PB_FIELD_NOT_REPEATED -1
     3.5  
     3.6  /**
     3.7 - * Reads an int32, uint32, sint32, fixed32, or sfixed32 from a protobuf message.
     3.8 + * Reads an int32, uint32, sint32, fixed32, sfixed32, or enum value from a protobuf message.
     3.9   *
    3.10   * @param pb			protobuf handle.
    3.11   * @param field			Field name.
    3.12 @@ -244,7 +244,7 @@
    3.13  native PbReadRepeatedVector2D(Handle:pb, const String:field[], index, Float:buffer[2]);
    3.14  
    3.15  /**
    3.16 - * Sets an int32, uint32, sint32, fixed32, or sfixed32  on a protobuf message.
    3.17 + * Sets an int32, uint32, sint32, fixed32, sfixed32, or enum value on a protobuf message.
    3.18   *
    3.19   * @param pb			protobuf handle.
    3.20   * @param field			Field name.
    3.21 @@ -340,7 +340,7 @@
    3.22  native PbSetVector2D(Handle:pb, const String:field[], const Float:vec[2], index=PB_FIELD_NOT_REPEATED);
    3.23  
    3.24  /**
    3.25 - * Add an int32, uint32, sint32, fixed32, or sfixed32 to a protobuf message repeated field.
    3.26 + * Add an int32, uint32, sint32, fixed32, sfixed32, or enum value to a protobuf message repeated field.
    3.27   *
    3.28   * @param pb			protobuf handle.
    3.29   * @param field			Field name.