A device detection library that is used natively or by 51Degrees products

collection.h

1/* *********************************************************************
2 * This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3 * Copyright 2026 51 Degrees Mobile Experts Limited, Davidson House,
4 * Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5 *
6 * This Original Work is licensed under the European Union Public Licence
7 * (EUPL) v.1.2 and is subject to its terms as set out below.
8 *
9 * If a copy of the EUPL was not distributed with this file, You can obtain
10 * one at https://opensource.org/licenses/EUPL-1.2.
11 *
12 * The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13 * amended by the European Commission) shall be deemed incompatible for
14 * the purposes of the Work and the provisions of the compatibility
15 * clause in Article 5 of the EUPL shall not apply.
16 *
17 * If using the Work as, or as part of, a network application, by
18 * including the attribution notice(s) required under Article 5 of the EUPL
19 * in the end user terms of the application under an appropriate heading,
20 * such notice(s) shall fulfill the requirements of that article.
21 * ********************************************************************* */
22
23#ifndef FIFTYONE_DEGREES_COLLECTION_H_INCLUDED
24#define FIFTYONE_DEGREES_COLLECTION_H_INCLUDED
25
26#ifdef FIFTYONE_DEGREES_IPI_SYMBOLS
27#include "ipiSymbols.h"
28#endif
29
240
241 /* Define NDEBUG if needed, to ensure asserts are disabled in release builds */
242#if !defined(DEBUG) && !defined(_DEBUG) && !defined(NDEBUG)
243#define NDEBUG
244#endif
245
246#include "collectionKey.h"
247#include "data.h"
248#include "exceptions.h"
249#include "cache.h"
250#include "file.h"
251#include "memory.h"
252#include "common.h"
253#include <stdio.h>
254#include <string.h>
255
256#include "propertyValueType.h"
257
262#define FIFTYONE_DEGREES_COLLECTION_FREE(c) \
263if (c != NULL) { c->freeCollection(c); }
264
272#ifndef FIFTYONE_DEGREES_MEMORY_ONLY
273#define FIFTYONE_DEGREES_COLLECTION_RELEASE(c, i) { assert(!((i)->collection) || (c == (i)->collection)); c->release(i); };
274#else
275#define FIFTYONE_DEGREES_COLLECTION_RELEASE(c, i)
276#endif
277
282#pragma pack(push, 1)
283typedef struct fiftyone_degrees_collection_header_t {
285 uint32_t length;
288 uint32_t count;
290#pragma pack(pop)
291
296typedef struct fiftyone_degrees_collection_config_t {
297 bool loaded;
298 uint32_t capacity;
300 uint16_t concurrency;
304
306typedef struct fiftyone_degrees_collection_t fiftyoneDegreesCollection;
307typedef struct fiftyone_degrees_collection_item_t fiftyoneDegreesCollectionItem;
308typedef struct fiftyone_degrees_collection_file_t fiftyoneDegreesCollectionFile;
310
317typedef struct fiftyone_degrees_collection_item_t {
319 void *handle;
320
327
339typedef void* (*fiftyoneDegreesCollectionGetMethod)(
340 const fiftyoneDegreesCollection *collection,
343 fiftyoneDegreesException *exception);
344
355typedef void* (*fiftyoneDegreesCollectionFileRead)(
356 const fiftyoneDegreesCollectionFile *collection,
359 fiftyoneDegreesException *exception);
360
373 void *state,
376 fiftyoneDegreesException *exception);
377
385
391 fiftyoneDegreesCollection* collection);
392
401 void *state,
402 uint32_t key,
403 void *data);
404
410typedef struct fiftyone_degrees_collection_t {
421 void *state;
425 uint32_t count;
426 uint32_t elementSize;
427 uint32_t size;
430#ifdef FIFTYONE_DEGREES_LARGE_DATA_FILE_SUPPORT
431 byte offsetShift;
440#endif
441 const char *typeName;
443
447typedef struct fiftyone_degrees_collection_memory_t {
449 byte *firstByte;
450 byte *lastByte;
454
458typedef struct fiftyone_degrees_collection_file_t {
467
473typedef struct fiftyone_degrees_collection_cache_t {
478
488
498 const fiftyoneDegreesCollection *collection,
499 uint32_t indexOrOffset,
500 fiftyoneDegreesException *exception);
501
518 FILE *file,
523
538
539#ifdef FIFTYONE_DEGREES_LARGE_DATA_FILE_SUPPORT
540
565fiftyoneDegreesCollectionCreateFromFileWithOffsetShift(
566 FILE *file,
571 byte offsetShift);
572
588fiftyoneDegreesCollectionCreateFromMemoryWithOffsetShift(
591 byte offsetShift);
592
593#endif
594
608 uint32_t offset,
609 fiftyoneDegreesException *exception);
610
631 fiftyoneDegreesException *exception);
632
647 FILE *file,
648 uint32_t elementSize,
649 bool isCount);
650
668 void *initial,
669 fiftyoneDegreesException *exception);
670
686 uint32_t elementSize,
687 bool isCount);
688
689
711 const fiftyoneDegreesCollection *collection,
716 void *state,
718 fiftyoneDegreesException *exception);
719
720#ifndef FIFTYONE_DEGREES_MEMORY_ONLY
721
731
736#define FIFTYONE_DEGREES_COLLECTION_HELD_STRINGS_GAP_BYTES ((uint32_t)65536)
737
739#define FIFTYONE_DEGREES_COLLECTION_HELD_SCAN_BUFFER_BYTES ((uint32_t)65536)
740
745typedef struct fiftyone_degrees_collection_held_range_t {
746 uint32_t first;
747 uint32_t end;
748 byte *memory;
750
763 void *state,
766 fiftyoneDegreesCollection **collection);
767
772typedef struct fiftyone_degrees_collection_held_bucket_t {
773 uint32_t first;
774 uint32_t last;
775 uint32_t lastTag;
777
781typedef struct fiftyone_degrees_collection_held_strings_t {
783 uint32_t bucketCount;
784 uint32_t bytes;
786 uint32_t count;
788
800 void *state,
801 uint32_t offset,
802 uint32_t tag,
803 fiftyoneDegreesException *exception);
804
811 void *state,
812 const byte *record);
813
824 uint32_t *count,
825 uint32_t first,
826 uint32_t end);
827
838 uint32_t *count,
839 uint32_t first,
840 uint32_t length,
841 uint32_t limit);
842
858 fiftyoneDegreesCollection **collection,
859 FILE *file,
860 uint64_t startPosition,
861 uint32_t unitBytes,
863 uint32_t rangeCount);
864
886 fiftyoneDegreesCollection **collection,
887 FILE *file,
889 byte shift,
890 bool replaceable,
892 uint32_t rangeCount,
894 void *createState);
895
908 FILE *file,
909 byte *buffer,
910 uint64_t position,
911 uint32_t count,
912 uint32_t recordBytes,
914 void *state);
915
924 uint32_t bytes);
925
934 uint32_t offset,
935 uint32_t tag);
936
950 void *state,
951 fiftyoneDegreesException *exception);
952
960
967
968#endif
969
983#define fiftyoneDegreesCollectionGetCount(collection) ((collection)->count)
984
988
989#endif
fiftyoneDegreesStatusCode fiftyoneDegreesCollectionHeldScan(FILE *file, byte *buffer, uint64_t position, uint32_t count, uint32_t recordBytes, fiftyoneDegreesCollectionHeldScanMethod method, void *state)
Calls the method for each fixed size record in a stretch of the data file.
fiftyoneDegreesCollection * fiftyoneDegreesCollectionCreateFromMemory(fiftyoneDegreesMemoryReader *reader, fiftyoneDegreesCollectionHeader header)
Creates the collection from a memory reader where the collection maps to the memory allocated to the ...
bool(* fiftyoneDegreesCollectionIterateMethod)(void *state, uint32_t key, void *data)
Method used to iterate over data held in a collection.
Definition collection.h:400
int(* fiftyoneDegreesCollectionItemComparer)(void *state, fiftyoneDegreesCollectionItem *item, fiftyoneDegreesCollectionKey key, fiftyoneDegreesException *exception)
Compares two items and returns the difference between them for the purposes of a binary search of ord...
Definition collection.h:372
void fiftyoneDegreesCollectionHeldRangeAdd(fiftyoneDegreesCollectionHeldRange *ranges, uint32_t *count, uint32_t first, uint32_t end)
Adds a stretch to a list with room for it.
fiftyoneDegreesStatusCode fiftyoneDegreesCollectionHeldStringsPlan(fiftyoneDegreesCollectionHeldStrings *strings, fiftyoneDegreesCollectionHeldStringEnd end, void *state, fiftyoneDegreesException *exception)
Works out the stretches of the strings to hold from the offsets recorded, which leaves on file any st...
fiftyoneDegreesStatusCode fiftyoneDegreesCollectionHeldCreate(fiftyoneDegreesCollection **collection, FILE *file, uint64_t startPosition, uint32_t unitBytes, fiftyoneDegreesCollectionHeldRange *ranges, uint32_t rangeCount)
Replaces the collection with one holding the stretches in memory, which reads everything else from th...
fiftyoneDegreesStatusCode fiftyoneDegreesCollectionHeldApply(fiftyoneDegreesCollection **collection, FILE *file, fiftyoneDegreesCollectionHeader header, byte shift, bool replaceable, fiftyoneDegreesCollectionHeldRange *ranges, uint32_t rangeCount, fiftyoneDegreesCollectionHeldCreateMethod create, void *createState)
Holds the stretches of a collection that reads from the file.
fiftyoneDegreesFileHandle * fiftyoneDegreesCollectionReadFilePosition(const fiftyoneDegreesCollectionFile *file, uint32_t offset, fiftyoneDegreesException *exception)
Get a handle from the file pool associated with the collection and position the file handle at the of...
long fiftyoneDegreesCollectionBinarySearch(const fiftyoneDegreesCollection *collection, fiftyoneDegreesCollectionItem *item, fiftyoneDegreesCollectionIndexOrOffset lowerKey, fiftyoneDegreesCollectionIndexOrOffset upperKey, const fiftyoneDegreesCollectionKeyType *keyType, void *state, fiftyoneDegreesCollectionItemComparer comparer, fiftyoneDegreesException *exception)
Where a collection is fixed width and contains an ordered list of items this method is used to perfor...
void * fiftyoneDegreesCollectionReadFileVariable(const fiftyoneDegreesCollectionFile *file, fiftyoneDegreesData *data, const fiftyoneDegreesCollectionKey *key, void *initial, fiftyoneDegreesException *exception)
Reads a variable size item from the file where the initial bytes can be used to calculate the size of...
void fiftyoneDegreesCollectionHeldStringsAdd(fiftyoneDegreesCollectionHeldStrings *strings, uint32_t offset, uint32_t tag)
Records the offset of a string that is needed.
void fiftyoneDegreesCollectionHeldRangeAddWithin(fiftyoneDegreesCollectionHeldRange *ranges, uint32_t *count, uint32_t first, uint32_t length, uint32_t limit)
Adds a stretch cut to end at the limit of its collection.
void(* fiftyoneDegreesCollectionHeldScanMethod)(void *state, const byte *record)
Called for each fixed size record of a stretch of the data file.
Definition collection.h:810
int32_t fiftyoneDegreesCollectionGetInteger32(const fiftyoneDegreesCollection *collection, uint32_t indexOrOffset, fiftyoneDegreesException *exception)
Returns a 32 bit integer from collections that provide such values.
fiftyoneDegreesCollectionHeader fiftyoneDegreesCollectionHeaderFromFile(FILE *file, uint32_t elementSize, bool isCount)
Reads the 4 bytes at the current reader position and configures the collection header.
fiftyoneDegreesStatusCode(* fiftyoneDegreesCollectionHeldCreateMethod)(void *state, const fiftyoneDegreesCollectionConfig *config, fiftyoneDegreesCollectionHeader header, fiftyoneDegreesCollection **collection)
Creates the collection that replaces the one provided when everything in it is to be held.
Definition collection.h:762
bool fiftyoneDegreesCollectionGetIsMemoryOnly()
Determines if in memory collection methods have been compiled so they are fully optimized.
void fiftyoneDegreesCollectionHeldStringsFree(fiftyoneDegreesCollectionHeldStrings *strings)
Frees everything held by the strings plan.
void *(* fiftyoneDegreesCollectionFileRead)(const fiftyoneDegreesCollectionFile *collection, const fiftyoneDegreesCollectionKey *key, fiftyoneDegreesData *data, fiftyoneDegreesException *exception)
Reads the item from the underlying data file.
Definition collection.h:355
fiftyoneDegreesCollection * fiftyoneDegreesCollectionCreateFromFile(FILE *file, fiftyoneDegreesFilePool *reader, const fiftyoneDegreesCollectionConfig *config, fiftyoneDegreesCollectionHeader header, fiftyoneDegreesCollectionFileRead read)
Creates a collection from the file handle at the current position in the file.
fiftyoneDegreesStatusCode fiftyoneDegreesCollectionHeldStringsInit(fiftyoneDegreesCollectionHeldStrings *strings, uint32_t bytes)
Prepares to record the offsets of the strings needed.
uint32_t(* fiftyoneDegreesCollectionHeldStringEnd)(void *state, uint32_t offset, uint32_t tag, fiftyoneDegreesException *exception)
Gets the offset after the string at the offset provided.
Definition collection.h:799
void(* fiftyoneDegreesCollectionFreeMethod)(fiftyoneDegreesCollection *collection)
Frees all the memory and handles associated with the collection.
Definition collection.h:390
fiftyoneDegreesCollectionHeader fiftyoneDegreesCollectionHeaderFromMemory(fiftyoneDegreesMemoryReader *reader, uint32_t elementSize, bool isCount)
Reads the 4 bytes at the current reader position and configures the collection header.
void *(* fiftyoneDegreesCollectionGetMethod)(const fiftyoneDegreesCollection *collection, const fiftyoneDegreesCollectionKey *key, fiftyoneDegreesCollectionItem *item, fiftyoneDegreesException *exception)
Gets an item from the collection.
Definition collection.h:339
void fiftyoneDegreesCollectionHeldStringsFreeOffsets(fiftyoneDegreesCollectionHeldStrings *strings)
Frees the offsets recorded, which are not needed once the stretches are worked out.
void * fiftyoneDegreesCollectionReadFileFixed(const fiftyoneDegreesCollectionFile *file, const fiftyoneDegreesCollectionKey *key, fiftyoneDegreesData *data, fiftyoneDegreesException *exception)
Used with collections where each item is a fixed number of bytes recorded in elementSize.
void(* fiftyoneDegreesCollectionReleaseMethod)(fiftyoneDegreesCollectionItem *item)
Releases the item so that the collection can free the memory or take other actions when the caller no...
Definition collection.h:383
long fiftyoneDegreesFileOffset
Type for file offset in API.
Definition fileOffset.h:73
uint32_t fiftyoneDegreesFileOffsetUnsigned
Type for collection start offset (in file).
Definition fileOffset.h:65
fiftyoneDegreesStatusCode
Status returned from the initialisation of a resource.
Definition status.h:81
Cache structure to store the root of the red black tree and a list of allocated cache nodes.
Definition cache.h:191
Type of collection where items are cached as they are used.
Definition collection.h:473
fiftyoneDegreesCollection * source
The source collection used to load items into the cache.
Definition collection.h:474
fiftyoneDegreesCache * cache
Loading cache to use as data source.
Definition collection.h:476
Collection configuration structure which defines how the collection should be created by the create m...
Definition collection.h:296
bool loaded
Collection is loaded entirely into memory.
Definition collection.h:297
uint32_t capacity
Number of items the cache should store, 0 for no cache.
Definition collection.h:298
uint16_t concurrency
Expected number of operations at the same time, which a data set takes as one for each processor when...
Definition collection.h:300
Type of collection where the collection is streamed from file.
Definition collection.h:458
fiftyoneDegreesFileOffset offset
Offset to the collection in the source data structure.
Definition collection.h:462
fiftyoneDegreesCollection * collection
The generic collection.
Definition collection.h:459
fiftyoneDegreesFilePool * reader
Reader used to load items into the cache, or NULL if no cache.
Definition collection.h:460
fiftyoneDegreesCollectionFileRead read
Read method used to read an item from file at an offset or index.
Definition collection.h:463
Collection header structure which defines the size and location of the collection data.
Definition collection.h:283
uint32_t length
Length of all the entities, in bytes, or in offset units where the collection is created with a non z...
Definition collection.h:285
uint32_t count
Number of entities in the collection.
Definition collection.h:288
fiftyoneDegreesFileOffsetUnsigned startPosition
Start position in the data file of the entities.
Definition collection.h:284
The lowest and highest string offsets recorded in part of the strings, and a tag for the highest that...
Definition collection.h:772
uint32_t first
Lowest offset recorded, or UINT32_MAX for none.
Definition collection.h:773
uint32_t last
Highest offset recorded.
Definition collection.h:774
uint32_t lastTag
Tag given with the highest offset.
Definition collection.h:775
A stretch of a collection to hold in memory, in the units of the collection's keys.
Definition collection.h:745
uint32_t first
Key of the first unit of the range.
Definition collection.h:746
byte * memory
The bytes of the range once held.
Definition collection.h:748
uint32_t end
Key after the last unit of the range.
Definition collection.h:747
The strings to hold, worked out from the offsets of the strings needed.
Definition collection.h:781
uint32_t bucketCount
Number of buckets.
Definition collection.h:783
fiftyoneDegreesCollectionHeldBucket * buckets
Offsets recorded.
Definition collection.h:782
uint32_t count
Number of stretches.
Definition collection.h:786
uint32_t bytes
Bytes in the strings collection.
Definition collection.h:784
fiftyoneDegreesCollectionHeldRange * ranges
The stretches to hold.
Definition collection.h:785
All the shared methods and fields required by file, memory and cached collections.
Definition collection.h:410
uint32_t count
The number of items, or 0 if not available.
Definition collection.h:425
fiftyoneDegreesCollectionGetMethod get
Gets an entry into the item provided.
Definition collection.h:411
uint32_t size
Number of bytes in the source data structure containing the collection's data, or where offsetShift i...
Definition collection.h:427
uint32_t elementSize
The size of each entry, or 0 if variable length.
Definition collection.h:426
void * state
Pointer to data for memory, cache or file.
Definition collection.h:421
const char * typeName
Name of collection type (vtable).
Definition collection.h:441
fiftyoneDegreesCollectionFreeMethod freeCollection
Frees collection and all items retrieved from the collection will become invalid.
Definition collection.h:417
fiftyoneDegreesCollectionReleaseMethod release
Releases the item handle.
Definition collection.h:415
Used to store a handle to the underlying item that could be used to release the item when it's finish...
Definition collection.h:317
const fiftyoneDegreesCollection * collection
Collection the item came from which may not have been set.
Definition collection.h:325
fiftyoneDegreesData data
Item data including allocated memory.
Definition collection.h:318
void * handle
A handle that relates to the data.
Definition collection.h:319
Explains to a collection (or cache) what the consumer is looking for.
Definition collectionKey.h:76
Explains to a collection how to properly extract the requested value.
Definition collectionKey.h:67
Type of collection where the collection is held in continuous memory.
Definition collection.h:447
void * memoryToFree
Memory to free when freeing the collection, or NULL if no memory to free.
Definition collection.h:451
byte * lastByte
The last byte in memory of the collection.
Definition collection.h:450
fiftyoneDegreesCollection * collection
The generic collection.
Definition collection.h:448
byte * firstByte
The first byte in memory of the collection.
Definition collection.h:449
Data structure used for reusing memory which may have been allocated in a previous operation.
Definition data.h:105
Structure used to represent a 51Degrees exception and passed into methods that might generate excepti...
Definition exceptions.h:115
Stack of handles used to read data from a single source file.
Definition file.h:239
Used to read data from memory in a similar manner to a file handle.
Definition memory.h:58
Location of the item within the Collection.
Definition collectionKey.h:56
File handle node in the stack of handles.
Definition file.h:231