Array Handling (ArrayList)
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The ArrayList module in libfastjson provides a dynamic, resizable array implementation specifically designed to support JSON array structures. It manages an internal buffer of void* pointers that grow automatically as elements are added, allowing the library to handle arbitrary lists of JSON objects. This module serves as the underlying storage engine for any fjson_object identified with the type fjson_type_array.
Sources: arraylist.h:18-30, json_object.c:595-603
The architecture follows a reference-counting model where the array_list structure tracks the current length, total allocated size, and a custom cleanup function for its elements. This ensures that when a JSON array is destroyed, all nested fjson_object instances within that array are correctly decremented or freed.
Sources: arraylist.h:21-28, json_object.c:580-588
Data Structures and Memory Layout
The core of the array handling system is the struct array_list, which maintains a pointer to the heap-allocated array of generic data pointers.
The array_list Structure
| Field | Type | Description |
|---|---|---|
array | void** | Pointer to the allocated block of memory holding data pointers. |
length | int | The number of elements currently stored in the list. |
size | int | The total capacity of the current array buffer. |
free_fn | array_list_free_fn* | Function pointer used to free elements during list destruction. |
Sources: arraylist.h:21-28
Default Configuration
The module defines a default starting size to minimize initial reallocations.
- Default Size: 32 elements (
ARRAY_LIST_DEFAULT_SIZE).
Sources: arraylist.h:18
Core ArrayList API
The arraylist module provides low-level memory management functions that are wrapped by the higher-level json_object API.
Lifecycle Management
array_list_new(free_fn): Allocates a new list and initializes the internal buffer to the default size.array_list_free(arr): Iterates through the list, calling thefree_fnon each non-NULL element, and then frees the internal buffer and the list structure itself.
Sources: arraylist.c:26-51
Element Manipulation
array_list_add(arr, data): Appends an element to the end of the list, expanding the buffer if necessary.array_list_put_idx(arr, idx, data): Places an element at a specific index. If the index exceeds the current size, the array is expanded. If an element already exists at that index, it is freed using the registeredfree_fn.array_list_get_idx(arr, i): Returns the pointer at the specified index, or NULL if out of bounds.array_list_del_idx(arr, idx): Removes an element, shifts subsequent elements to fill the gap usingmemmove, and nullifies the last slot.
Sources: arraylist.c:54-99
Internal Expansion Logic
When a list exceeds its current capacity, it uses an internal doubling strategy to minimize frequent reallocations.
Sources: arraylist.c:64-77
Integration with fjson_object
Libfastjson wraps the ArrayList within the fjson_object structure to provide JSON-specific array functionality. When an fjson_object is created as an array, it initializes an internal array_list with a specific free function: fjson_object_array_entry_free.
Sources: json_object.c:580-603
JSON Array Operations
The library provides specialized functions for interacting with JSON-typed arrays:
| Function | ArrayList Equivalent | Description |
|---|---|---|
fjson_object_array_add | array_list_add | Adds a JSON object to the end of the array. |
fjson_object_array_put_idx | array_list_put_idx | Puts a JSON object at a specific index. |
fjson_object_array_get_idx | array_list_get_idx | Retrieves the JSON object at an index. |
fjson_object_array_length | array_list_length | Returns the number of JSON objects in the array. |
fjson_object_array_del_idx | array_list_del_idx | Deletes a JSON object at an index. |
Sources: json_object.c:623-653, json_object.h:496-560
Serialization and Printing
When converting a JSON array to a string, the library iterates through the ArrayList to recursively print its members.
Serialization Flow
Sources: json_print.c:380-410, json_object.c:556-578
The printer supports different flags such as FJSON_TO_STRING_PRETTY and FJSON_TO_STRING_SPACED, which influence how the array elements are formatted with newlines, tabs, or spaces.
Sources: json_print.c:385-408, json_object.h:43-70
Sorting and Searching
The ArrayList provides built-in support for the standard C library's qsort and bsearch functions, enabling efficient data organization and retrieval.
array_list_sort: Wrapsqsortto sort the internal pointer array using a provided comparison function.array_list_bsearch: Wrapsbsearchfor binary searching within a sorted array.
Sources: arraylist.c:115-146
Sorting Example in JSON Context
In the json_object layer, fjson_object_array_sort allows sorting an array of JSON objects based on custom criteria (e.g., sorting an array of integers by their numeric value).
void fjson_object_array_sort(struct fjson_object *jso, int(*sort_fn)(const void *, const void *))
{
array_list_sort(jso->o.c_array, sort_fn);
}
Sources: json_object.c:609-612
Summary
The ArrayList module provides the foundational dynamic storage required for JSON arrays in libfastjson. By combining a growth-oriented memory strategy with a reference-counted cleanup mechanism, it allows the library to handle complex nested structures efficiently. The module is deeply integrated into the fjson_object lifecycle, ensuring that array-based data is correctly serialized, sorted, and freed.
Sources: arraylist.c:1-155, json_object.c:550-655