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

Hash/MatchMetrics.cpp

Getting started example of using 51Degrees device detection.

Getting started example of using 51Degrees device detection.The example shows how to:

  1. Specify the name of the data file, properties the data set should be initialised with, and the configuration.
    using namespace FiftyoneDegrees;
    string fileName = "51Degrees-V4.1.hash";
    string propertiesString = "ScreenPixelsWidth,HardwareModel,IsMobile,BrowserName";
    new Common::RequiredPropertiesConfig(&propertiesString);
    new DeviceDetection::Hash::DeviceDetection::Hash::ConfigHash();
    C++ class wrapper for the fiftyoneDegreesPropertiesRequired structure.
    Definition RequiredPropertiesConfig.hpp:59
    C++ class wrapper for the fiftyoneDegreesConfigHash configuration structure.
    Definition ConfigHash.hpp:72
    Hash Device Detection specific classes.
    Definition ComponentMetaDataBuilderHash.hpp:35
    A C++ wrapper class for transform.h conversion routines.
    Definition ComponentMetaDataBuilderHash.hpp:33
  2. Construct a new engine from the specified data file with the required properties and the specified configuration.
    using namespace FiftyoneDegrees;
    dataFilePath,
    config,
    properties);
    Encapsulates the Hash engine class which implements EngineDeviceDetection.
    Definition EngineHash.hpp:96
  3. Create a evidence instance and add a single HTTP User-Agent string to be processed.
    using namespace FiftyoneDegrees;
    evidence->operator[]("header.user-agent") = userAgent;
    Device detection specific evidence class containing evidence to be processed by a device detection en...
    Definition EvidenceDeviceDetection.hpp:64
    Definition GettingStarted.c:67
  4. Process the evidence using the engine to retrieve the values associated with the User-Agent for the selected properties.
    using namespace FiftyoneDegrees;
    DeviceDetection::Hash::DeviceDetection::Hash::ResultsHash *results = engine->process(evidence);
    ResultsHash * process(EvidenceDeviceDetection *evidence) const
  5. Obtain drift: The maximum drift for a matched substring from the character position where it was expected to be found. The maximum drift to allow when finding a match can be set through the configuration structure.
    int drift = results->getDrift();
  6. Obtain difference: The total difference in hash code values between the matched substrings and the actual substrings. The maximum difference to allow when finding a match can be set through the configuration structure.
    int difference = results->getDifference();
  7. Obtain iteration count: The number of iterations required to get the device offset in the devices collection in the graph of nodes. This is indicative of the time taken to fetch the result.
    int iterations = results->getIterations();
  8. Obtain match method: provides information about the algorithm that was used to perform detection for a particular User-Agent. For more information on what each method means please see: How device detection works.
    fiftyoneDegreesHashMatchMethod method = results->getMethod();
    fiftyoneDegreesHashMatchMethod
    DATA STRUCTURES.
    Definition hash.h:127
  9. Obtain the matched User-Agent: the matched substrings in the User-Agent separated with underscored.
    string matchedUserAgent = results->getUserAgent(0);
  10. Release the memory used by the results and the evidence.
    delete results;
    delete evidence;
  11. Finally release the memory used by the engine.
    delete engine;
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2026 51 Degrees Mobile Experts Limited, Davidson House,
* Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
*
* This Original Work is licensed under the European Union Public Licence
* (EUPL) v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */
// Include ExmapleBase.h before others as it includes Windows 'crtdbg.h'
// which requires to be included before 'malloc.h'.
#include "../../C/Hash/ExampleBase.h"
#include "ExampleBase.hpp"
namespace FiftyoneDegrees {
namespace Examples {
namespace Hash {
class MatchMetrics : public ExampleBase {
public:
: ExampleBase(dataFilePath, config)
{};
const char* getMethodString(int method) {
switch (method) {
case FIFTYONE_DEGREES_HASH_MATCH_METHOD_PERFORMANCE:
return "PERFORMANCE";
case FIFTYONE_DEGREES_HASH_MATCH_METHOD_COMBINED:
return "COMBINED";
case FIFTYONE_DEGREES_HASH_MATCH_METHOD_PREDICTIVE:
return "PREDICTIVE";
case FIFTYONE_DEGREES_HASH_MATCH_METHOD_NONE:
default:
return "NONE";
}
}
void run() {
// Create an evidence instance to store and process User-Agents.
EvidenceDeviceDetection *evidence = new EvidenceDeviceDetection();
cout << "Starting Match Metrics Example.\n";
// Carries out a match for a mobile User-Agent.
cout << "\nMobile User-Agent: " <<
mobileUserAgent << "\n";
evidence->operator[]("header.user-agent")
results = engine->process(evidence);
cout <<
" IsMobile: " <<
(*results->getValueAsString("IsMobile")).c_str() << "\n" <<
" Id: " << results->getDeviceId() << "\n" <<
" Drift: " << results->getDrift() << "\n" <<
" Difference: " << results->getDifference() << "\n" <<
" Iterations: " << results->getIterations() << "\n" <<
" Method: " <<
getMethodString(results->getMethod()) << "\n" <<
" Sub Strings: " << results->getUserAgent(0);
delete results;
// Carries out a match for a desktop User-Agent.
cout << "\nDesktop User-Agent: " <<
evidence->operator[]("header.user-agent")
results = engine->process(evidence);
cout <<
" IsMobile: " <<
(*results->getValueAsString("IsMobile")).c_str() << "\n" <<
" Id: " << results->getDeviceId() << "\n" <<
" Drift: " << results->getDrift() << "\n" <<
" Difference: " << results->getDifference() << "\n" <<
" Iterations: " << results->getIterations() << "\n" <<
" Method: " <<
getMethodString(results->getMethod()) << "\n" <<
" Sub Strings: " << results->getUserAgent(0);
delete results;
// Carries out a match for a MediaHub User-Agent.
cout << "\nMediaHub User-Agent: " <<
evidence->operator[]("header.user-agent")
results = engine->process(evidence);
cout <<
" IsMobile: " <<
(*results->getValueAsString("IsMobile")).c_str() << "\n" <<
" Id: " << results->getDeviceId() << "\n" <<
" Drift: " << results->getDrift() << "\n" <<
" Difference: " << results->getDifference() << "\n" <<
" Iterations: " << results->getIterations() << "\n" <<
" Method: " <<
getMethodString(results->getMethod()) << "\n" <<
" Sub Strings: " << results->getUserAgent(0);
delete results;
// Free the evidence.
delete evidence;
}
};
}
}
}
extern "C" void fiftyoneDegreesExampleCPPMatchMetricsRun(ExampleParameters *params) {
// Call the actual function.
try {
MatchMetrics *matchMetrics = new MatchMetrics(
params->dataFilePath, cppConfig);
matchMetrics->run();
delete matchMetrics;
}
catch (const StatusCodeException &e) {
ExampleBase::reportStatus(e.getCode(), params->dataFilePath);
exit(1);
}
}
#ifndef TEST
int main(int argc, char* argv[]) {
char dataFilePath[FIFTYONE_DEGREES_FILE_MAX_PATH];
if (argc > 1) {
strcpy(dataFilePath, argv[1]);
}
else {
dataDir,
dataFileName,
dataFilePath,
sizeof(dataFilePath));
}
ExampleBase::reportStatus(status, dataFileName);
fgetc(stdin);
return 1;
}
ExampleParameters params;
params.dataFilePath = dataFilePath;
// run the example
fiftyoneDegreesExampleMemCheck(
&params,
fiftyoneDegreesExampleCPPMatchMetricsRun);
// Wait for a character to be pressed.
fgetc(stdin);
return 0;
}
#endif
Value< string > getValueAsString(const char *propertyName)
Get a string representation of the value associated with the required property name.
Encapsulates the results of a Hash device detection engine's processing.
Definition ResultsHash.hpp:80
int getDrift() const
Returns the maximum drift for a matched substring from the character position where it was expected t...
int getIterations() const
Get the number of iterations carried out in order to find a match.
string getDeviceId(uint32_t resultIndex) const
Returns the unique device id if the Id property was included in the required list of properties when ...
int getMethod() const
Returns the method used to determine the match result.
int getDifference() const
Returns the total difference between the results returned and the target User-Agents.
string getUserAgent(int resultIndex) const
Returns relevant parts of the User-Agent which most closely matched the target User-Agent if the Conf...
Base class extended by all Hash examples.
Definition ExampleBase.hpp:58
static fiftyoneDegreesStatusCode getFilePath(const char *dataFolderName, const char *fileName, char *destination, size_t size)
Finds a file in the data folder, and downloads it first when it is missing and the data repository li...
EngineHash * engine
Hash Engine used for the example.
Definition ExampleBase.hpp:244
ExampleBase(byte *data, long length, DeviceDetection::Hash::ConfigHash *config)
Construct a new instance of the example to be run using the data pointer provided.
static const char * mobileUserAgent
Example mobile User-Agent string.
Definition ExampleBase.hpp:101
static const char * mediaHubUserAgent
Example media hub User-Agent string.
Definition ExampleBase.hpp:113
static void reportStatus(fiftyoneDegreesStatusCode status, const char *fileName)
Reports the status of the data file initialization.
DeviceDetection::Hash::ConfigHash * config
Configuration for the Engine.
Definition ExampleBase.hpp:240
static const char * desktopUserAgent
Example desktop User-Agent string.
Definition ExampleBase.hpp:104
Match Metrics Hash Example.
Definition MatchMetrics.cpp:134
void run()
Run the example.
Definition MatchMetrics.cpp:160
MatchMetrics(string dataFilePath, DeviceDetection::Hash::ConfigHash *config)
Construct a new instance of the example to be run using the data file provided.
Definition MatchMetrics.cpp:139
#define FIFTYONE_DEGREES_FILE_MAX_PATH
Define the max path length on the target system.
Definition file.h:218
EXTERNAL_VAR fiftyoneDegreesConfigHash fiftyoneDegreesHashDefaultConfig
Default detection configuration.
Definition hash.h:436
fiftyoneDegreesStatusCode
Status returned from the initialisation of a resource.
Definition status.h:81
@ FIFTYONE_DEGREES_STATUS_SUCCESS
All okay.
Definition status.h:82
C++ Hash engine examples.
Definition ExampleBase.hpp:54
C++ Examples.
Definition dd/FiftyoneDegrees.hpp:39
Hash specific configuration structure.
Definition hash.h:187