/* 1. Basic Types for Modeling (Opaque definitions) */
typedef struct _wmem_allocator_t {
    void *storage_sink; 
} wmem_allocator_t;

typedef struct _packet_info {
    wmem_allocator_t *pool;
} packet_info;

/* 2. Coverity Primitives */
void *__coverity_alloc__(size_t);
void __coverity_free__(void *);

/* 
 * 3. Base Allocation Logic
 * If allocator is NULL -> Standard allocation (tracked for leaks)
 * If allocator != NULL -> Scoped allocation (assigned to sink, suppresses leaks)
 */
void *wmem_alloc(wmem_allocator_t *allocator, size_t size) {
    void *ptr = __coverity_alloc__(size);
    if (allocator != NULL) {
        // Pointer "escapes" to allocator; caller no longer responsible for free.
        allocator->storage_sink = ptr;
    }
    return ptr;
}

/* 4. Base Deallocation Logic */
void wmem_free(wmem_allocator_t *allocator, void *ptr) {
    if (allocator == NULL) {
        // Only model the free for the manual (NULL) case.
        __coverity_free__(ptr);
    }
}

/* 5. String and Memory Utilities */
char *wmem_strdup(wmem_allocator_t *allocator, const char *src) {
    return (char *)wmem_alloc(allocator, 1);
}

void *wmem_memdup(wmem_allocator_t *allocator, const void *source, const size_t size) {
    return wmem_alloc(allocator, size);
}

char *wmem_strconcat(wmem_allocator_t *allocator, const char *first, ...) {
    return (char *)wmem_alloc(allocator, 1);
}

/* 6. Specific Scopes (Returning Global Singletons) */
static wmem_allocator_t *epan_scope_ptr;
static wmem_allocator_t *file_scope_ptr;

wmem_allocator_t *wmem_epan_scope(void) {
    if (!epan_scope_ptr) {
        epan_scope_ptr = (wmem_allocator_t*)__coverity_alloc__(sizeof(wmem_allocator_t));
    }
    return epan_scope_ptr;
}

wmem_allocator_t *wmem_file_scope(void) {
    if (!file_scope_ptr) {
        file_scope_ptr = (wmem_allocator_t*)__coverity_alloc__(sizeof(wmem_allocator_t));
    }
    return file_scope_ptr;
}
