sources/cqlrt_cf/cqlholder.m (75 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "cqlrt_cf.h" // CQLHolder is entirly private @interface CQLHolder : NSObject @property (nonatomic) void *bytes; @property (nonatomic) int type; @end @implementation CQLHolder - (instancetype)initWithBytes:(void *)bytesIn andType:(int)typeIn { self = [super init]; self.bytes = bytesIn; self.type = typeIn; return self; } - (void)dealloc { if (self.bytes) { [self dynamicTeardown]; } } // The two kinds of things we know how to hold. #define CF_HELD_TYPE_RESULT_SET 1 #define CF_HELD_TYPE_BOXED_STMT 2 - (void)dynamicTeardown { switch (self.type) { case CF_HELD_TYPE_RESULT_SET: { cql_result_set_ref ref = (__bridge cql_result_set_ref)self; cql_result_set *result_set = (cql_result_set *)self.bytes; result_set->meta.teardown(ref); break; } case CF_HELD_TYPE_BOXED_STMT: { cql_boxed_stmt *box = (cql_boxed_stmt *)self.bytes; // note this is a no-op on null statements, and nulls stmt after finalization cql_finalize_stmt(&box->stmt); break; } } free(self.bytes); self.bytes = NULL; self.type = 0; } @end // The public interface is C, the CQLHolder object is a detail. // For holding result sets. cql_result_set_ref _Nonnull cql_result_set_create( void *_Nonnull data, cql_int32 count, cql_result_set_meta meta) { cql_result_set *result_set = malloc(sizeof(cql_result_set)); result_set->count = count; result_set->data = data; result_set->meta = meta; CQLHolder *holder = [[CQLHolder alloc] initWithBytes:(void *)result_set andType:CF_HELD_TYPE_RESULT_SET]; return (__bridge_retained cql_result_set_ref)holder; } cql_object_ref _Nonnull cql_box_stmt(sqlite3_stmt *_Nullable stmt) { cql_boxed_stmt *box = (cql_boxed_stmt *)malloc(sizeof(cql_boxed_stmt)); box->stmt = stmt; CQLHolder *holder = [[CQLHolder alloc] initWithBytes:(void *)box andType:CF_HELD_TYPE_BOXED_STMT]; return (__bridge_retained cql_object_ref)holder; } // For holding boxed statements. sqlite3_stmt *_Nullable cql_unbox_stmt(cql_object_ref _Nonnull ref) { CQLHolder *holder = (__bridge CQLHolder *)ref; cql_boxed_stmt *box = (cql_boxed_stmt *)holder.bytes; return box->stmt; } cql_result_set *_Nonnull cql_get_result_set_from_ref(cql_result_set_ref _Nonnull ref) { CQLHolder *holder = (__bridge CQLHolder *)ref; cql_result_set *_Nonnull result_set = (cql_result_set *)holder.bytes; return result_set; }