diff --git a/libs/common/include/launchdarkly/bindings/c/array_builder.h b/libs/common/include/launchdarkly/bindings/c/array_builder.h index 227d7da04..ba1c84781 100644 --- a/libs/common/include/launchdarkly/bindings/c/array_builder.h +++ b/libs/common/include/launchdarkly/bindings/c/array_builder.h @@ -34,8 +34,9 @@ LD_EXPORT(void) LDArrayBuilder_Free(LDArrayBuilder array_builder); * After calling this method the provider LDValue is consumed. It should not * be accessed, and the caller doesn't need to call LDValue_Free. * - * @param array_builder The array builder to add the value to. - * @param val The value to add. + * @param array_builder The array builder to add the value to. Must not be + * NULL. + * @param val The value to add. Must not be NULL. */ LD_EXPORT(void) LDArrayBuilder_Add(LDArrayBuilder array_builder, LDValue val); @@ -45,8 +46,9 @@ LD_EXPORT(void) LDArrayBuilder_Add(LDArrayBuilder array_builder, LDValue val); * After calling this method the array builder is consumed. It should not be * used and the caller does not need to call LDArrayBuilder_Free. * - * @param array_builder The array builder to build an LDValue from. - * @return The built LDValue. + * @param array_builder The array builder to build an LDValue from. Must not be + * NULL. + * @return The built LDValue. Must not be NULL. */ LD_EXPORT(LDValue) LDArrayBuilder_Build(LDArrayBuilder array_builder); diff --git a/libs/common/include/launchdarkly/bindings/c/context.h b/libs/common/include/launchdarkly/bindings/c/context.h index 437ce8753..d39dcade0 100644 --- a/libs/common/include/launchdarkly/bindings/c/context.h +++ b/libs/common/include/launchdarkly/bindings/c/context.h @@ -19,7 +19,7 @@ typedef struct _LDContext_PrivateAttributesIter* /** * Check if the context is valid. * - * @param context The context to check. + * @param context The context to check. Must not be NULL. * @return True if the context is valid. */ LD_EXPORT(bool) LDContext_Valid(LDContext context); @@ -40,10 +40,12 @@ LD_EXPORT(void) LDContext_Free(LDContext context); * Do not access a returned LDValue from a context after the context has been * freed. * - * @param context The context to get an attribute from - * @param kind The kind within the context to get the attribute from. - * @param ref An attribute reference representing the attribute to get. - * @return The attribute value or a null pointer. + * @param context The context to get an attribute from. Must not be NULL. + * @param kind The kind within the context to get the attribute from. Must not + * be NULL. + * @param ref An attribute reference representing the attribute to get. Must not + * be NULL. + * @return The attribute value or a NULL pointer. */ LD_EXPORT(LDValue) LDContext_Get(LDContext context, char const* kind, char const* ref); @@ -54,7 +56,7 @@ LDContext_Get(LDContext context, char const* kind, char const* ref); * * The lifetime of the returned string is tied to the LDContext. * - * @param context The context to check for validity. + * @param context The context to check for validity. Must not be NULL. * @return A string explaining why the context is not valid. */ LD_EXPORT(char const*) LDContext_Errors(LDContext context); @@ -64,17 +66,17 @@ LD_EXPORT(char const*) LDContext_Errors(LDContext context); * context kind. If there is no such context kind, then a null pointer will * be returned. * - * The iterator must be destroyed with LDContext_DestroyPrivateAttributesIter. + * The iterator must be destroyed with LDContext_PrivateAttributesIter_Free. * * An iterator must not be used after the associated Context has been * freed. * - * @param context The context containing the kind. - * @param kind The kind to iterate private attributes for. + * @param context The context containing the kind. Must not be NULL. + * @param kind The kind to iterate private attributes for. Must not be NULL. * @return A private attributes iterator. */ LD_EXPORT(LDContext_PrivateAttributesIter) -LDContext_CreatePrivateAttributesIter(LDContext context, char const* kind); +LDContext_PrivateAttributesIter_New(LDContext context, char const* kind); /** * Destroy the iterator. @@ -82,12 +84,12 @@ LDContext_CreatePrivateAttributesIter(LDContext context, char const* kind); * @param iter The iterator to destroy. */ LD_EXPORT(void) -LDContext_DestroyPrivateAttributesIter(LDContext_PrivateAttributesIter iter); +LDContext_PrivateAttributesIter_Free(LDContext_PrivateAttributesIter iter); /** * Move the iterator to the next item. * - * @param iter The iterator to increment. + * @param iter The iterator to increment. Must not be NULL. */ LD_EXPORT(void) LDContext_PrivateAttributesIter_Next(LDContext_PrivateAttributesIter iter); @@ -95,7 +97,7 @@ LDContext_PrivateAttributesIter_Next(LDContext_PrivateAttributesIter iter); /** * Check if the iterator is at the end. * - * @param iter The iterator to check. + * @param iter The iterator to check. Must not be NULL. * @return True if the iterator is at the end. */ LD_EXPORT(bool) @@ -106,7 +108,7 @@ LDContext_PrivateAttributesIter_End(LDContext_PrivateAttributesIter iter); * * The lifetime of the returned value is the same as the Context. * - * @param iter The iterator to get a value for. + * @param iter The iterator to get a value for. Must not be NULL. * @return The attribute reference as a string. */ LD_EXPORT(char const*) diff --git a/libs/common/include/launchdarkly/bindings/c/context_builder.h b/libs/common/include/launchdarkly/bindings/c/context_builder.h index 80d86fe94..5edf0bccf 100644 --- a/libs/common/include/launchdarkly/bindings/c/context_builder.h +++ b/libs/common/include/launchdarkly/bindings/c/context_builder.h @@ -41,7 +41,7 @@ LD_EXPORT(void) LDContextBuilder_Free(LDContextBuilder builder); * When building a context using LDContextBuilder_Build the builder will be * consumed and you do not need to call LDContextBuilder_Free. * - * @param builder The builder to build a context from. + * @param builder The builder to build a context from. Must not be NULL. * @return The built context. */ LD_EXPORT(LDContext) LDContextBuilder_Build(LDContextBuilder builder); @@ -58,9 +58,9 @@ LD_EXPORT(LDContext) LDContextBuilder_Build(LDContextBuilder builder); * If you call LDContextBuilder_AddKind a second time, with an already specified * kind, but a different key, then the key for that kind will be updated. * - * @param builder The builder to add the kind to. - * @param kind The kind to add. - * @param key The key for that kind. + * @param builder The builder to add the kind to. Must not be NULL. + * @param kind The kind to add. Must not be NULL. + * @param key The key for that kind. Must not be NULL. */ LD_EXPORT(void) LDContextBuilder_AddKind(LDContextBuilder builder, @@ -74,9 +74,9 @@ LDContextBuilder_AddKind(LDContextBuilder builder, * You should not access the value after adding it to the builder, and you * do not need to call LDValue_Free on the value. * - * @param kind The kind to add the attribute to. - * @param attr_key The key of the attribute to add. - * @param val The value of the attribute to add. + * @param kind The kind to add the attribute to. Must not be NULL. + * @param attr_key The key of the attribute to add. Must not be NULL. + * @param val The value of the attribute to add. Must not be NULL. */ LD_EXPORT(bool) LDContextBuilder_Attributes_Set(LDContextBuilder builder, @@ -99,9 +99,9 @@ LDContextBuilder_Attributes_Set(LDContextBuilder builder, * convenience which also adds the attribute to the private attributes list, * as if using LDContextBuilder_Attributes_AddPrivateAttribute. * - * @param kind The kind to set the private attribute for. - * @param attr_key The key of the private attribute. - * @param val The value of the private attribute. + * @param kind The kind to set the private attribute for. Must not be NULL. + * @param attr_key The key of the private attribute. Must not be NULL. + * @param val The value of the private attribute. Must not be NULL. */ LD_EXPORT(bool) LDContextBuilder_Attributes_SetPrivate(LDContextBuilder builder, @@ -117,8 +117,8 @@ LDContextBuilder_Attributes_SetPrivate(LDContextBuilder builder, * This method will make a copy of the name string, and the caller remains * responsible for the original name string. * - * @param kind The kind to set the name for. - * @param name The name to set. + * @param kind The kind to set the name for. Must not be NULL. + * @param name The name to set. Must not be NULL. */ LD_EXPORT(bool) LDContextBuilder_Attributes_SetName(LDContextBuilder builder, @@ -131,7 +131,7 @@ LDContextBuilder_Attributes_SetName(LDContextBuilder builder, * If true, the context will _not_ appear on the Contexts page in the * LaunchDarkly dashboard. * - * @param kind The kind to set the anonymous attribute for. + * @param kind The kind to set the anonymous attribute for. Must not be NULL. * @param anonymous The value to set the anonymous attribute to. */ LD_EXPORT(bool) @@ -182,8 +182,8 @@ LDContextBuilder_Attributes_SetAnonymous(LDContextBuilder builder, * This method will make a copy of the attr_ref string, and the caller remains * responsible for the original name string. * - * @param kind The kind to set the attribute as private for. - * @param attr_ref An attribute reference. + * @param kind The kind to set the attribute as private for. Must not be NULL. + * @param attr_ref An attribute reference. Must not be NULL. */ LD_EXPORT(bool) LDContextBuilder_Attributes_AddPrivateAttribute(LDContextBuilder builder, diff --git a/libs/common/include/launchdarkly/bindings/c/object_builder.h b/libs/common/include/launchdarkly/bindings/c/object_builder.h index 8addcbe0c..3db644c1e 100644 --- a/libs/common/include/launchdarkly/bindings/c/object_builder.h +++ b/libs/common/include/launchdarkly/bindings/c/object_builder.h @@ -2,8 +2,8 @@ #pragma once -#include #include +#include #ifdef __cplusplus extern "C" { // only need to export C interface if @@ -36,8 +36,8 @@ LD_EXPORT(void) LDObjectBuilder_Free(LDObjectBuilder builder); * be copied. * * @param array_builder The object builder to add the value to. - * @param key The key for the value being added. - * @param val The value to add. + * @param key The key for the value being added. Must not be NULL. + * @param val The value to add. Must not be NULL. */ LD_EXPORT(void) LDObjectBuilder_Add(LDObjectBuilder builder, char const* key, LDValue val); @@ -48,7 +48,7 @@ LDObjectBuilder_Add(LDObjectBuilder builder, char const* key, LDValue val); * After calling this method the object builder is consumed. It should not be * used and the caller does not need to call LDObjectBuilder_Free. * - * @param builder The object builder to build an LDValue from. + * @param builder The object builder to build an LDValue from. Must not be NULL. * @return The built LDValue. */ LD_EXPORT(LDValue) LDObjectBuilder_Build(LDObjectBuilder builder); diff --git a/libs/common/include/launchdarkly/bindings/c/value.h b/libs/common/include/launchdarkly/bindings/c/value.h index 7e94627a6..dc5d58a75 100644 --- a/libs/common/include/launchdarkly/bindings/c/value.h +++ b/libs/common/include/launchdarkly/bindings/c/value.h @@ -109,7 +109,7 @@ LD_EXPORT(LDValue) LDValue_NewNumber(double val); * The input string will be copied. To avoid the copy, see * LDValue_ConstantString. * - * @param val Constant reference to a string. The string is copied. Cannot be + * @param val Constant reference to a string. The string is copied. Must not be * NULL. * @return New LDValue. */ @@ -118,7 +118,7 @@ LD_EXPORT(LDValue) LDValue_NewString(char const* val); /** * Allocates an LDValue by cloning an existing LDValue. * - * @param source Source LDValue. Must not be `NULL`. + * @param source Source LDValue. Must not be NULL. * @return New LDValue. */ LD_EXPORT(LDValue) LDValue_NewValue(LDValue val); @@ -129,13 +129,13 @@ LD_EXPORT(LDValue) LDValue_NewValue(LDValue val); * An LDValue should only be freed when directly owned by the caller, i.e., * it was never moved into an LDArray or LDObject. * - * @param value LDValue to free. No-op if NULL. + * @param value LDValue to free. */ LD_EXPORT(void) LDValue_Free(LDValue val); /** * Returns the type of an LDValue. - * @param value LDValue to inspect. Cannot be NULL. + * @param value LDValue to inspect. Must not be NULL. * @return Type of the LDValue, or LDValueType_Unrecognized if the type is * unrecognized. */ @@ -144,14 +144,14 @@ LD_EXPORT(enum LDValueType) LDValue_Type(LDValue val); /** * Obtain value of a boolean-type LDValue, otherwise returns LDBooleanFalse. * - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return Boolean value, or false if not boolean-type. */ LD_EXPORT(bool) LDValue_GetBool(LDValue val); /** * Obtain value of a number-type LDValue, otherwise return 0. - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return Number value, or 0 if not number-type. */ LD_EXPORT(double) LDValue_GetNumber(LDValue val); @@ -162,7 +162,7 @@ LD_EXPORT(double) LDValue_GetNumber(LDValue val); * the LDValue. If you need the string outside this lifetime, then a copy * should be made. * - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return String value, or empty string if not string-type. */ LD_EXPORT(char const*) LDValue_GetString(LDValue val); @@ -173,7 +173,7 @@ LD_EXPORT(char const*) LDValue_GetString(LDValue val); * * If not an array-type or object-type, returns 0. * - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return Count of LDValue elements, or 0 if not array-type/object-type. */ LD_EXPORT(unsigned int) LDValue_Count(LDValue val); @@ -183,7 +183,7 @@ LD_EXPORT(unsigned int) LDValue_Count(LDValue val); * * The iterator starts at the first element. * - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return Iterator, or NULL if not an array-type. The iterator * must should be destroyed with LDValue_DestroyArrayIter. */ @@ -193,14 +193,14 @@ LD_EXPORT(LDValue_ArrayIter) LDValue_CreateArrayIter(LDValue val); * Move the array-type iterator to the next item. Should only be done for an * iterator which is not at the end. * - * @param iter The iterator to advance. + * @param iter The iterator to advance. Must not be NULL. */ LD_EXPORT(void) LDValue_ArrayIter_Next(LDValue_ArrayIter iter); /** * Check if an array-type iterator is at the end. * - * @param iter The iterator to check. + * @param iter The iterator to check. Must not be NULL. * @return True if the iterator is at the end. */ LD_EXPORT(bool) LDValue_ArrayIter_End(LDValue_ArrayIter iter); @@ -208,7 +208,7 @@ LD_EXPORT(bool) LDValue_ArrayIter_End(LDValue_ArrayIter iter); /** * Get the value for the array-type iterator. * - * @param iter The iterator to get a value for. + * @param iter The iterator to get a value for. Must not be NULL. * @return The value. */ LD_EXPORT(LDValue) LdValue_ArrayIter_Value(LDValue_ArrayIter iter); @@ -224,7 +224,7 @@ LD_EXPORT(void) LDValue_DestroyArrayIter(LDValue_ArrayIter iter); * * The iterator starts at the first element. * - * @param value Target LDValue. Cannot be NULL. + * @param value Target LDValue. Must not be NULL. * @return Iterator, or NULL if not an object-type. The iterator * must should be destroyed with LDValue_DestroyObjectIter. */ @@ -234,14 +234,14 @@ LD_EXPORT(LDValue_ObjectIter) LDValue_CreateObjectIter(LDValue val); * Move the object-type iterator to the next item. Should only be done for an * iterator which is not at the end. * - * @param iter The iterator to advance. + * @param iter The iterator to advance. Must not be NULL. */ LD_EXPORT(void) LDValue_ObjectIter_Next(LDValue_ObjectIter iter); /** * Check if an object-type iterator is at the end. * - * @param iter The iterator to check. + * @param iter The iterator to check. Must not be NULL. * @return True if the iterator is at the end. */ LD_EXPORT(bool) LDValue_ObjectIter_End(LDValue_ObjectIter iter); @@ -249,7 +249,7 @@ LD_EXPORT(bool) LDValue_ObjectIter_End(LDValue_ObjectIter iter); /** * Get the value for an object-type iterator. * - * @param iter The iterator to get a value for. + * @param iter The iterator to get a value for. Must not be NULL. * @return The value. */ LD_EXPORT(LDValue) LdValue_ObjectIter_Value(LDValue_ObjectIter iter); @@ -259,7 +259,7 @@ LD_EXPORT(LDValue) LdValue_ObjectIter_Value(LDValue_ObjectIter iter); * * The returned key has a lifetime attached to that of the LDValue. * - * @param iter The iterator to get a key for. + * @param iter The iterator to get a key for. Must not be NULL. * @return The key. */ LD_EXPORT(char const*) LdValue_ObjectIter_Key(LDValue_ObjectIter iter); diff --git a/libs/common/src/bindings/c/array_builder.cpp b/libs/common/src/bindings/c/array_builder.cpp index 29eb9a105..248072757 100644 --- a/libs/common/src/bindings/c/array_builder.cpp +++ b/libs/common/src/bindings/c/array_builder.cpp @@ -3,6 +3,7 @@ #include #include +#include "../../c_binding_helpers.hpp" #include @@ -21,12 +22,17 @@ LD_EXPORT(void) LDArrayBuilder_Free(LDArrayBuilder array_builder) { } LD_EXPORT(void) LDArrayBuilder_Add(LDArrayBuilder array_builder, LDValue val) { + LD_ASSERT_NOT_NULL(array_builder); + LD_ASSERT_NOT_NULL(val); + auto vector = AS_VECTOR(array_builder); vector->emplace_back(std::move(*AS_VALUE(val))); LDValue_Free(val); } LD_EXPORT(LDValue) LDArrayBuilder_Build(LDArrayBuilder array_builder) { + LD_ASSERT_NOT_NULL(array_builder); + auto vector = AS_VECTOR(array_builder); auto value = new Value(std::move(*vector)); delete vector; diff --git a/libs/common/src/bindings/c/config/builder.cpp b/libs/common/src/bindings/c/config/builder.cpp index 4c2368107..82d0c0d33 100644 --- a/libs/common/src/bindings/c/config/builder.cpp +++ b/libs/common/src/bindings/c/config/builder.cpp @@ -57,6 +57,7 @@ class LogBackendWrapper : public launchdarkly::ILogBackend { LD_EXPORT(LDClientConfigBuilder) LDClientConfigBuilder_New(char const* sdk_key) { LD_ASSERT_NOT_NULL(sdk_key); + return FROM_BUILDER(new ConfigBuilder(sdk_key)); } @@ -65,6 +66,7 @@ LDClientConfigBuilder_Build(LDClientConfigBuilder b, LDClientConfig* out_config) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(out_config); + return ConsumeBuilder(b, out_config); } @@ -78,6 +80,7 @@ LDClientConfigBuilder_ServiceEndpoints_PollingBaseURL(LDClientConfigBuilder b, char const* url) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(url); + TO_BUILDER(b)->ServiceEndpoints().PollingBaseUrl(url); } @@ -86,6 +89,7 @@ LDClientConfigBuilder_ServiceEndpoints_StreamingBaseURL(LDClientConfigBuilder b, char const* url) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(url); + TO_BUILDER(b)->ServiceEndpoints().StreamingBaseUrl(url); } @@ -94,6 +98,7 @@ LDClientConfigBuilder_ServiceEndpoints_EventsBaseURL(LDClientConfigBuilder b, char const* url) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(url); + TO_BUILDER(b)->ServiceEndpoints().EventsBaseUrl(url); } @@ -103,6 +108,7 @@ LDClientConfigBuilder_ServiceEndpoints_RelayProxyBaseURL( char const* url) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(url); + TO_BUILDER(b)->ServiceEndpoints().RelayProxy(url); } @@ -111,6 +117,7 @@ LDClientConfigBuilder_AppInfo_Identifier(LDClientConfigBuilder b, char const* app_id) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(app_id); + TO_BUILDER(b)->AppInfo().Identifier(app_id); } @@ -119,18 +126,21 @@ LDClientConfigBuilder_AppInfo_Version(LDClientConfigBuilder b, char const* app_version) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(app_version); + TO_BUILDER(b)->AppInfo().Version(app_version); } LD_EXPORT(void) LDClientConfigBuilder_Offline(LDClientConfigBuilder b, bool offline) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Offline(offline); } LD_EXPORT(void) LDClientConfigBuilder_Events_Enabled(LDClientConfigBuilder b, bool enabled) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Events().Enabled(enabled); } @@ -138,6 +148,7 @@ LD_EXPORT(void) LDClientConfigBuilder_Events_Capacity(LDClientConfigBuilder b, size_t capacity) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Events().Capacity(capacity); } @@ -145,6 +156,7 @@ LD_EXPORT(void) LDClientConfigBuilder_Events_FlushIntervalMs(LDClientConfigBuilder b, unsigned int milliseconds) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Events().FlushInterval( std::chrono::milliseconds{milliseconds}); } @@ -153,6 +165,7 @@ LD_EXPORT(void) LDClientConfigBuilder_Events_AllAttributesPrivate(LDClientConfigBuilder b, bool all_attributes_private) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Events().AllAttributesPrivate(all_attributes_private); } @@ -160,6 +173,7 @@ LD_EXPORT(void) LDClientConfigBuilder_Events_PrivateAttribute(LDClientConfigBuilder b, char const* attribute_reference) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Events().PrivateAttribute(attribute_reference); } @@ -167,6 +181,7 @@ LD_EXPORT(void) LDClientConfigBuilder_DataSource_WithReasons(LDClientConfigBuilder b, bool with_reasons) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->DataSource().WithReasons(with_reasons); } @@ -174,6 +189,7 @@ LD_EXPORT(void) LDClientConfigBuilder_DataSource_UseReport(LDClientConfigBuilder b, bool use_report) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->DataSource().UseReport(use_report); } @@ -209,6 +225,7 @@ LD_EXPORT(void) LDDataSourceStreamBuilder_InitialReconnectDelayMs(LDDataSourceStreamBuilder b, unsigned int milliseconds) { LD_ASSERT_NOT_NULL(b); + TO_STREAM_BUILDER(b)->InitialReconnectDelay( std::chrono::milliseconds{milliseconds}); } @@ -225,6 +242,7 @@ LD_EXPORT(void) LDDataSourcePollBuilder_IntervalS(LDDataSourcePollBuilder b, unsigned int seconds) { LD_ASSERT_NOT_NULL(b); + TO_POLL_BUILDER(b)->PollInterval(std::chrono::seconds{seconds}); } @@ -237,6 +255,7 @@ LDClientConfigBuilder_HttpProperties_WrapperName(LDClientConfigBuilder b, char const* wrapper_name) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(wrapper_name); + TO_BUILDER(b)->HttpProperties().WrapperName(wrapper_name); } @@ -246,6 +265,7 @@ LDClientConfigBuilder_HttpProperties_WrapperVersion( char const* wrapper_version) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(wrapper_version); + TO_BUILDER(b)->HttpProperties().WrapperVersion(wrapper_version); } @@ -256,6 +276,7 @@ LDClientConfigBuilder_HttpProperties_Header(LDClientConfigBuilder b, LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(key); LD_ASSERT_NOT_NULL(value); + TO_BUILDER(b)->HttpProperties().Header(key, value); } @@ -270,6 +291,7 @@ LD_EXPORT(void) LDLoggingBasicBuilder_Free(LDLoggingBasicBuilder b) { LD_EXPORT(void) LDClientConfigBuilder_Logging_Disable(LDClientConfigBuilder b) { LD_ASSERT_NOT_NULL(b); + TO_BUILDER(b)->Logging().Logging(LoggingBuilder::NoLogging()); } @@ -277,6 +299,7 @@ LD_EXPORT(void) LDLoggingBasicBuilder_Level(LDLoggingBasicBuilder b, enum LDLogLevel level) { using launchdarkly::LogLevel; LD_ASSERT_NOT_NULL(b); + LoggingBuilder::BasicLogging* logger = TO_BASIC_LOGGING_BUILDER(b); logger->Level(static_cast(level)); } @@ -284,6 +307,7 @@ LDLoggingBasicBuilder_Level(LDLoggingBasicBuilder b, enum LDLogLevel level) { void LDLoggingBasicBuilder_Tag(LDLoggingBasicBuilder b, char const* tag) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(tag); + TO_BASIC_LOGGING_BUILDER(b)->Tag(tag); } @@ -292,6 +316,7 @@ LDClientConfigBuilder_Logging_Basic(LDClientConfigBuilder b, LDLoggingBasicBuilder basic_builder) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(basic_builder); + LoggingBuilder::BasicLogging* bb = TO_BASIC_LOGGING_BUILDER(basic_builder); TO_BUILDER(b)->Logging().Logging(*bb); LDLoggingBasicBuilder_Free(basic_builder); @@ -316,6 +341,7 @@ LDClientConfigBuilder_Logging_Custom(LDClientConfigBuilder b, LDLoggingCustomBuilder custom_builder) { LD_ASSERT_NOT_NULL(b); LD_ASSERT_NOT_NULL(custom_builder); + LoggingBuilder::CustomLogging* cb = TO_CUSTOM_LOGGING_BUILDER(custom_builder); TO_BUILDER(b)->Logging().Logging(*cb); @@ -325,6 +351,7 @@ LDClientConfigBuilder_Logging_Custom(LDClientConfigBuilder b, LD_EXPORT(void) LDLoggingCustomBuilder_Backend(LDLoggingCustomBuilder b, LDLogBackend backend) { LD_ASSERT_NOT_NULL(b); + TO_CUSTOM_LOGGING_BUILDER(b)->Backend( std::make_shared(backend)); } diff --git a/libs/common/src/bindings/c/context.cpp b/libs/common/src/bindings/c/context.cpp index b69dd30d3..24efcbc9d 100644 --- a/libs/common/src/bindings/c/context.cpp +++ b/libs/common/src/bindings/c/context.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "../../c_binding_helpers.hpp" using launchdarkly::AttributeReference; using launchdarkly::Context; @@ -20,21 +21,32 @@ LD_EXPORT(void) LDContext_Free(LDContext context) { } LD_EXPORT(bool) LDContext_Valid(LDContext context) { + LD_ASSERT_NOT_NULL(context); + return AS_CONTEXT(context)->valid(); } LD_EXPORT(LDValue) LDContext_Get(LDContext context, char const* kind, char const* ref) { + LD_ASSERT_NOT_NULL(context); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(ref); + return reinterpret_cast( const_cast(&(AS_CONTEXT(context)->get(kind, ref)))); } LD_EXPORT(char const*) LDContext_Errors(LDContext context) { + LD_ASSERT_NOT_NULL(context); + return AS_CONTEXT(context)->errors().c_str(); } LD_EXPORT(LDContext_PrivateAttributesIter) -LDContext_CreatePrivateAttributesIter(LDContext context, char const* kind) { +LDContext_PrivateAttributesIter_New(LDContext context, char const* kind) { + LD_ASSERT_NOT_NULL(context); + LD_ASSERT_NOT_NULL(kind); + auto* cpp_context = AS_CONTEXT(context); auto found = std::find(cpp_context->kinds().begin(), cpp_context->kinds().end(), kind); @@ -50,22 +62,28 @@ LDContext_CreatePrivateAttributesIter(LDContext context, char const* kind) { } LD_EXPORT(void) -LDContext_DestroyPrivateAttributesIter(LDContext_PrivateAttributesIter iter) { +LDContext_PrivateAttributesIter_Free(LDContext_PrivateAttributesIter iter) { delete AS_PRIVATE_ATTRIBUTES_ITERATOR(iter); } LD_EXPORT(void) LDContext_PrivateAttributesIter_Next(LDContext_PrivateAttributesIter iter) { + LD_ASSERT_NOT_NULL(iter); + AS_PRIVATE_ATTRIBUTES_ITERATOR(iter)->Next(); } LD_EXPORT(bool) LDContext_PrivateAttributesIter_End(LDContext_PrivateAttributesIter iter) { + LD_ASSERT_NOT_NULL(iter); + return AS_PRIVATE_ATTRIBUTES_ITERATOR(iter)->End(); } LD_EXPORT(char const*) LDContext_PrivateAttributesIter_Value(LDContext_PrivateAttributesIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto& redaction_name = AS_PRIVATE_ATTRIBUTES_ITERATOR(iter)->iter->redaction_name(); return redaction_name.c_str(); diff --git a/libs/common/src/bindings/c/context_builder.cpp b/libs/common/src/bindings/c/context_builder.cpp index 9cf808773..7fccf6b73 100644 --- a/libs/common/src/bindings/c/context_builder.cpp +++ b/libs/common/src/bindings/c/context_builder.cpp @@ -3,6 +3,7 @@ #include #include +#include "../../c_binding_helpers.hpp" #define AS_BUILDER(x) reinterpret_cast(x) @@ -26,6 +27,8 @@ LD_EXPORT(void) LDContextBuilder_Free(LDContextBuilder builder) { } LD_EXPORT(LDContext) LDContextBuilder_Build(LDContextBuilder builder) { + LD_ASSERT_NOT_NULL(builder); + auto built = AS_BUILDER(builder)->builder.build(); auto context = new Context(std::move(built)); LDContextBuilder_Free(builder); @@ -36,6 +39,10 @@ LD_EXPORT(void) LDContextBuilder_AddKind(LDContextBuilder builder, char const* kind, char const* key) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(key); + auto* binding = AS_BUILDER(builder); binding->kind_to_key[kind] = key; binding->builder.kind(kind, key); @@ -46,6 +53,10 @@ LDContextBuilder_Attributes_Set(LDContextBuilder builder, char const* kind, char const* attr_key, LDValue val) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(attr_key); + auto* binding = AS_BUILDER(builder); auto existing = binding->kind_to_key.find(kind); if (existing != binding->kind_to_key.end()) { @@ -63,6 +74,11 @@ LDContextBuilder_Attributes_SetPrivate(LDContextBuilder builder, char const* kind, char const* attr_key, LDValue val) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(attr_key); + LD_ASSERT_NOT_NULL(val); + auto* binding = AS_BUILDER(builder); auto existing = binding->kind_to_key.find(kind); if (existing != binding->kind_to_key.end()) { @@ -79,6 +95,10 @@ LD_EXPORT(bool) LDContextBuilder_Attributes_SetName(LDContextBuilder builder, char const* kind, char const* name) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(name); + auto* binding = AS_BUILDER(builder); auto existing = binding->kind_to_key.find(kind); if (existing != binding->kind_to_key.end()) { @@ -94,6 +114,9 @@ LD_EXPORT(bool) LDContextBuilder_Attributes_SetAnonymous(LDContextBuilder builder, char const* kind, bool anonymous) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + auto* binding = AS_BUILDER(builder); auto existing = binding->kind_to_key.find(kind); if (existing != binding->kind_to_key.end()) { @@ -109,6 +132,10 @@ LD_EXPORT(bool) LDContextBuilder_Attributes_AddPrivateAttribute(LDContextBuilder builder, char const* kind, char const* attr_key) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(kind); + LD_ASSERT_NOT_NULL(attr_key); + auto* binding = AS_BUILDER(builder); auto existing = binding->kind_to_key.find(kind); if (existing != binding->kind_to_key.end()) { diff --git a/libs/common/src/bindings/c/object_builder.cpp b/libs/common/src/bindings/c/object_builder.cpp index 75574780e..1b41d9e2b 100644 --- a/libs/common/src/bindings/c/object_builder.cpp +++ b/libs/common/src/bindings/c/object_builder.cpp @@ -3,6 +3,7 @@ #include #include +#include "../../c_binding_helpers.hpp" #include #include @@ -24,12 +25,18 @@ LD_EXPORT(void) LDObjectBuilder_Free(LDObjectBuilder builder) { LD_EXPORT(void) LDObjectBuilder_Add(LDObjectBuilder builder, char const* key, LDValue val) { + LD_ASSERT_NOT_NULL(builder); + LD_ASSERT_NOT_NULL(key); + LD_ASSERT_NOT_NULL(val); + auto map = AS_MAP(builder); map->emplace(key, std::move(*AS_VALUE(val))); LDValue_Free(val); } LD_EXPORT(LDValue) LDObjectBuilder_Build(LDObjectBuilder builder) { + LD_ASSERT_NOT_NULL(builder); + auto map = AS_MAP(builder); auto value = new Value(std::move(*map)); delete map; diff --git a/libs/common/src/bindings/c/status.cpp b/libs/common/src/bindings/c/status.cpp index 63cbba900..bb0d4a362 100644 --- a/libs/common/src/bindings/c/status.cpp +++ b/libs/common/src/bindings/c/status.cpp @@ -24,9 +24,7 @@ LD_EXPORT(bool) LDStatus_Ok(LDStatus res) { } LD_EXPORT(void) LDStatus_Free(LDStatus error) { - if (Error* e = TO_ERROR(error)) { - delete e; - } + delete TO_ERROR(error); } LD_EXPORT(LDStatus) LDStatus_Success(void) { diff --git a/libs/common/src/bindings/c/value.cpp b/libs/common/src/bindings/c/value.cpp index dadd18c09..0cc8b84c3 100644 --- a/libs/common/src/bindings/c/value.cpp +++ b/libs/common/src/bindings/c/value.cpp @@ -29,6 +29,8 @@ LD_EXPORT(LDValue) LDValue_NewNumber(double val) { } LD_EXPORT(LDValue) LDValue_NewString(char const* val) { + LD_ASSERT_NOT_NULL(val); + return AS_LDVALUE(new Value(val)); } @@ -41,6 +43,8 @@ LD_EXPORT(void) LDValue_Free(LDValue val) { } LD_EXPORT(enum LDValueType) LDValue_Type(LDValue val) { + LD_ASSERT_NOT_NULL(val); + switch (AS_VALUE(val)->Type()) { case Value::Type::kNull: return LDValueType_Null; @@ -59,18 +63,26 @@ LD_EXPORT(enum LDValueType) LDValue_Type(LDValue val) { } LD_EXPORT(bool) LDValue_GetBool(LDValue val) { + LD_ASSERT_NOT_NULL(val); + return AS_VALUE(val)->AsBool(); } LD_EXPORT(double) LDValue_GetNumber(LDValue val) { + LD_ASSERT_NOT_NULL(val); + return AS_VALUE(val)->AsDouble(); } LD_EXPORT(char const*) LDValue_GetString(LDValue val) { + LD_ASSERT_NOT_NULL(val); + return AS_VALUE(val)->AsString().c_str(); } LD_EXPORT(unsigned int) LDValue_Count(LDValue val) { + LD_ASSERT_NOT_NULL(val); + auto* value = AS_VALUE(val); switch (value->Type()) { case Value::Type::kObject: @@ -83,6 +95,8 @@ LD_EXPORT(unsigned int) LDValue_Count(LDValue val) { } LD_EXPORT(LDValue_ArrayIter) LDValue_CreateArrayIter(LDValue val) { + LD_ASSERT_NOT_NULL(val); + if (AS_VALUE(val)->IsArray()) { auto& array = AS_VALUE(val)->AsArray(); return reinterpret_cast( @@ -93,24 +107,34 @@ LD_EXPORT(LDValue_ArrayIter) LDValue_CreateArrayIter(LDValue val) { } LD_EXPORT(void) LDValue_ArrayIter_Next(LDValue_ArrayIter iter) { + LD_ASSERT_NOT_NULL(iter); + AS_ARR_ITER(iter)->Next(); } LD_EXPORT(bool) LDValue_ArrayIter_End(LDValue_ArrayIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto* val_iter = AS_ARR_ITER(iter); return val_iter->End(); } LD_EXPORT(LDValue) LdValue_ArrayIter_Value(LDValue_ArrayIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto* val_iter = AS_ARR_ITER(iter); return AS_LDVALUE(const_cast(&(*val_iter->iter))); } LD_EXPORT(void) LDValue_DestroyArrayIter(LDValue_ArrayIter iter) { + LD_ASSERT_NOT_NULL(iter); + delete AS_ARR_ITER(iter); } LD_EXPORT(LDValue_ObjectIter) LDValue_CreateObjectIter(LDValue val) { + LD_ASSERT_NOT_NULL(val); + if (AS_VALUE(val)->IsObject()) { auto& obj = AS_VALUE(val)->AsObject(); return reinterpret_cast( @@ -121,25 +145,35 @@ LD_EXPORT(LDValue_ObjectIter) LDValue_CreateObjectIter(LDValue val) { } LD_EXPORT(void) LDValue_ObjectIter_Next(LDValue_ObjectIter iter) { + LD_ASSERT_NOT_NULL(iter); + AS_OBJ_ITER(iter)->Next(); } LD_EXPORT(bool) LDValue_ObjectIter_End(LDValue_ObjectIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto* val_iter = AS_OBJ_ITER(iter); return val_iter->End(); } LD_EXPORT(LDValue) LdValue_ObjectIter_Value(LDValue_ObjectIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto* val_iter = AS_OBJ_ITER(iter); return AS_LDVALUE(const_cast(&val_iter->iter->second)); } LD_EXPORT(char const*) LdValue_ObjectIter_Key(LDValue_ObjectIter iter) { + LD_ASSERT_NOT_NULL(iter); + auto* val_iter = AS_OBJ_ITER(iter); return val_iter->iter->first.c_str(); } LD_EXPORT(void) LDValue_DestroyObjectIter(LDValue_ObjectIter iter) { + LD_ASSERT_NOT_NULL(iter); + delete AS_OBJ_ITER(iter); } diff --git a/libs/common/tests/context_c_binding_test.cpp b/libs/common/tests/context_c_binding_test.cpp index c387c1aa4..d2afbce06 100644 --- a/libs/common/tests/context_c_binding_test.cpp +++ b/libs/common/tests/context_c_binding_test.cpp @@ -51,7 +51,7 @@ TEST(ContextCBindingTests, CanAddAttributes) { auto count = 0; LDContext_PrivateAttributesIter iter = - LDContext_CreatePrivateAttributesIter(context, "user"); + LDContext_PrivateAttributesIter_New(context, "user"); while (!LDContext_PrivateAttributesIter_End(iter)) { if (count == 0) { @@ -66,7 +66,7 @@ TEST(ContextCBindingTests, CanAddAttributes) { count++; } - LDContext_DestroyPrivateAttributesIter(iter); + LDContext_PrivateAttributesIter_Free(iter); EXPECT_EQ(2, count);