-
Notifications
You must be signed in to change notification settings - Fork 4
/
51Degrees.h
336 lines (302 loc) · 15 KB
/
51Degrees.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/* *********************************************************************
* This Source Code Form is copyright of 51Degrees Mobile Experts Limited.
* Copyright © 2014 51Degrees Mobile Experts Limited, 5 Charlotte Close,
* Caversham, Reading, Berkshire, United Kingdom RG4 7BY
*
* This Source Code Form is the subject of the following patent
* applications, owned by 51Degrees Mobile Experts Limited of 5 Charlotte
* Close, Caversham, Reading, Berkshire, United Kingdom RG4 7BY:
* European Patent Application No. 13192291.6; and
* United States Patent Application Nos. 14/085,223 and 14/085,301.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0.
*
* If a copy of the MPL was not distributed with this file, You can obtain
* one at http://mozilla.org/MPL/2.0/.
*
* This Source Code Form is "Incompatible With Secondary Licenses", as
* defined by the Mozilla Public License, v. 2.0.
********************************************************************** */
#ifndef FIFTYONEDEGREES_H_INCLUDED
#define FIFTYONEDEGREES_H_INCLUDED
#ifdef _MSC_VER
#define _INTPTR 0
#endif
#ifdef __cplusplus
#define EXTERNAL extern "C"
#else
#define EXTERNAL
#endif
#include <stdint.h>
#include <limits.h>
/* Used to represent bytes */
typedef unsigned char byte;
/* Used to represent boolean */
typedef unsigned char fiftyoneDegreesBool;
/* Used to return the match method */
typedef enum { NONE, EXACT, NUMERIC, NEAREST, CLOSEST } fiftyoneDegreesMatchMethod;
/* Used to provide the status of the data set initialisation */
typedef enum e_fiftyoneDegrees_DataSetInitStatus {
DATA_SET_INIT_STATUS_SUCCESS,
DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY,
DATA_SET_INIT_STATUS_CORRUPT_DATA,
DATA_SET_INIT_STATUS_INCORRECT_VERSION,
DATA_SET_INIT_STATUS_FILE_NOT_FOUND
} fiftyoneDegreesDataSetInitStatus;
typedef struct fiftyoneDegreesRange_t {
const int16_t lower;
const int16_t upper;
} fiftyoneDegreesRANGE;
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_ascii_string_t {
const int16_t length;
const byte firstByte;
} fiftyoneDegreesAsciiString;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_component_t {
const byte componentId; /* The unique Id of the component. */
const int32_t nameOffset; /* Offset in the strings data structure to the name */
const int32_t defaultProfileOffset; /* Offset in the profiles data structure to the default profile */
} fiftyoneDegreesComponent;
#pragma pack(pop)
#pragma pack(push, 4)
typedef struct fiftyoneDegrees_map_t {
const int32_t nameOffset; /* Offset in the strings data structure to the name */
} fiftyoneDegreesMap;
#pragma pack(pop)
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_node_numeric_index_t {
const int16_t value; /* The numeric value of the index */
const int32_t relatedNodeOffset; /* The node offset which the numeric value relates to */
} fiftyoneDegreesNodeNumericIndex;
#pragma pack(pop)
#pragma pack(push, 4)
typedef union fiftyoneDegrees_node_index_value_t {
const byte characters[4]; /* If not a string the characters to be used */
const int32_t integer; /* If a string the offset in the strings data structure of the characters */
} fiftyoneDegreesNodeIndexValue;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_node_index_t {
const byte isString; /* True if the value is an offset in the ascii string collection */
union {
const byte characters[4];
const int32_t integer;
} value; /* The value of the index as either an integer or character array */
const int32_t relatedNodeOffset; /* The node offset which the value relates to */
} fiftyoneDegreesNodeIndex;
#pragma pack(pop)
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_string_t {
byte* value;
int16_t length;
} fiftyoneDegreesString;
#pragma pack(pop)
typedef struct fiftyoneDegrees_strings_t {
const fiftyoneDegreesString *firstString;
const int32_t count;
} fiftyoneDegreesStrings;
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_node_t {
const int16_t position;
const int16_t nextCharacterPosition;
const int32_t parentOffset;
const int32_t characterStringOffset;
const int16_t childrenCount;
const int16_t numericChildrenCount;
const int32_t signatureCount;
} fiftyoneDegreesNode;
#pragma pack(pop)
#pragma pack(push, 4)
typedef struct fiftyoneDegrees_profile_offset_t {
const int32_t profileId; /* The unique Id of the profile */
const int32_t offset; /* Offset to the profile in the profiles structure */
} fiftyoneDegreesProfileOffset;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct property_t {
const byte componentIndex; /* Index of the component */
const byte displayOrder; /* The order the property should be displayed in relative to other properties */
const fiftyoneDegreesBool isMandatory; /* True if the property is mandatory and must be provided */
const fiftyoneDegreesBool isList; /* True if the property is a list can can return multiple values */
const fiftyoneDegreesBool showValues; /* True if the values should be shown in GUIs */
const fiftyoneDegreesBool isObsolete; /* True if the property is obsolete and will be removed from future data sets */
const fiftyoneDegreesBool show; /* True if the property should be shown in GUIs */
const byte valueType; /* The type of value the property represents */
const int32_t defaultValueIndex; /* The default value index for the property */
const int32_t nameOffset; /* The offset in the strings structure to the property name */
const int32_t descriptionOffset; /* The offset in the strings structure to the property description */
const int32_t categoryOffset; /* The offset in the strings structure to the property category */
const int32_t urlOffset; /* The offset in the strings structure to the property url */
const int32_t firstValueIndex; /* Index of the first possible value */
const int32_t lastValueIndex; /* Index of the last possible value */
const int32_t mapCount; /* Number of maps the property is associated with */
const int32_t firstMapIndex; /* The first index in the list of maps the property is associated with */
} fiftyoneDegreesProperty;
#pragma pack(pop)
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_value_t {
const int16_t propertyIndex; /* Index of the property the value relates to */
const int32_t nameOffset; /* The offset in the strings structure to the value name */
const int32_t descriptionOffset; /* The offset in the strings structure to the value description */
const int32_t urlOffset; /* The offset in the strings structure to the value url */
} fiftyoneDegreesValue;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_profile_t {
const byte componentIndex;
const int32_t profileId;
const int32_t valueCount;
const int32_t signatureCount;
} fiftyoneDegreesProfile;
#pragma pack(pop)
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_date_t {
const int16_t year;
const byte month;
const byte day;
} fiftyoneDegreesDate;
#pragma pack(pop)
#pragma pack(push, 4)
typedef struct fiftyoneDegrees_entity_header_t {
const int32_t startPosition; /* Start position in the data file of the entities */
const int32_t length; /* Length in bytes of the entities */
const int32_t count; /* Number of entities in the collection */
} fiftyoneDegreesEntityHeader;
#pragma pack(pop)
#pragma pack(push, 2)
typedef struct fiftyoneDegrees_numeric_node_state {
int16_t target;
const fiftyoneDegreesNode *node;
const fiftyoneDegreesNodeNumericIndex *firstNodeNumericIndex;
const fiftyoneDegreesRANGE *range;
int32_t startIndex;
int32_t lowIndex;
int32_t highIndex;
fiftyoneDegreesBool lowInRange;
fiftyoneDegreesBool highInRange;
} fiftyoneDegreesNumericNodeState;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_dataset_header_t {
const int32_t versionMajor;
const int32_t versionMinor;
const int32_t versionBuild;
const int32_t versionRevision;
const byte tag[16];
const int32_t copyrightOffset;
const int16_t age;
const int32_t minUserAgentCount;
const int32_t nameOffset;
const int32_t formatOffset;
const fiftyoneDegreesDate published;
const fiftyoneDegreesDate nextUpdate;
const int32_t deviceCombinations;
const int16_t maxUserAgentLength;
const int16_t minUserAgentLength;
const char lowestCharacter;
const char highestCharacter;
const int32_t maxSignatures;
const int32_t signatureProfilesCount;
const int32_t signatureNodesCount;
const int16_t maxValues;
const int32_t csvBufferLength;
const int32_t jsonBufferLength;
const int32_t xmlBufferLength;
const int32_t maxSignaturesClosest;
const fiftyoneDegreesEntityHeader strings;
const fiftyoneDegreesEntityHeader components;
const fiftyoneDegreesEntityHeader maps;
const fiftyoneDegreesEntityHeader properties;
const fiftyoneDegreesEntityHeader values;
const fiftyoneDegreesEntityHeader profiles;
const fiftyoneDegreesEntityHeader signatures;
const fiftyoneDegreesEntityHeader rankedSignatureIndexes;
const fiftyoneDegreesEntityHeader nodes;
const fiftyoneDegreesEntityHeader rootNodes;
const fiftyoneDegreesEntityHeader profileOffsets;
} fiftyoneDegreesDataSetHeader;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_dataset_t {
const fiftyoneDegreesDataSetHeader header;
int32_t sizeOfSignature; /* The length in bytes of each signature record */
int32_t signatureStartOfNodes; /* The number of bytes to ignore before the nodes start */
const fiftyoneDegreesProperty **requiredProperties; /* Pointer to properties to be returned */
int32_t requiredPropertyCount; /* Number of properties to return */
const byte *strings;
const fiftyoneDegreesComponent *components;
const fiftyoneDegreesMap *maps;
const fiftyoneDegreesProperty *properties;
const fiftyoneDegreesValue *values;
const byte *profiles;
const byte *signatures;
const int32_t *rankedSignatureIndexes;
const byte *nodes;
const fiftyoneDegreesNode **rootNodes;
const fiftyoneDegreesProfileOffset *profileOffsets;
} fiftyoneDegreesDataSet;
#pragma pack(pop)
typedef struct fiftyoneDegrees_linked_signature_list_item_t {
struct fiftyoneDegrees_linked_signature_list_item_t *next;
struct fiftyoneDegrees_linked_signature_list_item_t *previous;
int32_t rankedSignatureIndex;
int32_t frequency;
} fiftyoneDegreesLinkedSignatureListItem;
typedef struct fiftyoneDegrees_linked_signature_list_t {
const fiftyoneDegreesLinkedSignatureListItem *items; /* List of signatures that are being evaluated by Closest match */
fiftyoneDegreesLinkedSignatureListItem *first; /* Pointer to the first signature in the linked list */
fiftyoneDegreesLinkedSignatureListItem *last; /* Pointer to the last signature in the linked list */
int32_t count; /* The number of signatures pointed to by signatures */
fiftyoneDegreesLinkedSignatureListItem *current; /* Pointer to the current item in the list when navigating */
} fiftyoneDegreesLinkedSignatureList;
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_workset_t {
const fiftyoneDegreesDataSet *dataSet; /* A pointer to the data set to use for the match */
char *input; /* An input buffer large enough to store the useragent to be matched */
char *targetUserAgent; /* A pointer to the user agent string */
byte *targetUserAgentArray; /* An array of bytes representing the target user agent */
int32_t targetUserAgentArrayLength; /* The length of the target user agent */
char* relevantNodes; /* Pointer to a char array containing the relevant nodes */
char* closestNodes; /* Pointer to a char array containing the closest nodes */
const fiftyoneDegreesProfile **profiles; /* Pointer to a list of profiles returned for the match */
int32_t profileCount; /* The number of profiles the match contains */
const fiftyoneDegreesNode **nodes; /* Pointer to a list of nodes related to the match */
const fiftyoneDegreesNode **orderedNodes; /* Pointer to a list of nodes in ascending order of signature count */
int32_t nodeCount; /* The number of nodes referenced by **nodes */
int32_t closestNodeRankedSignatureIndex; /* If a single node is returned the index of the ranked signature to be processed */
fiftyoneDegreesLinkedSignatureList linkedSignatureList; /* Linked list of signatures used by Closest match */
byte *signature; /* The signature found if only one exists */
char *signatureAsString; /* The signature as a string */
int16_t nextCharacterPositionIndex;
fiftyoneDegreesMatchMethod method; /* The method used to provide the match result */
int32_t difference; /* The difference score between the signature found and the target */
int32_t rootNodesEvaluated; /* The number of root nodes evaluated */
int32_t stringsRead; /* The number of strings read */
int32_t nodesEvaluated; /* The number of nodes read during the detection */
int32_t signaturesCompared; /* The number of signatures read in full and compared to the target */
int32_t signaturesRead; /* The number of signatures read in full */
int32_t closestSignatures; /* The total number of closest signatures available */
const fiftyoneDegreesValue **values; /* Pointers to values associated with the property requested */
int32_t valuesCount; /* Number of values available */
fiftyoneDegreesBool startWithInitialScore; /* True if the NEAREST and CLOSEST methods should start with an initial score */
int(*functionPtrGetScore)(struct fiftyoneDegrees_workset_t *ws, const fiftyoneDegreesNode *node); /* Returns scores for each different node between signature and match */
const byte* (*functionPtrNextClosestSignature)(struct fiftyoneDegrees_workset_t *ws); /* Returns the next closest signature */
} fiftyoneDegreesWorkset;
#pragma pack(pop)
/* External methods */
EXTERNAL fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyArray(const char *fileName, fiftyoneDegreesDataSet *dataSet, char** properties, int32_t count);
EXTERNAL fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyString(const char *fileName, fiftyoneDegreesDataSet *dataSet, char* properties);
EXTERNAL void fiftyoneDegreesDestroy(const fiftyoneDegreesDataSet *dataSet);
EXTERNAL fiftyoneDegreesWorkset* fiftyoneDegreesCreateWorkset(const fiftyoneDegreesDataSet *dataSet);
EXTERNAL void fiftyoneDegreesFreeWorkset(const fiftyoneDegreesWorkset *ws);
EXTERNAL void fiftyoneDegreesMatch(fiftyoneDegreesWorkset *ws, char* userAgent);
EXTERNAL int32_t fiftyoneDegreesSetValues(fiftyoneDegreesWorkset *ws, int32_t requiredPropertyIndex);
EXTERNAL const fiftyoneDegreesAsciiString* fiftyoneDegreesGetString(const fiftyoneDegreesDataSet *dataSet, int32_t offset);
EXTERNAL const char* fiftyoneDegreesGetValueName(const fiftyoneDegreesDataSet *dataSet, const fiftyoneDegreesValue *value);
EXTERNAL const char* fiftyoneDegreesGetPropertyName(const fiftyoneDegreesDataSet *dataSet, const fiftyoneDegreesProperty *property);
EXTERNAL int32_t fiftyoneDegreesProcessDeviceCSV(fiftyoneDegreesWorkset *ws, char* result, int32_t resultLength);
EXTERNAL int32_t fiftyoneDegreesProcessDeviceJSON(fiftyoneDegreesWorkset *ws, char* result, int32_t resultLength);
#endif // 51DEGREES_H_INCLUDED