# DeviceAtlas Device API C++ # The DeviceAtlas Device Detection API provides a way to detect devices based on the User-Agent HTTP headers. Using the headers, the API returns device information such as screen width, screen height, is mobile, vendor, model etc. To see a full list of properties in DeviceAtlas please visit: https://deviceatlas.com/resources/available-properties . ### Data File ### The DeviceAtlas API relies on a device data file to function. DeviceAtlas provides daily data file updates so it is recommended to download the data file on a regular basis. This can be done manually from your account page or automated via the https://deviceatlas.com/getJSON page. For more information please see: https://deviceatlas.com/resources/getting-the-data ### Dependencies ### This library does not depend on any third party libraries. ### Client-side Component ### In addition to the properties from the data file, properties can be gathered from the client's browser and used both on the client side and on the server side. Please see the Client-side Component readme file for more information. ### Pre-Requirements ### - C/C++ compiler - CMake 2.6 (or above) Following compilers have been tested and are able to compile all components: - GCC/G++ (4.7.x minimum, 4.9 and onwards recommended) - Clang/LLVM (3.0 or above) ** Note ** For Windows users, please see the Windows section for building the API. ### CMake ### CMake should be able to find out all necessary components if you installed them through your package manager. ** ZLIB library and headers ** If your ZLIB library and headers are located in custom locations it is possible to set these cmake environment variables: - ZLIB_LIBRARY=&lt;path to the zlib library&gt; - ZLIB_INCLUDE_DIR=&lt;path to the zlib headers folder&gt; For example: ```shell cmake -ZLIB_LIBRARY=/home/test/zlib/lib/libz.so -DZLIB_INCLUDE_DIR=/home/test/zlib/include ``` ** Custom compiler location ** - CMAKE_C_COMPILER=&lt;full path to the C compiler executable&gt; - CMAKE_CXX_COMPILER=&lt;full path to the C++ compiler&gt; For example: ```shell cmake -DCMAKE_C_COMPILER=/home/test/gcc-4.8.3/bin/gcc -DCMAKE_CXX_COMPILER=/home/test/gcc-4.8.3/bin/g++ ``` NB: For a static API version used with another shared library it is possible to use CFLAGS/CXXFLAGS with -fPIC/fpic compilation flag. ### Building the API ### #### Ubuntu/Debian #### ```shell % sudo apt-get install g++ (or clang) cmake zlib1g-dev ``` #### RedHat/CentOS #### ```shell % sudo dnf install g++ (or clang) cmake zlib-devel ``` #### MacOS #### ```shell % brew install g++ (or clang ; not necessary if clang from XCode is already installed) cmake zlib ``` #### FreeBSD ### ```shell % sudo pkg install cmake (optional) % sudo pkg install gcc<any version> (or llvm<any version>) if another compiler different from the base system is preferred ``` 1. Unpack the API 2. Change to the API directory 3. Run cmake command (Optional) You can set an installation script with cmake -DINSTALL_SCRIPT=(common/redhat/debian/freebsd) * common/debian: will install libraries in /usr/lib and headers in /usr/include (also works for Ubuntu). * redhat: will install libraries in /usr/lib64 in 64bits version (also works for CentOS). * freebsd: will install libraries in /usr/local/lib and headers in /usr/local/include. 4. Run make ``` % tar -zxvf deviceatlas-enterprise-c-{version}.tgz % cd deviceatlas-enterprise-c-{version} % cmake . % make ``` Note: replace {version} with your API version (e.g. 3.1). ### Basic Usage ### #### Example #### The following example code shows the API loading the data file and using a property name to find a certain value for a given User-Agent. ```cpp using namespace com::deviceatlas; const char *dbFile = argv[1]; // DeviceAtlas data file const char *uaString = argv[2]; // User-Agent header. const char *property = argv[3]; // Name of property to retrieve. // Create DeviceAtlas from this database. const char *ucBrowserUa = argv[3]; const char *property = argv[4]; try { da::DeviceAtlas atlas; ... // or initializing with a config class (Optional) ... da::DeviceConfig cfg; cfg.cache_size = 10000; da::DeviceAtlas atlas(cfg); ... atlas.loadDataFromFile(dbFile); HeaderMap map; map["user-agent"] = uaString; map["x-ucbrowser-ua"] = ucBrowserUa; ... HttpHeaders headers(atlas, map); da::DeliveryContext dc(atlas, headers); // [] accessor to get a Value, a null check is required before // attempting to use its data. const Value *value = dc[property]; if (value) std::cout << (std::string)*value << std::endl; // da::DeliveryContext can be also compatible with C++17 // std::string_view type (only available with compilers supporting // C++17). std::string_view property_s{"model"}; Value *value; Value defv; defv.u.strval = "<default model value>"; defv.type = String; ... std::optional<const Value *> p = dc[property_s]; if (p.has_value()) value = p.value(); ... or ... value = p.value_or(&defv); ... // or getting an iterator da::DeliveryContext::const_iterator it = dc.find(property); if (it != dc.end()) std::cout << (std::string)*it->second << std::endl; } catch(std::exception &e) { std::cerr << e.what() << std::endl; } ``` ### Details by class #### da::DeviceAtlas: DeviceAtlas() loadDataFromFile(const char *) Constructed from a file's path containing the JSON data. The C++ std namespace provides streams for files and strings amongst other things. Streams for sockets, etc, are easy to implement. Property The API will only provide you with const instances. Fields are: name: the name of the property type: an enumeration of String, Numeric, or Boolean A reference to a property object is valid only as long as the atlas that created it exists. Value JSON::Type type Field representing the type of the object: Either JSON::String or JSON::Number. Note that because the supplied data contains mismatches between the property types and the values they represent (eg, boolean properties can refer to either string or integer values), both properties and values need separate type fields. std::string toString() Return string representation of the property. long longval(): Return the long integer value of this property. Throws an exception of the value is not an numeric type. const char *strval(): Return the long integer value of this property. Throws an exception of the value is not an numeric type. A reference to a property object is valid only as long as the atlas that created it exists. HttpHeaders Represents the evidence presented to the API to find the properties for a device. Two constructors are available, one taking a const char *, the other taking a map HTTP headername -> HTTP header value. Only the User-Agent field is currently supported. The content of the HttpHeaders object should be considered opaque. It is purely to be presented as a constructor to Da::DeliveryContext DeliveryContext DeliveryContext(const DeviceAtlas &, const HttpHeaders &) Create a delivery context containing properties for the identified device. This object can be queried faster for each property of the specified device than the atlas itself can. begin() and end() provide const iterators over std::pair<const Da::Property *, const Da::Value *> getProperty((const Property & | const char *), (const Value *&|int &|const char *&|bool &)) Get a property from the context, specified by string or Property descriptor. Other than the "Value" returning variant, an exception will be thrown if the assumed type does not match the type of th value refine(const char *) Handles a sum of parameters which must be in this format for example: idevicePixelRatio:1|ideviceAspectRatio:16/70 It will add additional properties and will provide an accurate model name according to client side properties rules. [propertyname] [] property accessor, raises an exception if the key does not exist find(const char *propname) Returns a const_iterator for this property or the end boundary if not found template<typename T> contains(const char *, T) Checks the presence of a property and checks the equality of T value against this property value if found. The T type have to be compatible. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ Copyright (c) DeviceAtlas Limited 2023. All Rights Reserved. _ <!-- HTML+JS for document formatting when opened in browser --> <div class="btn-group" id="main-menu" style="float:right"><a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Menu<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="README.html">Main</a></li><li><a href="README.DeviceApi.html">Device API Usage C</a></li><li><a href="README.ClientHints.html">Client Hints Support</a></li><li><a href="README.CarrierApi.html">Carrier Identification API</a></li><li><a href="README.Upgrade.html">Device API Upgrade</a></li><li class="disabled"><a href="README.Cpp.html">Device API C++</a></li><li><a href="README.Nginx.html">NGINX Module</a></li><li><a href="README.Apache2.html">Apache2 Module</a></li><li><a href="README.JsonConverter.html">Device Identification API C JSONConverter</a></li><li><a href="README.Go-DeviceApi.html">Device API Usage Go</a></li><li><a href="README.Go-Upgrade.html">Device API Upgrade Go</a></li><li><a href="https://docs.deviceatlas.com/apis/clientside/latest/README.ClientSide.html" target="_blank">Client-side component</a></li><li class="divider"></li><li><a href="./ApiDocs/index.html">C ApiDocs</a></li><li><a href="./ApiCppDocs/index.html">C ++ interface ApiDocs</a></li><li><a href="./Go-ApiDocs/carrier.html">Go ApiDocs Carrier</a></li><li><a href="./Go-ApiDocs/device.html">Go ApiDocs Device</a></li></ul></div>