From 249eb0a6a31a09f6afd072e175566ea9d80bb554 Mon Sep 17 00:00:00 2001 From: Jan Wulkop Date: Fri, 26 May 2017 20:56:31 +0200 Subject: [PATCH] Split hue classes into different header and source files --- hueplusplus/HttpHandler.cpp | 8 ++++---- hueplusplus/HttpHandler.h | 56 -------------------------------------------------------- hueplusplus/Hue.cpp | 14 +++++++++----- hueplusplus/Hue.h | 119 ----------------------------------------------------------------------------------------------------------------------- hueplusplus/HueColorLight.cpp | 490 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/HueDimmableLight.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/HueExtendedColorLight.cpp | 397 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/HueLight.cpp | 1005 ++++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- hueplusplus/HueLight.h | 327 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- hueplusplus/HueTemperatureLight.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/UPnP.cpp | 4 ++-- hueplusplus/UPnP.h | 13 ------------- hueplusplus/include/HttpHandler.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/include/Hue.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/include/HueColorLight.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/include/HueDimmableLight.h | 24 ++++++++++++++++++++++++ hueplusplus/include/HueExtendedColorLight.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/include/HueLight.h | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/include/HueTemperatureLight.h | 31 +++++++++++++++++++++++++++++++ hueplusplus/include/UPnP.h | 13 +++++++++++++ hueplusplus/include/json/json.h | 2139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hueplusplus/json/json.h | 2139 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 22 files changed, 3793 insertions(+), 3666 deletions(-) delete mode 100644 hueplusplus/HttpHandler.h delete mode 100644 hueplusplus/Hue.h create mode 100644 hueplusplus/HueColorLight.cpp create mode 100644 hueplusplus/HueDimmableLight.cpp create mode 100644 hueplusplus/HueExtendedColorLight.cpp delete mode 100644 hueplusplus/HueLight.h create mode 100644 hueplusplus/HueTemperatureLight.cpp delete mode 100644 hueplusplus/UPnP.h create mode 100644 hueplusplus/include/HttpHandler.h create mode 100644 hueplusplus/include/Hue.h create mode 100644 hueplusplus/include/HueColorLight.h create mode 100644 hueplusplus/include/HueDimmableLight.h create mode 100644 hueplusplus/include/HueExtendedColorLight.h create mode 100644 hueplusplus/include/HueLight.h create mode 100644 hueplusplus/include/HueTemperatureLight.h create mode 100644 hueplusplus/include/UPnP.h create mode 100644 hueplusplus/include/json/json.h delete mode 100644 hueplusplus/json/json.h diff --git a/hueplusplus/HttpHandler.cpp b/hueplusplus/HttpHandler.cpp index 189a3d9..c6cb9fc 100644 --- a/hueplusplus/HttpHandler.cpp +++ b/hueplusplus/HttpHandler.cpp @@ -17,7 +17,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ -#include "HttpHandler.h" +#include "include/HttpHandler.h" #include #include #include // printf, sprintf @@ -120,7 +120,7 @@ std::string HttpHandler::sendRequest(const std::string & msg, const std::string std::string HttpHandler::sendRequestGetBody(const std::string & msg, const std::string & adr, int port) { std::string response = sendRequest(msg, adr, port); - unsigned int start = response.find("\r\n\r\n"); + size_t start = response.find("\r\n\r\n"); if (start == std::string::npos) { std::cerr << "Failed to find body in response\n"; @@ -194,7 +194,7 @@ std::vector HttpHandler::sendMulticast(const std::string & msg, con // construct return vector std::vector returnString; - unsigned int pos = response.find("\r\n\r\n"); + size_t pos = response.find("\r\n\r\n"); unsigned int prevpos = 0; while (pos != std::string::npos) { @@ -205,4 +205,4 @@ std::vector HttpHandler::sendMulticast(const std::string & msg, con } return returnString; -} \ No newline at end of file +} diff --git a/hueplusplus/HttpHandler.h b/hueplusplus/HttpHandler.h deleted file mode 100644 index 97e04a2..0000000 --- a/hueplusplus/HttpHandler.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - \file HttpHandler.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -**/ - -#ifndef _HTTPHANDLER_H -#define _HTTPHANDLER_H - -#include -#include - -//! Class to handle http requests and multicast requests -class HttpHandler -{ -public: - //! Function that sends a request to a specific address \ref adr on a specific \ref port. - //! It returns a string containing the answer of the host - //! \param msg String that contains the request that is sent to \ref adr - //! \param adr String that contains an ip or hostname - //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 80 - //! \return String containing the answer of the host - std::string sendRequest(const std::string &msg, const std::string &adr, int port=80); - - //! Function that sends a request to a specific address \ref adr on a specific \ref port. - //! It returns a string containing only the body of the answer of the host - //! \param msg String that contains the request that is sent to \ref adr - //! \param adr String that contains an ip or hostname - //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 80 - //! \return String containing the body of the answer of the host - std::string sendRequestGetBody(const std::string &msg, const std::string &adr, int port = 80); - - //! Function that sends a multicast request to a specific address \ref adr on a specific \ref port with a \ref timeout. - //! It returns a vector containing all answers the multicast request got - //! \param msg String that contains the request that is sent to \ref adr - //! \param adr Optional String that contains an ip or hostname. Standard value is "239.255.255.250" - //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 1900 - //! \param timeout Optional Integer that specifies the timeout of the request in seconds. Standard value is 5 - //! \return Vector containing strings of each answer received - std::vector sendMulticast(const std::string &msg, const std::string &adr = "239.255.255.250", int port = 1900, int timeout = 5); -}; - -#endif \ No newline at end of file diff --git a/hueplusplus/Hue.cpp b/hueplusplus/Hue.cpp index fcc5794..c148601 100644 --- a/hueplusplus/Hue.cpp +++ b/hueplusplus/Hue.cpp @@ -17,11 +17,15 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ -#include "Hue.h" +#include "include/Hue.h" +#include "include/HueLight.h" +#include "include/HueColorLight.h" +#include "include/HueDimmableLight.h" +#include "include/HueExtendedColorLight.h" +#include "include/HueTemperatureLight.h" -#include "HttpHandler.h" -#include "json/json.h" -#include "UPnP.h" +#include "include/HttpHandler.h" +#include "include/UPnP.h" #include #include @@ -44,7 +48,7 @@ std::vector HueFinder::FindBridges() const std::vector foundBridges; for (const std::pair &p : foundDevices) { - unsigned int found = p.second.find("IpBridge"); + size_t found = p.second.find("IpBridge"); if (found != std::string::npos) { HueIdentification bridge; diff --git a/hueplusplus/Hue.h b/hueplusplus/Hue.h deleted file mode 100644 index b5b0e16..0000000 --- a/hueplusplus/Hue.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - \file Hue.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -**/ - -#ifndef _HUE_H -#define _HUE_H - -#include "HueLight.h" - -#include "json/json.h" - -#include -#include -#include -#include -#include - -// forward declarations -class Hue; - -//! Class to find all Hue bridges on the network and create usernames for them. -class HueFinder -{ -public: - struct HueIdentification - { - std::string ip; - std::string mac; - }; -public: - //! Function that finds all bridges in the network and returns them.\n - //! The user should be given the opportunity to select the correct one based on the mac address. - //! \return vector containing ip and mac of all found bridges - std::vector FindBridges() const; - - //! Function that gets a \ref Hue bridge based on its identification - //! \param identification \ref HueIdentification that specifies a bridge - //! \return \ref Hue class object - Hue GetBridge(const HueIdentification& identification); - - //! Function that adds a \ref username to the \ref usernames map - //! \param mac MAC address of Hue bridge - //! \param username Username that is used to control the Hue bridge - void AddUsername(const std::string& mac, const std::string& username); - - //! Function that returns a map of mac addresses and usernames. - //! These should be saved at the end and re-loaded next time, so only one username is generated per bridge. - //! \returns A map mapping mac address to username for every bridge - const std::map& GetAllUsernames() const; -private: - //! Function that sends a username request to the Hue bridge for about 30 seconds, but you have 5 seconds to prepare.\n - //! It returns the username received - //! \param ip String that specifies the ip the request is send to - //! \return String containing username - std::string RequestUsername(const std::string& ip) const; - -private: - std::map usernames; -}; - -//! Hue class -class Hue -{ -public: - //! Constructor of Hue class - //! \param ip String that specifies the ip address of the Hue bridge - //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername - Hue(const std::string& ip, const std::string& username); - - //! Function to get the ip address of the hue bridge - //! \return string containing ip - std::string getBridgeIP(); - - //! Function that sends a username request to the Hue bridge for about 30 seconds, but you have 5 seconds to prepare - //! It automatically sets the \ref username variable according to the username received - //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use - //! \param ip String that specifies the ip the request is send to - void requestUsername(const std::string& ip); - - //! Function that returns the \ref username - //! \return String containing \ref username - std::string getUsername(); - - //! Function to set the ip address of the Hue bridge in this class - //! \param ip String that specifies the ip - void setIP(const std::string ip); - - // todo: some intelligence of finding light - //! Function that returns a \HueLight of specified \ref id - //! \param id Integer that specifies the ID of a Hue light - //! \return \ref HueLight that can be controlled - std::unique_ptr getLight(int id); - -private: - //! Function that refreshes the local \ref state of the Hue bridge - void refreshState(); - -private: - std::string ip; - std::string username; - Json::Value state; -}; - -#endif \ No newline at end of file diff --git a/hueplusplus/HueColorLight.cpp b/hueplusplus/HueColorLight.cpp new file mode 100644 index 0000000..882b43b --- /dev/null +++ b/hueplusplus/HueColorLight.cpp @@ -0,0 +1,490 @@ +/** + \file HueColorLight.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#include "include/HueColorLight.h" + +#include +#include +#include + +bool HueColorLight::setColorHue(uint16_t hue, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + if (transistion != 4) + { + request["transistiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["hue"].asUInt() != hue || state["state"]["colormode"].asString() != "hs") + { + hue = hue % 65535; + request["hue"] = hue; + } + + if (!request.isMember("on") && !request.isMember("hue")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transistiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("hue")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "hue"].asUInt() == request["hue"].asUInt(); + } + return success; +} + +bool HueColorLight::setColorSaturation(uint8_t sat, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + if (transistion != 4) + { + request["transistiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["sat"].asUInt() != sat) + { + if (sat > 254) + { + sat = 254; + } + request["sat"] = sat; + } + + if (!request.isMember("on") && !request.isMember("sat")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transistiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("sat")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "sat"].asUInt() == request["sat"].asUInt(); + } + return success; +} + +bool HueColorLight::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + + if (transistion != 4) + { + request["transitiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["hue"].asUInt() != hue || state["state"]["colormode"].asString() != "hs") + { + hue = hue % 65535; + request["hue"] = hue; + } + if (state["state"]["sat"].asUInt() != sat || state["state"]["colormode"].asString() != "hs") + { + if (sat > 254) + { + sat = 254; + } + request["sat"] = sat; + } + + if (!request.isMember("on") && !request.isMember("hue") && !request.isMember("sat")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transitiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("hue")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "hue"].asUInt() == request["hue"].asUInt(); + ++i; + } + if (success && request.isMember("sat")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "sat"].asUInt() == request["sat"].asUInt(); + } + return success; +} + +bool HueColorLight::setColorXY(float x, float y, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + + if (transistion != 4) + { + request["transitiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["xy"][0].asFloat() != x || state["state"]["xy"][1].asFloat() != y || state["state"]["colormode"].asString() != "xy") + { + request["xy"][0] = x; + request["xy"][1] = y; + } + + if (!request.isMember("on") && !request.isMember("xy")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transitiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("xy")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "xy"][0].asFloat() == request["xy"][0].asFloat(); + if (success) + { + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "xy"][1].asFloat() == request["xy"][1].asFloat(); + } + } + return success; +} + +bool HueColorLight::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transistion) +{ + float red = r / 255; + float green = g / 255; + float blue = b / 255; + + // gamma correction + red = (red > 0.04045f) ? pow((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f); + green = (green > 0.04045f) ? pow((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f); + blue = (blue > 0.04045f) ? pow((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f); + + float X = red * 0.664511f + green * 0.154324f + blue * 0.162028f; + float Y = red * 0.283881f + green * 0.668433f + blue * 0.047685f; + float Z = red * 0.000088f + green * 0.072310f + blue * 0.986039f; + + float x = X / (X + Y + Z); + float y = Y / (X + Y + Z); + + return setColorXY(x, y, transistion); +} + +bool HueColorLight::setColorLoop(bool on) +{ + //colorloop + refreshState(); + Json::Value request(Json::objectValue); + + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + std::string effect; + if ((effect = on ? "colorloop" : "none") != state["state"]["effect"].asString()) + { + request["effect"] = effect; + } + if (!request.isMember("on") && !request.isMember("effect")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("effect")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "effect"].asString() == request["effect"].asString(); + } + return success; +} + +bool HueColorLight::alertHueSaturation(uint16_t hue, uint8_t sat) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else + { + return false; + } +} + +bool HueColorLight::alertXY(float x, float y) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else + { + return false; + } +} + +bool HueColorLight::alertRGB(uint8_t r, uint8_t g, uint8_t b) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else + { + return false; + } +} + +/*bool HueColorLight::pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2) +{ +float A = (-y1 * x2 + y0*(-x1 + x2) + x0*(y1 - y2) + x1 * y1); +int8_t sign = A < 0 ? -1 : 1; +float s = (y0 * x2 - x0 * y2 + (y2 - y0) * pointx + (x0 - x2) * pointy) * sign; +float t = (x0 * y1 - y0 * x1 + (y0 - y1) * pointx + (x1 - x0) * pointy) * sign; + +return s > 0 && t > 0 && (s + t) < A * sign; +}*/ diff --git a/hueplusplus/HueDimmableLight.cpp b/hueplusplus/HueDimmableLight.cpp new file mode 100644 index 0000000..efd0f4d --- /dev/null +++ b/hueplusplus/HueDimmableLight.cpp @@ -0,0 +1,93 @@ +/** + \file HueDimmableLight.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free SofHueDimmableLighttware Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#include "include/HueDimmableLight.h" + +#include +#include +#include + +bool HueDimmableLight::setBrightness(unsigned int bri, uint8_t transistion) +{ + std::cout << "Setting lamp with id: " << id << " to brightness of " << bri << std::endl; + refreshState(); + if (bri == 0) + { + if (state["state"]["on"] == true) + { + return OffNoRefresh(transistion); + } + else + { + return true; + } + } + else + { + Json::Value request(Json::objectValue); + if (transistion != 4) + { + request["transistiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["bri"].asUInt() != bri) + { + bri -= 1; + if (bri > 254) + { + bri = 254; + } + request["bri"] = bri; + } + + if (!request.isMember("on") && !request.isMember("bri")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transistiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("bri")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "bri"].asUInt() == request["bri"].asUInt(); + } + return success; + } +} diff --git a/hueplusplus/HueExtendedColorLight.cpp b/hueplusplus/HueExtendedColorLight.cpp new file mode 100644 index 0000000..b67216d --- /dev/null +++ b/hueplusplus/HueExtendedColorLight.cpp @@ -0,0 +1,397 @@ +/** + \file HueExtendedColorLight.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#include "include/HueExtendedColorLight.h" + +#include +#include +#include + +bool HueExtendedColorLight::setColorTemperature(unsigned int mired, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + if (transistion != 4) + { + request["transitiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["ct"].asUInt() != mired || state["state"]["colormode"].asString() != "ct") + { + if (mired > 500) + { + mired = 500; + } + if (mired < 153) + { + mired = 153; + } + request["ct"] = mired; + } + + if (!request.isMember("on") && !request.isMember("ct")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transitiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("ct")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "ct"].asUInt() == request["ct"].asUInt(); + } + return success; +} + +bool HueExtendedColorLight::alertTemperature(unsigned int mired) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else if (cType == "ct") + { + uint16_t oldCT = state["state"]["ct"].asUInt(); + if (!setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorTemperature(oldCT, 1); + } + } + else + { + return false; + } +} + +bool HueExtendedColorLight::alertHueSaturation(uint16_t hue, uint8_t sat) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else if (cType == "ct") + { + uint16_t oldCT = state["state"]["ct"].asUInt(); + if (!setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorTemperature(oldCT, 1); + } + } + else + { + return false; + } +} + +bool HueExtendedColorLight::alertXY(float x, float y) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else if (cType == "ct") + { + uint16_t oldCT = state["state"]["ct"].asUInt(); + if (!setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorTemperature(oldCT, 1); + } + } + else + { + return false; + } +} + +bool HueExtendedColorLight::alertRGB(uint8_t r, uint8_t g, uint8_t b) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "hs") + { + uint16_t oldHue = state["state"]["hue"].asUInt(); + uint8_t oldSat = state["state"]["sat"].asUInt(); + if (!setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorHueSaturation(oldHue, oldSat, 1); + } + } + else if (cType == "xy") + { + float oldX = state["state"]["xy"][0].asFloat(); + float oldY = state["state"]["xy"][1].asFloat(); + if (!setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorXY(oldX, oldY, 1); + } + } + else if (cType == "ct") + { + uint16_t oldCT = state["state"]["ct"].asUInt(); + if (!setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorTemperature(oldCT, 1); + } + } + else + { + return false; + } +} diff --git a/hueplusplus/HueLight.cpp b/hueplusplus/HueLight.cpp index 34556a1..d88af32 100644 --- a/hueplusplus/HueLight.cpp +++ b/hueplusplus/HueLight.cpp @@ -17,10 +17,11 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ -#include "HueLight.h" +#include "include/HueLight.h" -#include "HttpHandler.h" -#include "json/json.h" + +#include "include/HttpHandler.h" +#include "include/json/json.h" #include #include @@ -210,1001 +211,3 @@ void HueLight::refreshState() } std::cout << "\tRefresh state took: " << std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl; } - -bool HueDimmableLight::setBrightness(unsigned int bri, uint8_t transistion) -{ - std::cout << "Setting lamp with id: " << id << " to brightness of " << bri << std::endl; - refreshState(); - if (bri == 0) - { - if (state["state"]["on"] == true) - { - return OffNoRefresh(transistion); - } - else - { - return true; - } - } - else - { - Json::Value request(Json::objectValue); - if (transistion != 4) - { - request["transistiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["bri"].asUInt() != bri) - { - bri -= 1; - if (bri > 254) - { - bri = 254; - } - request["bri"] = bri; - } - - if (!request.isMember("on") && !request.isMember("bri")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transistiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("bri")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "bri"].asUInt() == request["bri"].asUInt(); - } - return success; - } -} - -bool HueTemperatureLight::setColorTemperature(unsigned int mired, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - if (transistion != 4) - { - request["transistiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["ct"].asUInt() != mired) - { - if (mired > 500) - { - mired = 500; - } - if (mired < 153) - { - mired = 153; - } - request["ct"] = mired; - } - - if (!request.isMember("on") && !request.isMember("ct")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transistiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("ct")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "ct"].asUInt() == request["ct"].asUInt(); - } - return success; -} - -bool HueTemperatureLight::alertTemperature(unsigned int mired) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "ct") - { - uint16_t oldCT = state["state"]["ct"].asUInt(); - if (!setColorTemperature(mired, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorTemperature(oldCT, 1); - } - } - else - { - return false; - } -} - -bool HueColorLight::setColorHue(uint16_t hue, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - if (transistion != 4) - { - request["transistiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["hue"].asUInt() != hue || state["state"]["colormode"].asString() != "hs") - { - hue = hue % 65535; - request["hue"] = hue; - } - - if (!request.isMember("on") && !request.isMember("hue")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transistiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("hue")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "hue"].asUInt() == request["hue"].asUInt(); - } - return success; -} - -bool HueColorLight::setColorSaturation(uint8_t sat, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - if (transistion != 4) - { - request["transistiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["sat"].asUInt() != sat) - { - if (sat > 254) - { - sat = 254; - } - request["sat"] = sat; - } - - if (!request.isMember("on") && !request.isMember("sat")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transistiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("sat")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "sat"].asUInt() == request["sat"].asUInt(); - } - return success; -} - -bool HueColorLight::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - - if (transistion != 4) - { - request["transitiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["hue"].asUInt() != hue || state["state"]["colormode"].asString() != "hs") - { - hue = hue % 65535; - request["hue"] = hue; - } - if (state["state"]["sat"].asUInt() != sat || state["state"]["colormode"].asString() != "hs") - { - if (sat > 254) - { - sat = 254; - } - request["sat"] = sat; - } - - if (!request.isMember("on") && !request.isMember("hue") && !request.isMember("sat")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transitiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("hue")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "hue"].asUInt() == request["hue"].asUInt(); - ++i; - } - if (success && request.isMember("sat")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "sat"].asUInt() == request["sat"].asUInt(); - } - return success; -} - -bool HueColorLight::setColorXY(float x, float y, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - - if (transistion != 4) - { - request["transitiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["xy"][0].asFloat() != x || state["state"]["xy"][1].asFloat() != y || state["state"]["colormode"].asString() != "xy") - { - request["xy"][0] = x; - request["xy"][1] = y; - } - - if (!request.isMember("on") && !request.isMember("xy")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transitiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("xy")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "xy"][0].asFloat() == request["xy"][0].asFloat(); - if (success) - { - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "xy"][1].asFloat() == request["xy"][1].asFloat(); - } - } - return success; -} - -bool HueColorLight::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transistion) -{ - float red = r / 255; - float green = g / 255; - float blue = b / 255; - - // gamma correction - red = (red > 0.04045f) ? pow((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f); - green = (green > 0.04045f) ? pow((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f); - blue = (blue > 0.04045f) ? pow((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f); - - float X = red * 0.664511f + green * 0.154324f + blue * 0.162028f; - float Y = red * 0.283881f + green * 0.668433f + blue * 0.047685f; - float Z = red * 0.000088f + green * 0.072310f + blue * 0.986039f; - - float x = X / (X + Y + Z); - float y = Y / (X + Y + Z); - - return setColorXY(x, y, transistion); -} - -bool HueColorLight::setColorLoop(bool on) -{ - //colorloop - refreshState(); - Json::Value request(Json::objectValue); - - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - std::string effect; - if ((effect = on ? "colorloop" : "none") != state["state"]["effect"].asString()) - { - request["effect"] = effect; - } - if (!request.isMember("on") && !request.isMember("effect")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("effect")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "effect"].asString() == request["effect"].asString(); - } - return success; -} - -bool HueColorLight::alertHueSaturation(uint16_t hue, uint8_t sat) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorHueSaturation(hue, sat, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorHueSaturation(hue, sat, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else - { - return false; - } -} - -bool HueColorLight::alertXY(float x, float y) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorXY(x, y, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorXY(x, y, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else - { - return false; - } -} - -bool HueColorLight::alertRGB(uint8_t r, uint8_t g, uint8_t b) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorRGB(r, g, b, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorRGB(r, g, b, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else - { - return false; - } -} - -/*bool HueColorLight::pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2) -{ -float A = (-y1 * x2 + y0*(-x1 + x2) + x0*(y1 - y2) + x1 * y1); -int8_t sign = A < 0 ? -1 : 1; -float s = (y0 * x2 - x0 * y2 + (y2 - y0) * pointx + (x0 - x2) * pointy) * sign; -float t = (x0 * y1 - y0 * x1 + (y0 - y1) * pointx + (x1 - x0) * pointy) * sign; - -return s > 0 && t > 0 && (s + t) < A * sign; -}*/ - -bool HueExtendedColorLight::setColorTemperature(unsigned int mired, uint8_t transistion) -{ - refreshState(); - Json::Value request(Json::objectValue); - if (transistion != 4) - { - request["transitiontime"] = transistion; - } - if (state["state"]["on"].asBool() != true) - { - request["on"] = true; - } - if (state["state"]["ct"].asUInt() != mired || state["state"]["colormode"].asString() != "ct") - { - if (mired > 500) - { - mired = 500; - } - if (mired < 153) - { - mired = 153; - } - request["ct"] = mired; - } - - if (!request.isMember("on") && !request.isMember("ct")) - { - //Nothing needs to be changed - return true; - } - - Json::Value reply = SendPutRequest(request); - - //Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.isMember("transitiontime")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); - ++i; - } - if (success && request.isMember("on")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); - ++i; - } - if (success && request.isMember("ct")) - { - //Check if success was sent and the value was changed - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "ct"].asUInt() == request["ct"].asUInt(); - } - return success; -} - -bool HueExtendedColorLight::alertTemperature(unsigned int mired) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorTemperature(mired, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorTemperature(mired, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else if (cType == "ct") - { - uint16_t oldCT = state["state"]["ct"].asUInt(); - if (!setColorTemperature(mired, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorTemperature(oldCT, 1); - } - } - else - { - return false; - } -} - -bool HueExtendedColorLight::alertHueSaturation(uint16_t hue, uint8_t sat) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorHueSaturation(hue, sat, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorHueSaturation(hue, sat, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else if (cType == "ct") - { - uint16_t oldCT = state["state"]["ct"].asUInt(); - if (!setColorHueSaturation(hue, sat, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorTemperature(oldCT, 1); - } - } - else - { - return false; - } -} - -bool HueExtendedColorLight::alertXY(float x, float y) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorXY(x, y, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorXY(x, y, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else if (cType == "ct") - { - uint16_t oldCT = state["state"]["ct"].asUInt(); - if (!setColorXY(x, y, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorTemperature(oldCT, 1); - } - } - else - { - return false; - } -} - -bool HueExtendedColorLight::alertRGB(uint8_t r, uint8_t g, uint8_t b) -{ - refreshState(); - std::string cType = state["state"]["colormode"].asString(); - bool on = state["state"]["on"].asBool(); - if (cType == "hs") - { - uint16_t oldHue = state["state"]["hue"].asUInt(); - uint8_t oldSat = state["state"]["sat"].asUInt(); - if (!setColorRGB(r, g, b, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorHueSaturation(oldHue, oldSat, 1); - } - } - else if (cType == "xy") - { - float oldX = state["state"]["xy"][0].asFloat(); - float oldY = state["state"]["xy"][1].asFloat(); - if (!setColorRGB(r, g, b, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorXY(oldX, oldY, 1); - } - } - else if (cType == "ct") - { - uint16_t oldCT = state["state"]["ct"].asUInt(); - if (!setColorRGB(r, g, b, 1)) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(110)); - if (!alert()) - { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - if (!on) - { - return OffNoRefresh(1); - } - else - { - return setColorTemperature(oldCT, 1); - } - } - else - { - return false; - } -} diff --git a/hueplusplus/HueLight.h b/hueplusplus/HueLight.h deleted file mode 100644 index 0887749..0000000 --- a/hueplusplus/HueLight.h +++ /dev/null @@ -1,327 +0,0 @@ -/** - \file HueLight.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -**/ - -#ifndef _HUE_LIGHT_H -#define _HUE_LIGHT_H - -#include "json/json.h" - -/*enum ModelType -{ -UNDEFINED, // undefined model -LCT001, // Hue bulb A19, Color Gamut B, ECL -LCT007, // Hue bulb A19, Color Gamut B, ECL -LCT010, // Hue bulb A19, Color Gamut C, ECL -LCT014, // Hue bulb A19, Color Gamut C, ECL - -LCT002, // Hue Spot BR30, Color Gamut B, ECL -LCT003, // Hue Spot GU10, Color Gamut B, ECL - -LCT011, // Hue BR30, Color Gamut C, ECL - -LST001, // Hue LightStrips, Color Gamut A, CL -LST002, // Hue LightStrips Plus, Color Gamut C, ECL - -LLC010, // Hue Living Colors Iris, Color Gamut A, CL -LLC011, // Hue Living Colors Bloom, Color Gamut A, CL -LLC012, // Hue Living Colors Bloom, Color Gamut A, CL -LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL, NO HUE FRIEND -LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL, NO HUE FRIEND -LLC013, // Disney Living Colors, Color Gamut A, CL - -LWB004, // Hue A19 Lux, Color Gamut -, DL -LWB006, // Hue A19 Lux, Color Gamut -, DL -LWB007, // Hue A19 Lux, Color Gamut -, DL -LWB010, // Hue A19 Lux, Color Gamut -, DL -LWB014, // Hue A19 Lux, Color Gamut -, DL - -LLM001, // Color Light Module, Color Gamut B, ECL -LLM010, // Color Temperature Module, Color Gamut 2200K-6500K, CTL -LLM011, // Color Temperature Module, Color Gamut 2200K-6500K, CTL -LLM012, // Color Temperature Module, Color Gamut 2200K-6500K, CTL - -LTW001, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL -LTW004, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL -LTW013, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL -LTW014, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL - -LLC020 // Hue Go, Color Gamut C, ECL -};*/ - -//! enum that specifies the color type of all Hue lights -enum ColorType -{ - UNDEFINED, //!< ColorType for this light is unknown or undefined - NONE, //!< light has no specific ColorType - GAMUT_A, - GAMUT_B, - GAMUT_C, - TEMPERATURE, - GAMUT_A_TEMPERATURE, - GAMUT_B_TEMPERATURE, - GAMUT_C_TEMPERATURE -}; - -// supports groups, scenes and on/off control -class HueLight -{ - friend class Hue; - -public: - //! virtual std dtor - virtual ~HueLight() = default; - - //! virtual function that turns the light on. - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool On(uint8_t transistion = 4); - - //! virtual function that turns the light off. - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool Off(uint8_t transistion = 4); - - //! Function that lets the light perform one breath cycle. - //! \return Bool that is true on success - virtual bool alert(); - - //! virtual function that returns the name of the light. - //! \return String containig the name of the light - virtual std::string getName(); - - //! Function that converts Kelvin to Mired. - //! \param kelvin Unsigned integer value in Kelvin - //! \return Unsigned integer value in Mired - unsigned int KelvinToMired(unsigned int kelvin); - - //! Function that converts Mired to Kelvin. - //! \param mired Unsigned integer value in Mired - //! \return Unsigned integer value in Kelvin - unsigned int MiredToKelvin(unsigned int mired); - -protected: - //! protected ctor that is used by \ref Hue class. - //! \param ip String that specifies the ip of the Hue bridge - //! \param username String that specifies the username used to control the bridge - //! \param id Integer that specifies the id of this light - HueLight(const std::string& ip, const std::string& username, int id); - - //! virtual function that turns the light on without refreshing its state. - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool OnNoRefresh(uint8_t transistion = 4); - - //! virtual function that turns the light off without refreshing its state. - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool OffNoRefresh(uint8_t transistion = 4); - - //! utility function to send a put request to the light. - //! \throws std::runtime_error if the reply could not be parsed - //! \return The parsed reply - Json::Value SendPutRequest(const Json::Value& request); - - //! virtual function that refreshes the \ref state of the light. - virtual void refreshState(); - -protected: - std::string ip; //!< holds the ip of the light's base - std::string username; //!< holds the username of the light's base - int id; //!< holds the id of the light - Json::Value state; //!< holds the current state of the light updated by \ref refreshState - ColorType colorType; //!< holds the \ref ColorType of the light -}; - -// supports groups, scenes, on/off and dimming -class HueDimmableLight : public HueLight -{ - friend class Hue; - -public: - //! virtual function that sets the brightness of this light. Ranging from 0=off to 255=fully on - //! \param bri Unsigned int that specifies the brightness - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setBrightness(unsigned int bri, uint8_t transistion = 4); - -protected: - //! protected ctor that is used by \ref Hue class. - //! \param ip String that specifies the ip of the Hue bridge - //! \param username String that specifies the username used to control the bridge - //! \param id Integer that specifies the id of this light - HueDimmableLight(const std::string& ip, const std::string& username, int id) : HueLight(ip, username, id) {}; -}; - -// supports groups, scenes, on/off, dimming, and setting of color temperature -class HueTemperatureLight : public HueDimmableLight -{ - friend class Hue; - -public: - //! Fucntion that sets the color temperature of this light in mired. Ranging from 153 to 500 - //! \param mired Unsigned int that specifies the color temperature in Mired - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorTemperature(unsigned int mired, uint8_t transistion = 4); - - //! Function that lets the light perform one breath cycle in specified color temperature. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param mired Color temperature in mired - //! \return Bool that is true on success - bool alertTemperature(unsigned int mired); - -protected: - //! protected ctor that is used by \ref Hue class. - //! \param ip String that specifies the ip of the Hue bridge - //! \param username String that specifies the username used to control the bridge - //! \param id Integer that specifies the id of this light - HueTemperatureLight(const std::string& ip, const std::string& username, int id) : HueDimmableLight(ip, username, id) {}; -}; - -// xy beats ct beats hue/sat. -// supports groups, scenes, on / off, dimming and color control(hue / saturation, enhanced hue, color loop and XY) -class HueColorLight : public HueDimmableLight -{ - friend class Hue; - -public: - //! Function to set the color of this light with specified hue. Ranging from 0 to 65535, whereas 65535 and 0 are red, 25500 is green and 46920 is blue. - //! \param hue uint16_t that specifies the hue - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorHue(uint16_t hue, uint8_t transistion = 4); - - //! Function to set the saturation of color of this light with specified saturation. Ranging from 0 to 254, whereas 0 is least saturated (white) and 254 is most saturated. - //! \param sat uint8_t that specifies the saturation - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorSaturation(uint8_t sat, uint8_t transistion = 4); - - //! Function to set the color of this light with specified hue and saturation. - //! \param hue uint16_t that specifies the hue - //! \param sat uint8_t that specifies the saturation - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms. - //! \return Bool that is true on success - virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition = 4); - - //! Function to set the color of this light in CIE with specified x y. Where x and y are ranging from 0 to 1. - //! \param x float that specifies the x coordinate in CIE - //! \param y float that specifies the y coordinate in CIE - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorXY(float x, float y, uint8_t transistion = 4); - - //! Function to set the color of this light with red green and blue values. Where red, green and blue are ranging from 0 to 255. - //! \param r uint8_t that specifies the red color percentage - //! \param g uint8_t that specifies the green color percentage - //! \param b uint8_t that specifies the blue color percentage - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transistion = 4); - - //! Function to enable colorloop effect. The colorloop effect will loop through all colors on current hue and saturation levels. - //! Notice that none of the setter functions check for this and the colorloop can only be disabled via this function. - //! or by simply calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), - //! so you could alternatively call Off() and then use any of the setter functions - //! \param on bool that enables this feature when true and disables it when false - //! \return Bool that is true on success - virtual bool setColorLoop(bool on); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param hue uint16_t that specifies the hue - //! \param sat uint8_t that specifies the saturation - //! \return Bool that is true on success - bool alertHueSaturation(uint16_t hue, uint8_t sat); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param x float that specifies the x coordinate in CIE - //! \param y float that specifies the y coordinate in CIE - //! \return Bool that is true on success - bool alertXY(float x, float y); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param r uint8_t that specifies the red color percentage - //! \param g uint8_t that specifies the green color percentage - //! \param b uint8_t that specifies the blue color percentage - //! \return Bool that is true on success - bool alertRGB(uint8_t r, uint8_t g, uint8_t b); - -protected: - //! protected ctor that is used by \ref Hue class. - //! \param ip String that specifies the ip of the Hue bridge - //! \param username String that specifies the username used to control the bridge - //! \param id Integer that specifies the id of this light - HueColorLight(const std::string& ip, const std::string& username, int id) : HueDimmableLight(ip, username, id) {}; - - /*private: - bool pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2); // currently unused because Hue bridge handles this*/ -}; - -// supports same as Color light, but which supports additional setting of color temperature -class HueExtendedColorLight : public HueColorLight -{ - friend class Hue; - -public: - //! Fucntion that sets the color temperature of this light in mired. Ranging from 153 to 500. - //! \param mired Unsigned int that specifies the color temperature in Mired - //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - virtual bool setColorTemperature(unsigned int mired, uint8_t transistion = 4); - - //! Function that lets the light perform one breath cycle in specified color temperature. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param mired Color temperature in mired - //! \return Bool that is true on success - bool alertTemperature(unsigned int mired); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param hue uint16_t that specifies the hue - //! \param sat uint8_t that specifies the saturation - //! \return Bool that is true on success - bool alertHueSaturation(uint16_t hue, uint8_t sat); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param x float that specifies the x coordinate in CIE - //! \param y float that specifies the y coordinate in CIE - //! \return Bool that is true on success - bool alertXY(float x, float y); - - //! Function that lets the light perform one breath cycle in specified color. - //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs - //! \param r uint8_t that specifies the red color percentage - //! \param g uint8_t that specifies the green color percentage - //! \param b uint8_t that specifies the blue color percentage - //! \return Bool that is true on success - bool alertRGB(uint8_t r, uint8_t g, uint8_t b); - -protected: - //! protected ctor that is used by \ref Hue class. - //! \param ip String that specifies the ip of the Hue bridge - //! \param username String that specifies the username used to control the bridge - //! \param id Integer that specifies the id of this light - HueExtendedColorLight(const std::string& ip, const std::string& username, int id) : HueColorLight(ip, username, id) {}; -}; - -#endif \ No newline at end of file diff --git a/hueplusplus/HueTemperatureLight.cpp b/hueplusplus/HueTemperatureLight.cpp new file mode 100644 index 0000000..b37a8f7 --- /dev/null +++ b/hueplusplus/HueTemperatureLight.cpp @@ -0,0 +1,116 @@ +/** + \file HueTemperatureLight.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#include "include/HueTemperatureLight.h" + +#include +#include +#include + + +bool HueTemperatureLight::setColorTemperature(unsigned int mired, uint8_t transistion) +{ + refreshState(); + Json::Value request(Json::objectValue); + if (transistion != 4) + { + request["transistiontime"] = transistion; + } + if (state["state"]["on"].asBool() != true) + { + request["on"] = true; + } + if (state["state"]["ct"].asUInt() != mired) + { + if (mired > 500) + { + mired = 500; + } + if (mired < 153) + { + mired = 153; + } + request["ct"] = mired; + } + + if (!request.isMember("on") && !request.isMember("ct")) + { + //Nothing needs to be changed + return true; + } + + Json::Value reply = SendPutRequest(request); + + //Check whether request was successful + std::string path = "/lights/" + std::to_string(id) + "/state/"; + bool success = true; + int i = 0; + if (success && request.isMember("transistiontime")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transistiontime"].asUInt() == request["transistiontime"].asUInt(); + ++i; + } + if (success && request.isMember("on")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); + ++i; + } + if (success && request.isMember("ct")) + { + //Check if success was sent and the value was changed + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "ct"].asUInt() == request["ct"].asUInt(); + } + return success; +} + +bool HueTemperatureLight::alertTemperature(unsigned int mired) +{ + refreshState(); + std::string cType = state["state"]["colormode"].asString(); + bool on = state["state"]["on"].asBool(); + if (cType == "ct") + { + uint16_t oldCT = state["state"]["ct"].asUInt(); + if (!setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(110)); + if (!alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + if (!on) + { + return OffNoRefresh(1); + } + else + { + return setColorTemperature(oldCT, 1); + } + } + else + { + return false; + } +} + diff --git a/hueplusplus/UPnP.cpp b/hueplusplus/UPnP.cpp index 39d3bac..32140df 100644 --- a/hueplusplus/UPnP.cpp +++ b/hueplusplus/UPnP.cpp @@ -1,5 +1,5 @@ -#include "UPnP.h" -#include "HttpHandler.h" +#include "include/UPnP.h" +#include "include/HttpHandler.h" #include #include diff --git a/hueplusplus/UPnP.h b/hueplusplus/UPnP.h deleted file mode 100644 index ad60297..0000000 --- a/hueplusplus/UPnP.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _UPNP_H -#define _UPNP_H - -#include -#include - -class UPnP -{ -public: - std::vector> getDevices(); -}; - -#endif \ No newline at end of file diff --git a/hueplusplus/include/HttpHandler.h b/hueplusplus/include/HttpHandler.h new file mode 100644 index 0000000..97e04a2 --- /dev/null +++ b/hueplusplus/include/HttpHandler.h @@ -0,0 +1,56 @@ +/** + \file HttpHandler.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#ifndef _HTTPHANDLER_H +#define _HTTPHANDLER_H + +#include +#include + +//! Class to handle http requests and multicast requests +class HttpHandler +{ +public: + //! Function that sends a request to a specific address \ref adr on a specific \ref port. + //! It returns a string containing the answer of the host + //! \param msg String that contains the request that is sent to \ref adr + //! \param adr String that contains an ip or hostname + //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 80 + //! \return String containing the answer of the host + std::string sendRequest(const std::string &msg, const std::string &adr, int port=80); + + //! Function that sends a request to a specific address \ref adr on a specific \ref port. + //! It returns a string containing only the body of the answer of the host + //! \param msg String that contains the request that is sent to \ref adr + //! \param adr String that contains an ip or hostname + //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 80 + //! \return String containing the body of the answer of the host + std::string sendRequestGetBody(const std::string &msg, const std::string &adr, int port = 80); + + //! Function that sends a multicast request to a specific address \ref adr on a specific \ref port with a \ref timeout. + //! It returns a vector containing all answers the multicast request got + //! \param msg String that contains the request that is sent to \ref adr + //! \param adr Optional String that contains an ip or hostname. Standard value is "239.255.255.250" + //! \param port Optional Integer that specifies the port to which the request is sent. Standard value is 1900 + //! \param timeout Optional Integer that specifies the timeout of the request in seconds. Standard value is 5 + //! \return Vector containing strings of each answer received + std::vector sendMulticast(const std::string &msg, const std::string &adr = "239.255.255.250", int port = 1900, int timeout = 5); +}; + +#endif \ No newline at end of file diff --git a/hueplusplus/include/Hue.h b/hueplusplus/include/Hue.h new file mode 100644 index 0000000..b5b0e16 --- /dev/null +++ b/hueplusplus/include/Hue.h @@ -0,0 +1,119 @@ +/** + \file Hue.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#ifndef _HUE_H +#define _HUE_H + +#include "HueLight.h" + +#include "json/json.h" + +#include +#include +#include +#include +#include + +// forward declarations +class Hue; + +//! Class to find all Hue bridges on the network and create usernames for them. +class HueFinder +{ +public: + struct HueIdentification + { + std::string ip; + std::string mac; + }; +public: + //! Function that finds all bridges in the network and returns them.\n + //! The user should be given the opportunity to select the correct one based on the mac address. + //! \return vector containing ip and mac of all found bridges + std::vector FindBridges() const; + + //! Function that gets a \ref Hue bridge based on its identification + //! \param identification \ref HueIdentification that specifies a bridge + //! \return \ref Hue class object + Hue GetBridge(const HueIdentification& identification); + + //! Function that adds a \ref username to the \ref usernames map + //! \param mac MAC address of Hue bridge + //! \param username Username that is used to control the Hue bridge + void AddUsername(const std::string& mac, const std::string& username); + + //! Function that returns a map of mac addresses and usernames. + //! These should be saved at the end and re-loaded next time, so only one username is generated per bridge. + //! \returns A map mapping mac address to username for every bridge + const std::map& GetAllUsernames() const; +private: + //! Function that sends a username request to the Hue bridge for about 30 seconds, but you have 5 seconds to prepare.\n + //! It returns the username received + //! \param ip String that specifies the ip the request is send to + //! \return String containing username + std::string RequestUsername(const std::string& ip) const; + +private: + std::map usernames; +}; + +//! Hue class +class Hue +{ +public: + //! Constructor of Hue class + //! \param ip String that specifies the ip address of the Hue bridge + //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername + Hue(const std::string& ip, const std::string& username); + + //! Function to get the ip address of the hue bridge + //! \return string containing ip + std::string getBridgeIP(); + + //! Function that sends a username request to the Hue bridge for about 30 seconds, but you have 5 seconds to prepare + //! It automatically sets the \ref username variable according to the username received + //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use + //! \param ip String that specifies the ip the request is send to + void requestUsername(const std::string& ip); + + //! Function that returns the \ref username + //! \return String containing \ref username + std::string getUsername(); + + //! Function to set the ip address of the Hue bridge in this class + //! \param ip String that specifies the ip + void setIP(const std::string ip); + + // todo: some intelligence of finding light + //! Function that returns a \HueLight of specified \ref id + //! \param id Integer that specifies the ID of a Hue light + //! \return \ref HueLight that can be controlled + std::unique_ptr getLight(int id); + +private: + //! Function that refreshes the local \ref state of the Hue bridge + void refreshState(); + +private: + std::string ip; + std::string username; + Json::Value state; +}; + +#endif \ No newline at end of file diff --git a/hueplusplus/include/HueColorLight.h b/hueplusplus/include/HueColorLight.h new file mode 100644 index 0000000..07020a5 --- /dev/null +++ b/hueplusplus/include/HueColorLight.h @@ -0,0 +1,87 @@ +#ifndef _HUE_COLOR_LIGHT +#define _HUE_COLOR_LIGHT + +#include "HueDimmableLight.h" + +// xy beats ct beats hue/sat. +// supports groups, scenes, on / off, dimming and color control(hue / saturation, enhanced hue, color loop and XY) +class HueColorLight : public HueDimmableLight +{ + friend class Hue; + +public: + //! Function to set the color of this light with specified hue. Ranging from 0 to 65535, whereas 65535 and 0 are red, 25500 is green and 46920 is blue. + //! \param hue uint16_t that specifies the hue + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorHue(uint16_t hue, uint8_t transistion = 4); + + //! Function to set the saturation of color of this light with specified saturation. Ranging from 0 to 254, whereas 0 is least saturated (white) and 254 is most saturated. + //! \param sat uint8_t that specifies the saturation + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorSaturation(uint8_t sat, uint8_t transistion = 4); + + //! Function to set the color of this light with specified hue and saturation. + //! \param hue uint16_t that specifies the hue + //! \param sat uint8_t that specifies the saturation + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms. + //! \return Bool that is true on success + virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition = 4); + + //! Function to set the color of this light in CIE with specified x y. Where x and y are ranging from 0 to 1. + //! \param x float that specifies the x coordinate in CIE + //! \param y float that specifies the y coordinate in CIE + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorXY(float x, float y, uint8_t transistion = 4); + + //! Function to set the color of this light with red green and blue values. Where red, green and blue are ranging from 0 to 255. + //! \param r uint8_t that specifies the red color percentage + //! \param g uint8_t that specifies the green color percentage + //! \param b uint8_t that specifies the blue color percentage + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transistion = 4); + + //! Function to enable colorloop effect. The colorloop effect will loop through all colors on current hue and saturation levels. + //! Notice that none of the setter functions check for this and the colorloop can only be disabled via this function. + //! or by simply calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), + //! so you could alternatively call Off() and then use any of the setter functions + //! \param on bool that enables this feature when true and disables it when false + //! \return Bool that is true on success + virtual bool setColorLoop(bool on); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param hue uint16_t that specifies the hue + //! \param sat uint8_t that specifies the saturation + //! \return Bool that is true on success + bool alertHueSaturation(uint16_t hue, uint8_t sat); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param x float that specifies the x coordinate in CIE + //! \param y float that specifies the y coordinate in CIE + //! \return Bool that is true on success + bool alertXY(float x, float y); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param r uint8_t that specifies the red color percentage + //! \param g uint8_t that specifies the green color percentage + //! \param b uint8_t that specifies the blue color percentage + //! \return Bool that is true on success + bool alertRGB(uint8_t r, uint8_t g, uint8_t b); + +protected: + //! protected ctor that is used by \ref Hue class. + //! \param ip String that specifies the ip of the Hue bridge + //! \param username String that specifies the username used to control the bridge + //! \param id Integer that specifies the id of this light + HueColorLight(const std::string& ip, const std::string& username, int id) : HueDimmableLight(ip, username, id) {}; + + /*private: + bool pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2); // currently unused because Hue bridge handles this*/ +}; +#endif diff --git a/hueplusplus/include/HueDimmableLight.h b/hueplusplus/include/HueDimmableLight.h new file mode 100644 index 0000000..8d67cdb --- /dev/null +++ b/hueplusplus/include/HueDimmableLight.h @@ -0,0 +1,24 @@ +#ifndef _HUE_DIMMABLE_LIGHT_H +#define _HUE_DIMMABLE_LIGHT_H +#include "HueLight.h" + +// supports groups, scenes, on/off and dimming +class HueDimmableLight : public HueLight +{ + friend class Hue; + +public: + //! virtual function that sets the brightness of this light. Ranging from 0=off to 255=fully on + //! \param bri Unsigned int that specifies the brightness + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setBrightness(unsigned int bri, uint8_t transistion = 4); + +protected: + //! protected ctor that is used by \ref Hue class. + //! \param ip String that specifies the ip of the Hue bridge + //! \param username String that specifies the username used to control the bridge + //! \param id Integer that specifies the id of this light + HueDimmableLight(const std::string& ip, const std::string& username, int id) : HueLight(ip, username, id) {}; +}; +#endif diff --git a/hueplusplus/include/HueExtendedColorLight.h b/hueplusplus/include/HueExtendedColorLight.h new file mode 100644 index 0000000..3d8eece --- /dev/null +++ b/hueplusplus/include/HueExtendedColorLight.h @@ -0,0 +1,52 @@ +#ifndef _HUE_EXTENDED_COLOR_LIGHT +#define _HUE_EXTENDED_COLOR_LIGHT + +#include "HueColorLight.h" +// supports same as Color light, but which supports additional setting of color temperature +class HueExtendedColorLight : public HueColorLight +{ + friend class Hue; + +public: + //! Fucntion that sets the color temperature of this light in mired. Ranging from 153 to 500. + //! \param mired Unsigned int that specifies the color temperature in Mired + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorTemperature(unsigned int mired, uint8_t transistion = 4); + + //! Function that lets the light perform one breath cycle in specified color temperature. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param mired Color temperature in mired + //! \return Bool that is true on success + bool alertTemperature(unsigned int mired); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param hue uint16_t that specifies the hue + //! \param sat uint8_t that specifies the saturation + //! \return Bool that is true on success + bool alertHueSaturation(uint16_t hue, uint8_t sat); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param x float that specifies the x coordinate in CIE + //! \param y float that specifies the y coordinate in CIE + //! \return Bool that is true on success + bool alertXY(float x, float y); + + //! Function that lets the light perform one breath cycle in specified color. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param r uint8_t that specifies the red color percentage + //! \param g uint8_t that specifies the green color percentage + //! \param b uint8_t that specifies the blue color percentage + //! \return Bool that is true on success + bool alertRGB(uint8_t r, uint8_t g, uint8_t b); + +protected: + //! protected ctor that is used by \ref Hue class. + //! \param ip String that specifies the ip of the Hue bridge + //! \param username String that specifies the username used to control the bridge + //! \param id Integer that specifies the id of this light + HueExtendedColorLight(const std::string& ip, const std::string& username, int id) : HueColorLight(ip, username, id) {}; +}; +#endif diff --git a/hueplusplus/include/HueLight.h b/hueplusplus/include/HueLight.h new file mode 100644 index 0000000..a222c60 --- /dev/null +++ b/hueplusplus/include/HueLight.h @@ -0,0 +1,157 @@ +/** + \file HueLight.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#ifndef _HUE_LIGHT_H +#define _HUE_LIGHT_H + +#include "json/json.h" + +/*enum ModelType +{ +UNDEFINED, // undefined model +LCT001, // Hue bulb A19, Color Gamut B, ECL +LCT007, // Hue bulb A19, Color Gamut B, ECL +LCT010, // Hue bulb A19, Color Gamut C, ECL +LCT014, // Hue bulb A19, Color Gamut C, ECL + +LCT002, // Hue Spot BR30, Color Gamut B, ECL +LCT003, // Hue Spot GU10, Color Gamut B, ECL + +LCT011, // Hue BR30, Color Gamut C, ECL + +LST001, // Hue LightStrips, Color Gamut A, CL +LST002, // Hue LightStrips Plus, Color Gamut C, ECL + +LLC010, // Hue Living Colors Iris, Color Gamut A, CL +LLC011, // Hue Living Colors Bloom, Color Gamut A, CL +LLC012, // Hue Living Colors Bloom, Color Gamut A, CL +LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL, NO HUE FRIEND +LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL, NO HUE FRIEND +LLC013, // Disney Living Colors, Color Gamut A, CL + +LWB004, // Hue A19 Lux, Color Gamut -, DL +LWB006, // Hue A19 Lux, Color Gamut -, DL +LWB007, // Hue A19 Lux, Color Gamut -, DL +LWB010, // Hue A19 Lux, Color Gamut -, DL +LWB014, // Hue A19 Lux, Color Gamut -, DL + +LLM001, // Color Light Module, Color Gamut B, ECL +LLM010, // Color Temperature Module, Color Gamut 2200K-6500K, CTL +LLM011, // Color Temperature Module, Color Gamut 2200K-6500K, CTL +LLM012, // Color Temperature Module, Color Gamut 2200K-6500K, CTL + +LTW001, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL +LTW004, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL +LTW013, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL +LTW014, // Hue Spot BR30, Color Gamut 2200K-6500K, CTL + +LLC020 // Hue Go, Color Gamut C, ECL +};*/ + +//! enum that specifies the color type of all Hue lights +enum ColorType +{ + UNDEFINED, //!< ColorType for this light is unknown or undefined + NONE, //!< light has no specific ColorType + GAMUT_A, + GAMUT_B, + GAMUT_C, + TEMPERATURE, + GAMUT_A_TEMPERATURE, + GAMUT_B_TEMPERATURE, + GAMUT_C_TEMPERATURE +}; + +// supports groups, scenes and on/off control +class HueLight +{ + friend class Hue; + +public: + //! virtual std dtor + virtual ~HueLight() = default; + + //! virtual function that turns the light on. + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool On(uint8_t transistion = 4); + + //! virtual function that turns the light off. + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool Off(uint8_t transistion = 4); + + //! Function that lets the light perform one breath cycle. + //! \return Bool that is true on success + virtual bool alert(); + + //! virtual function that returns the name of the light. + //! \return String containig the name of the light + virtual std::string getName(); + + //! Function that converts Kelvin to Mired. + //! \param kelvin Unsigned integer value in Kelvin + //! \return Unsigned integer value in Mired + unsigned int KelvinToMired(unsigned int kelvin); + + //! Function that converts Mired to Kelvin. + //! \param mired Unsigned integer value in Mired + //! \return Unsigned integer value in Kelvin + unsigned int MiredToKelvin(unsigned int mired); + +protected: + //! protected ctor that is used by \ref Hue class. + //! \param ip String that specifies the ip of the Hue bridge + //! \param username String that specifies the username used to control the bridge + //! \param id Integer that specifies the id of this light + HueLight(const std::string& ip, const std::string& username, int id); + + //! virtual function that turns the light on without refreshing its state. + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool OnNoRefresh(uint8_t transistion = 4); + + //! virtual function that turns the light off without refreshing its state. + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool OffNoRefresh(uint8_t transistion = 4); + + //! utility function to send a put request to the light. + //! \throws std::runtime_error if the reply could not be parsed + //! \return The parsed reply + Json::Value SendPutRequest(const Json::Value& request); + + //! virtual function that refreshes the \ref state of the light. + virtual void refreshState(); + +protected: + std::string ip; //!< holds the ip of the light's base + std::string username; //!< holds the username of the light's base + int id; //!< holds the id of the light + Json::Value state; //!< holds the current state of the light updated by \ref refreshState + ColorType colorType; //!< holds the \ref ColorType of the light +}; + + + + + + + +#endif diff --git a/hueplusplus/include/HueTemperatureLight.h b/hueplusplus/include/HueTemperatureLight.h new file mode 100644 index 0000000..74287a5 --- /dev/null +++ b/hueplusplus/include/HueTemperatureLight.h @@ -0,0 +1,31 @@ +#ifndef _HUE_TEMPAERATURE_LIGHT +#define _HUE_TEMPAERATURE_LIGHT + +#include "HueDimmableLight.h" + +// supports groups, scenes, on/off, dimming, and setting of color temperature +class HueTemperatureLight : public HueDimmableLight +{ + friend class Hue; + +public: + //! Fucntion that sets the color temperature of this light in mired. Ranging from 153 to 500 + //! \param mired Unsigned int that specifies the color temperature in Mired + //! \param transistion Optional parameter to set the transition from current state to new standard is 4 = 400ms + //! \return Bool that is true on success + virtual bool setColorTemperature(unsigned int mired, uint8_t transistion = 4); + + //! Function that lets the light perform one breath cycle in specified color temperature. + //! It uses this_thread::sleep_for to accomodate for the time an \ref alert() needs + //! \param mired Color temperature in mired + //! \return Bool that is true on success + bool alertTemperature(unsigned int mired); + +protected: + //! protected ctor that is used by \ref Hue class. + //! \param ip String that specifies the ip of the Hue bridge + //! \param username String that specifies the username used to control the bridge + //! \param id Integer that specifies the id of this light + HueTemperatureLight(const std::string& ip, const std::string& username, int id) : HueDimmableLight(ip, username, id) {}; +}; +#endif diff --git a/hueplusplus/include/UPnP.h b/hueplusplus/include/UPnP.h new file mode 100644 index 0000000..ad60297 --- /dev/null +++ b/hueplusplus/include/UPnP.h @@ -0,0 +1,13 @@ +#ifndef _UPNP_H +#define _UPNP_H + +#include +#include + +class UPnP +{ +public: + std::vector> getDevices(); +}; + +#endif \ No newline at end of file diff --git a/hueplusplus/include/json/json.h b/hueplusplus/include/json/json.h new file mode 100644 index 0000000..94a1e2f --- /dev/null +++ b/hueplusplus/include/json/json.h @@ -0,0 +1,2139 @@ +/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json.h" + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_AMALGATED_H_INCLUDED +# define JSON_AMALGATED_H_INCLUDED +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + +// DO NOT EDIT. This file (and "version") is generated by CMake. +// Run CMake configure step to update it. +#ifndef JSON_VERSION_H_INCLUDED +# define JSON_VERSION_H_INCLUDED + +# define JSONCPP_VERSION_STRING "1.7.4" +# define JSONCPP_VERSION_MAJOR 1 +# define JSONCPP_VERSION_MINOR 7 +# define JSONCPP_VERSION_PATCH 4 +# define JSONCPP_VERSION_QUALIFIER +# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY 0 +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED +#include +#include //typdef String + +/// If defined, indicates that json library is embedded in CppTL library. +//# define JSON_IN_CPPTL 1 + +/// If defined, indicates that json may leverage CppTL library +//# define JSON_USE_CPPTL 1 +/// If defined, indicates that cpptl vector based map should be used instead of +/// std::map +/// as Value container. +//# define JSON_USE_CPPTL_SMALLMAP 1 + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgated header. +// #define JSON_IS_AMALGAMATION + +#ifdef JSON_IN_CPPTL +#include +#ifndef JSON_USE_CPPTL +#define JSON_USE_CPPTL 1 +#endif +#endif + +#ifdef JSON_IN_CPPTL +#define JSON_API CPPTL_API +#elif defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#elif defined(JSON_DLL) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_IN_CPPTL +#if !defined(JSON_API) +#define JSON_API +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +#if defined(_MSC_VER) // MSVC +# if _MSC_VER <= 1200 // MSVC 6 + // Microsoft Visual Studio 6 only support conversion from __int64 to double + // (no conversion from unsigned __int64). +# define JSON_USE_INT64_DOUBLE_CONVERSION 1 + // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' + // characters in the debug information) + // All projects I've ever seen with VS6 were using this globally (not bothering + // with pragma push/pop). +# pragma warning(disable : 4786) +# endif // MSVC 6 + +# if _MSC_VER >= 1500 // MSVC 2008 + /// Indicates that the following function is deprecated. +# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +# endif + +#endif // defined(_MSC_VER) + +// In c++11 the override keyword allows you to explicity define that a function +// is intended to override the base-class version. This makes the code more +// managable and fixes a set of common hard-to-find bugs. +#if __cplusplus >= 201103L +# define JSONCPP_OVERRIDE override +#elif defined(_MSC_VER) && _MSC_VER > 1600 +# define JSONCPP_OVERRIDE override +#else +# define JSONCPP_OVERRIDE +#endif + +#ifndef JSON_HAS_RVALUE_REFERENCES + +#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 +#define JSON_HAS_RVALUE_REFERENCES 1 +#endif // MSVC >= 2010 + +#ifdef __clang__ +#if __has_feature(cxx_rvalue_references) +#define JSON_HAS_RVALUE_REFERENCES 1 +#endif // has_feature + +#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +#define JSON_HAS_RVALUE_REFERENCES 1 +#endif // GXX_EXPERIMENTAL + +#endif // __clang__ || __GNUC__ + +#endif // not defined JSON_HAS_RVALUE_REFERENCES + +#ifndef JSON_HAS_RVALUE_REFERENCES +#define JSON_HAS_RVALUE_REFERENCES 0 +#endif + +#ifdef __clang__ +#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) +# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) +# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +# endif // GNUC version +#endif // __clang__ || __GNUC__ + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +#if __GNUC__ >= 6 +# define JSON_USE_INT64_DOUBLE_CONVERSION 1 +#endif + +#if !defined(JSON_IS_AMALGAMATION) + +# include "version.h" + +# if JSONCPP_USING_SECURE_MEMORY +# include "allocator.h" //typedef Allocator +# endif + +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { +typedef int Int; +typedef unsigned int UInt; +#if defined(JSON_NO_INT64) +typedef int LargestInt; +typedef unsigned int LargestUInt; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else // if defined(_MSC_VER) // Other platforms, use long long +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif // if defined(_MSC_VER) +typedef Int64 LargestInt; +typedef UInt64 LargestUInt; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) +#if JSONCPP_USING_SECURE_MEMORY +#define JSONCPP_STRING std::basic_string, Json::SecureAllocator > +#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > +#define JSONCPP_OSTREAM std::basic_ostream> +#define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > +#define JSONCPP_ISTREAM std::istream +#else +#define JSONCPP_STRING std::string +#define JSONCPP_OSTRINGSTREAM std::ostringstream +#define JSONCPP_OSTREAM std::ostream +#define JSONCPP_ISTRINGSTREAM std::istringstream +#define JSONCPP_ISTREAM std::istream +#endif // if JSONCPP_USING_SECURE_MEMORY +} // end namespace Json + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class FastWriter; +class StyledWriter; + +// reader.h +class Reader; + +// features.h +class Features; + +// value.h +typedef unsigned int ArrayIndex; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/features.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_FEATURES_H_INCLUDED +#define CPPTL_JSON_FEATURES_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +/** \brief Configuration passed to reader and writer. + * This configuration object can be used to force the Reader or Writer + * to behave in a standard conforming way. + */ +class JSON_API Features { +public: + /** \brief A configuration that allows all features and assumes all strings + * are UTF-8. + * - C & C++ comments are allowed + * - Root object can be any JSON value + * - Assumes Value strings are encoded in UTF-8 + */ + static Features all(); + + /** \brief A configuration that is strictly compatible with the JSON + * specification. + * - Comments are forbidden. + * - Root object must be either an array or an object value. + * - Assumes Value strings are encoded in UTF-8 + */ + static Features strictMode(); + + /** \brief Initialize the configuration like JsonConfig::allFeatures; + */ + Features(); + + /// \c true if comments are allowed. Default: \c true. + bool allowComments_; + + /// \c true if root must be either an array or an object value. Default: \c + /// false. + bool strictRoot_; + + /// \c true if dropped null placeholders are allowed. Default: \c false. + bool allowDroppedNullPlaceholders_; + + /// \c true if numeric object key are allowed. Default: \c false. + bool allowNumericKeys_; +}; + +} // namespace Json + +#endif // CPPTL_JSON_FEATURES_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/features.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_H_INCLUDED +#define CPPTL_JSON_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include + +#ifndef JSON_USE_CPPTL_SMALLMAP +#include +#else +#include +#endif +#ifdef JSON_USE_CPPTL +#include +#endif + +//Conditional NORETURN attribute on the throw functions would: +// a) suppress false positives from static code analysis +// b) possibly improve optimization opportunities. +#if !defined(JSONCPP_NORETURN) +# if defined(_MSC_VER) +# define JSONCPP_NORETURN __declspec(noreturn) +# elif defined(__GNUC__) +# define JSONCPP_NORETURN __attribute__ ((__noreturn__)) +# else +# define JSONCPP_NORETURN +# endif +#endif + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +/** \brief JSON (JavaScript Object Notation). + */ +namespace Json { + +/** Base class for all exceptions we throw. + * + * We use nothing but these internally. Of course, STL can throw others. + */ +class JSON_API Exception : public std::exception { +public: + Exception(JSONCPP_STRING const& msg); + ~Exception() throw() JSONCPP_OVERRIDE; + char const* what() const throw() JSONCPP_OVERRIDE; +protected: + JSONCPP_STRING msg_; +}; + +/** Exceptions which the user cannot easily avoid. + * + * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input + * + * \remark derived from Json::Exception + */ +class JSON_API RuntimeError : public Exception { +public: + RuntimeError(JSONCPP_STRING const& msg); +}; + +/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. + * + * These are precondition-violations (user bugs) and internal errors (our bugs). + * + * \remark derived from Json::Exception + */ +class JSON_API LogicError : public Exception { +public: + LogicError(JSONCPP_STRING const& msg); +}; + +/// used internally +JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg); +/// used internally +JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg); + +/** \brief Type of the value held by a Value object. + */ +enum ValueType { + nullValue = 0, ///< 'null' value + intValue, ///< signed integer value + uintValue, ///< unsigned integer value + realValue, ///< double value + stringValue, ///< UTF-8 string value + booleanValue, ///< bool value + arrayValue, ///< array value (ordered list) + objectValue ///< object value (collection of name/value pairs). +}; + +enum CommentPlacement { + commentBefore = 0, ///< a comment placed on the line before a value + commentAfterOnSameLine, ///< a comment just after a value on the same line + commentAfter, ///< a comment on the line after a value (only make sense for + /// root value) + numberOfCommentPlacement +}; + +//# ifdef JSON_USE_CPPTL +// typedef CppTL::AnyEnumerator EnumMemberNames; +// typedef CppTL::AnyEnumerator EnumValues; +//# endif + +/** \brief Lightweight wrapper to tag static string. + * + * Value constructor and objectValue member assignement takes advantage of the + * StaticString and avoid the cost of string duplication when storing the + * string or the member name. + * + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ +class JSON_API StaticString { +public: + explicit StaticString(const char* czstring) : c_str_(czstring) {} + + operator const char*() const { return c_str_; } + + const char* c_str() const { return c_str_; } + +private: + const char* c_str_; +}; + +/** \brief Represents a JSON value. + * + * This class is a discriminated union wrapper that can represents a: + * - signed integer [range: Value::minInt - Value::maxInt] + * - unsigned integer (range: 0 - Value::maxUInt) + * - double + * - UTF-8 string + * - boolean + * - 'null' + * - an ordered list of Value + * - collection of name/value pairs (javascript object) + * + * The type of the held value is represented by a #ValueType and + * can be obtained using type(). + * + * Values of an #objectValue or #arrayValue can be accessed using operator[]() + * methods. + * Non-const methods will automatically create the a #nullValue element + * if it does not exist. + * The sequence of an #arrayValue will be automatically resized and initialized + * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. + * + * The get() methods can be used to obtain default value in the case the + * required element does not exist. + * + * It is possible to iterate over the list of a #objectValue values using + * the getMemberNames() method. + * + * \note #Value string-length fit in size_t, but keys must be < 2^30. + * (The reason is an implementation detail.) A #CharReader will raise an + * exception if a bound is exceeded to avoid security holes in your app, + * but the Value API does *not* check bounds. That is the responsibility + * of the caller. + */ +class JSON_API Value { + friend class ValueIteratorBase; +public: + typedef std::vector Members; + typedef ValueIterator iterator; + typedef ValueConstIterator const_iterator; + typedef Json::UInt UInt; + typedef Json::Int Int; +#if defined(JSON_HAS_INT64) + typedef Json::UInt64 UInt64; + typedef Json::Int64 Int64; +#endif // defined(JSON_HAS_INT64) + typedef Json::LargestInt LargestInt; + typedef Json::LargestUInt LargestUInt; + typedef Json::ArrayIndex ArrayIndex; + + static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). + static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null + static Value const& nullSingleton(); ///< Prefer this to null or nullRef. + + /// Minimum signed integer value that can be stored in a Json::Value. + static const LargestInt minLargestInt; + /// Maximum signed integer value that can be stored in a Json::Value. + static const LargestInt maxLargestInt; + /// Maximum unsigned integer value that can be stored in a Json::Value. + static const LargestUInt maxLargestUInt; + + /// Minimum signed int value that can be stored in a Json::Value. + static const Int minInt; + /// Maximum signed int value that can be stored in a Json::Value. + static const Int maxInt; + /// Maximum unsigned int value that can be stored in a Json::Value. + static const UInt maxUInt; + +#if defined(JSON_HAS_INT64) + /// Minimum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 minInt64; + /// Maximum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 maxInt64; + /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. + static const UInt64 maxUInt64; +#endif // defined(JSON_HAS_INT64) + +private: +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + class CZString { + public: + enum DuplicationPolicy { + noDuplication = 0, + duplicate, + duplicateOnCopy + }; + CZString(ArrayIndex index); + CZString(char const* str, unsigned length, DuplicationPolicy allocate); + CZString(CZString const& other); +#if JSON_HAS_RVALUE_REFERENCES + CZString(CZString&& other); +#endif + ~CZString(); + CZString& operator=(CZString other); + bool operator<(CZString const& other) const; + bool operator==(CZString const& other) const; + ArrayIndex index() const; + //const char* c_str() const; ///< \deprecated + char const* data() const; + unsigned length() const; + bool isStaticString() const; + + private: + void swap(CZString& other); + + struct StringStorage { + unsigned policy_: 2; + unsigned length_: 30; // 1GB max + }; + + char const* cstr_; // actually, a prefixed string, unless policy is noDup + union { + ArrayIndex index_; + StringStorage storage_; + }; + }; + +public: +#ifndef JSON_USE_CPPTL_SMALLMAP + typedef std::map ObjectValues; +#else + typedef CppTL::SmallMap ObjectValues; +#endif // ifndef JSON_USE_CPPTL_SMALLMAP +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +public: + /** \brief Create a default Value of the given type. + + This is a very useful constructor. + To create an empty array, pass arrayValue. + To create an empty object, pass objectValue. + Another Value can then be set to this one by assignment. +This is useful since clear() and resize() will not alter types. + + Examples: +\code +Json::Value null_value; // null +Json::Value arr_value(Json::arrayValue); // [] +Json::Value obj_value(Json::objectValue); // {} +\endcode + */ + Value(ValueType type = nullValue); + Value(Int value); + Value(UInt value); +#if defined(JSON_HAS_INT64) + Value(Int64 value); + Value(UInt64 value); +#endif // if defined(JSON_HAS_INT64) + Value(double value); + Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) + Value(const char* begin, const char* end); ///< Copy all, incl zeroes. + /** \brief Constructs a value from a static string. + + * Like other value string constructor but do not duplicate the string for + * internal storage. The given string must remain alive after the call to this + * constructor. + * \note This works only for null-terminated strings. (We cannot change the + * size of this class, so we have nowhere to store the length, + * which might be computed later for various operations.) + * + * Example of usage: + * \code + * static StaticString foo("some text"); + * Json::Value aValue(foo); + * \endcode + */ + Value(const StaticString& value); + Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. +#ifdef JSON_USE_CPPTL + Value(const CppTL::ConstString& value); +#endif + Value(bool value); + /// Deep copy. + Value(const Value& other); +#if JSON_HAS_RVALUE_REFERENCES + /// Move constructor + Value(Value&& other); +#endif + ~Value(); + + /// Deep copy, then swap(other). + /// \note Over-write existing comments. To preserve comments, use #swapPayload(). + Value& operator=(Value other); + /// Swap everything. + void swap(Value& other); + /// Swap values but leave comments and source offsets in place. + void swapPayload(Value& other); + + ValueType type() const; + + /// Compare payload only, not comments etc. + bool operator<(const Value& other) const; + bool operator<=(const Value& other) const; + bool operator>=(const Value& other) const; + bool operator>(const Value& other) const; + bool operator==(const Value& other) const; + bool operator!=(const Value& other) const; + int compare(const Value& other) const; + + const char* asCString() const; ///< Embedded zeroes could cause you trouble! +#if JSONCPP_USING_SECURE_MEMORY + unsigned getCStringLength() const; //Allows you to understand the length of the CString +#endif + JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. + /** Get raw char* of string-value. + * \return false if !string. (Seg-fault if str or end are NULL.) + */ + bool getString( + char const** begin, char const** end) const; +#ifdef JSON_USE_CPPTL + CppTL::ConstString asConstString() const; +#endif + Int asInt() const; + UInt asUInt() const; +#if defined(JSON_HAS_INT64) + Int64 asInt64() const; + UInt64 asUInt64() const; +#endif // if defined(JSON_HAS_INT64) + LargestInt asLargestInt() const; + LargestUInt asLargestUInt() const; + float asFloat() const; + double asDouble() const; + bool asBool() const; + + bool isNull() const; + bool isBool() const; + bool isInt() const; + bool isInt64() const; + bool isUInt() const; + bool isUInt64() const; + bool isIntegral() const; + bool isDouble() const; + bool isNumeric() const; + bool isString() const; + bool isArray() const; + bool isObject() const; + + bool isConvertibleTo(ValueType other) const; + + /// Number of values in array or object + ArrayIndex size() const; + + /// \brief Return true if empty array, empty object, or null; + /// otherwise, false. + bool empty() const; + + /// Return isNull() + bool operator!() const; + + /// Remove all object members and array elements. + /// \pre type() is arrayValue, objectValue, or nullValue + /// \post type() is unchanged + void clear(); + + /// Resize the array to size elements. + /// New elements are initialized to null. + /// May only be called on nullValue or arrayValue. + /// \pre type() is arrayValue or nullValue + /// \post type() is arrayValue + void resize(ArrayIndex size); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](ArrayIndex index); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](int index); + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](ArrayIndex index) const; + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](int index) const; + + /// If the array contains at least index+1 elements, returns the element + /// value, + /// otherwise returns defaultValue. + Value get(ArrayIndex index, const Value& defaultValue) const; + /// Return true if index < size(). + bool isValidIndex(ArrayIndex index) const; + /// \brief Append value to array at the end. + /// + /// Equivalent to jsonvalue[jsonvalue.size()] = value; + Value& append(const Value& value); + + /// Access an object value by name, create a null member if it does not exist. + /// \note Because of our implementation, keys are limited to 2^30 -1 chars. + /// Exceeding that will cause an exception. + Value& operator[](const char* key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const char* key) const; + /// Access an object value by name, create a null member if it does not exist. + /// \param key may contain embedded nulls. + Value& operator[](const JSONCPP_STRING& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + /// \param key may contain embedded nulls. + const Value& operator[](const JSONCPP_STRING& key) const; + /** \brief Access an object value by name, create a null member if it does not + exist. + + * If the object has no entry for that name, then the member name used to store + * the new entry is not duplicated. + * Example of use: + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + Value& operator[](const StaticString& key); +#ifdef JSON_USE_CPPTL + /// Access an object value by name, create a null member if it does not exist. + Value& operator[](const CppTL::ConstString& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const CppTL::ConstString& key) const; +#endif + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + Value get(const char* key, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \note key may contain embedded nulls. + Value get(const char* begin, const char* end, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \param key may contain embedded nulls. + Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; +#ifdef JSON_USE_CPPTL + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + Value get(const CppTL::ConstString& key, const Value& defaultValue) const; +#endif + /// Most general and efficient version of isMember()const, get()const, + /// and operator[]const + /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 + Value const* find(char const* begin, char const* end) const; + /// Most general and efficient version of object-mutators. + /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 + /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. + Value const* demand(char const* begin, char const* end); + /// \brief Remove and return the named member. + /// + /// Do nothing if it did not exist. + /// \return the removed Value, or null. + /// \pre type() is objectValue or nullValue + /// \post type() is unchanged + /// \deprecated + Value removeMember(const char* key); + /// Same as removeMember(const char*) + /// \param key may contain embedded nulls. + /// \deprecated + Value removeMember(const JSONCPP_STRING& key); + /// Same as removeMember(const char* begin, const char* end, Value* removed), + /// but 'key' is null-terminated. + bool removeMember(const char* key, Value* removed); + /** \brief Remove the named map member. + + Update 'removed' iff removed. + \param key may contain embedded nulls. + \return true iff removed (no exceptions) + */ + bool removeMember(JSONCPP_STRING const& key, Value* removed); + /// Same as removeMember(JSONCPP_STRING const& key, Value* removed) + bool removeMember(const char* begin, const char* end, Value* removed); + /** \brief Remove the indexed array element. + + O(n) expensive operations. + Update 'removed' iff removed. + \return true iff removed (no exceptions) + */ + bool removeIndex(ArrayIndex i, Value* removed); + + /// Return true if the object has a member named key. + /// \note 'key' must be null-terminated. + bool isMember(const char* key) const; + /// Return true if the object has a member named key. + /// \param key may contain embedded nulls. + bool isMember(const JSONCPP_STRING& key) const; + /// Same as isMember(JSONCPP_STRING const& key)const + bool isMember(const char* begin, const char* end) const; +#ifdef JSON_USE_CPPTL + /// Return true if the object has a member named key. + bool isMember(const CppTL::ConstString& key) const; +#endif + + /// \brief Return a list of the member names. + /// + /// If null, return an empty list. + /// \pre type() is objectValue or nullValue + /// \post if type() was nullValue, it remains nullValue + Members getMemberNames() const; + + //# ifdef JSON_USE_CPPTL + // EnumMemberNames enumMemberNames() const; + // EnumValues enumValues() const; + //# endif + + /// \deprecated Always pass len. + JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.") + void setComment(const char* comment, CommentPlacement placement); + /// Comments must be //... or /* ... */ + void setComment(const char* comment, size_t len, CommentPlacement placement); + /// Comments must be //... or /* ... */ + void setComment(const JSONCPP_STRING& comment, CommentPlacement placement); + bool hasComment(CommentPlacement placement) const; + /// Include delimiters and embedded newlines. + JSONCPP_STRING getComment(CommentPlacement placement) const; + + JSONCPP_STRING toStyledString() const; + + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); + + // Accessors for the [start, limit) range of bytes within the JSON text from + // which this value was parsed, if any. + void setOffsetStart(ptrdiff_t start); + void setOffsetLimit(ptrdiff_t limit); + ptrdiff_t getOffsetStart() const; + ptrdiff_t getOffsetLimit() const; + +private: + void initBasic(ValueType type, bool allocated = false); + + Value& resolveReference(const char* key); + Value& resolveReference(const char* key, const char* end); + + struct CommentInfo { + CommentInfo(); + ~CommentInfo(); + + void setComment(const char* text, size_t len); + + char* comment_; + }; + + // struct MemberNamesTransform + //{ + // typedef const char *result_type; + // const char *operator()( const CZString &name ) const + // { + // return name.c_str(); + // } + //}; + + union ValueHolder { + LargestInt int_; + LargestUInt uint_; + double real_; + bool bool_; + char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ + ObjectValues* map_; + } value_; + ValueType type_ : 8; + unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. + // If not allocated_, string_ must be null-terminated. + CommentInfo* comments_; + + // [start, limit) byte offsets in the source JSON text from which this Value + // was extracted. + ptrdiff_t start_; + ptrdiff_t limit_; +}; + +/** \brief Experimental and untested: represents an element of the "path" to + * access a node. + */ +class JSON_API PathArgument { +public: + friend class Path; + + PathArgument(); + PathArgument(ArrayIndex index); + PathArgument(const char* key); + PathArgument(const JSONCPP_STRING& key); + +private: + enum Kind { + kindNone = 0, + kindIndex, + kindKey + }; + JSONCPP_STRING key_; + ArrayIndex index_; + Kind kind_; +}; + +/** \brief Experimental and untested: represents a "path" to access a node. + * + * Syntax: + * - "." => root node + * - ".[n]" => elements at index 'n' of root node (an array value) + * - ".name" => member named 'name' of root node (an object value) + * - ".name1.name2.name3" + * - ".[0][1][2].name1[3]" + * - ".%" => member name is provided as parameter + * - ".[%]" => index is provied as parameter + */ +class JSON_API Path { +public: + Path(const JSONCPP_STRING& path, + const PathArgument& a1 = PathArgument(), + const PathArgument& a2 = PathArgument(), + const PathArgument& a3 = PathArgument(), + const PathArgument& a4 = PathArgument(), + const PathArgument& a5 = PathArgument()); + + const Value& resolve(const Value& root) const; + Value resolve(const Value& root, const Value& defaultValue) const; + /// Creates the "path" to access the specified node and returns a reference on + /// the node. + Value& make(Value& root) const; + +private: + typedef std::vector InArgs; + typedef std::vector Args; + + void makePath(const JSONCPP_STRING& path, const InArgs& in); + void addPathInArg(const JSONCPP_STRING& path, + const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind); + void invalidPath(const JSONCPP_STRING& path, int location); + + Args args_; +}; + +/** \brief base class for Value iterators. + * + */ +class JSON_API ValueIteratorBase { +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef unsigned int size_t; + typedef int difference_type; + typedef ValueIteratorBase SelfType; + + bool operator==(const SelfType& other) const { return isEqual(other); } + + bool operator!=(const SelfType& other) const { return !isEqual(other); } + + difference_type operator-(const SelfType& other) const { + return other.computeDistance(*this); + } + + /// Return either the index or the member name of the referenced value as a + /// Value. + Value key() const; + + /// Return the index of the referenced Value, or -1 if it is not an arrayValue. + UInt index() const; + + /// Return the member name of the referenced Value, or "" if it is not an + /// objectValue. + /// \note Avoid `c_str()` on result, as embedded zeroes are possible. + JSONCPP_STRING name() const; + + /// Return the member name of the referenced Value. "" if it is not an + /// objectValue. + /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. + JSONCPP_DEPRECATED("Use `key = name();` instead.") + char const* memberName() const; + /// Return the member name of the referenced Value, or NULL if it is not an + /// objectValue. + /// \note Better version than memberName(). Allows embedded nulls. + char const* memberName(char const** end) const; + +protected: + Value& deref() const; + + void increment(); + + void decrement(); + + difference_type computeDistance(const SelfType& other) const; + + bool isEqual(const SelfType& other) const; + + void copy(const SelfType& other); + +private: + Value::ObjectValues::iterator current_; + // Indicates that iterator is for a null value. + bool isNull_; + +public: + // For some reason, BORLAND needs these at the end, rather + // than earlier. No idea why. + ValueIteratorBase(); + explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); +}; + +/** \brief const iterator for object and array value. + * + */ +class JSON_API ValueConstIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef const Value value_type; + //typedef unsigned int size_t; + //typedef int difference_type; + typedef const Value& reference; + typedef const Value* pointer; + typedef ValueConstIterator SelfType; + + ValueConstIterator(); + ValueConstIterator(ValueIterator const& other); + +private: +/*! \internal Use by Value to create an iterator. + */ + explicit ValueConstIterator(const Value::ObjectValues::iterator& current); +public: + SelfType& operator=(const ValueIteratorBase& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +/** \brief Iterator for object and array value. + */ +class JSON_API ValueIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef Value value_type; + typedef unsigned int size_t; + typedef int difference_type; + typedef Value& reference; + typedef Value* pointer; + typedef ValueIterator SelfType; + + ValueIterator(); + explicit ValueIterator(const ValueConstIterator& other); + ValueIterator(const ValueIterator& other); + +private: +/*! \internal Use by Value to create an iterator. + */ + explicit ValueIterator(const Value::ObjectValues::iterator& current); +public: + SelfType& operator=(const SelfType& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +} // namespace Json + + +namespace std { +/// Specialize std::swap() for Json::Value. +template<> +inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } +} + + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_READER_H_INCLUDED +#define CPPTL_JSON_READER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "features.h" +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include +#include + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +/** \brief Unserialize a JSON document into a + *Value. + * + * \deprecated Use CharReader and CharReaderBuilder. + */ +class JSON_API Reader { +public: + typedef char Char; + typedef const Char* Location; + + /** \brief An error tagged with where in the JSON text it was encountered. + * + * The offsets give the [start, limit) range of bytes within the text. Note + * that this is bytes, not codepoints. + * + */ + struct StructuredError { + ptrdiff_t offset_start; + ptrdiff_t offset_limit; + JSONCPP_STRING message; + }; + + /** \brief Constructs a Reader allowing all features + * for parsing. + */ + Reader(); + + /** \brief Constructs a Reader allowing the specified feature set + * for parsing. + */ + Reader(const Features& features); + + /** \brief Read a Value from a JSON + * document. + * \param document UTF-8 encoded string containing the document to read. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + * back during + * serialization, \c false to discard comments. + * This parameter is ignored if + * Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + bool + parse(const std::string& document, Value& root, bool collectComments = true); + + /** \brief Read a Value from a JSON + document. + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the + document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + document to read. + * Must be >= beginDoc. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + back during + * serialization, \c false to discard comments. + * This parameter is ignored if + Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + error occurred. + */ + bool parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments = true); + + /// \brief Parse from input stream. + /// \see Json::operator>>(std::istream&, Json::Value&). + bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + * \deprecated Use getFormattedErrorMessages() instead (typo fix). + */ + JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") + JSONCPP_STRING getFormatedErrorMessages() const; + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + */ + JSONCPP_STRING getFormattedErrorMessages() const; + + /** \brief Returns a vector of structured erros encounted while parsing. + * \return A (possibly empty) vector of StructuredError objects. Currently + * only one error can be returned, but the caller should tolerate + * multiple + * errors. This can occur if the parser recovers from a non-fatal + * parse error and then encounters additional errors. + */ + std::vector getStructuredErrors() const; + + /** \brief Add a semantic error message. + * \param value JSON Value location associated with the error + * \param message The error message. + * \return \c true if the error was successfully added, \c false if the + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const JSONCPP_STRING& message); + + /** \brief Add a semantic error message with extra context. + * \param value JSON Value location associated with the error + * \param message The error message. + * \param extra Additional JSON Value location to contextualize the error + * \return \c true if the error was successfully added, \c false if either + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); + + /** \brief Return whether there are any errors. + * \return \c true if there are no errors to report \c false if + * errors have occurred. + */ + bool good() const; + +private: + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + JSONCPP_STRING message_; + Location extra_; + }; + + typedef std::deque Errors; + + bool readToken(Token& token); + void skipSpaces(); + bool match(Location pattern, int patternLength); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + void readNumber(); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, JSONCPP_STRING& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const JSONCPP_STRING& message, + Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void + getLocationLineAndColumn(Location location, int& line, int& column) const; + JSONCPP_STRING getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + typedef std::stack Nodes; + Nodes nodes_; + Errors errors_; + JSONCPP_STRING document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; + JSONCPP_STRING commentsBefore_; + Features features_; + bool collectComments_; +}; // Reader + +/** Interface for reading JSON from a char array. + */ +class JSON_API CharReader { +public: + virtual ~CharReader() {} + /** \brief Read a Value from a JSON + document. + * The document must be a UTF-8 encoded string containing the document to read. + * + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the + document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + document to read. + * Must be >= beginDoc. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param errs [out] Formatted error messages (if not NULL) + * a user friendly string that lists errors in the parsed + * document. + * \return \c true if the document was successfully parsed, \c false if an + error occurred. + */ + virtual bool parse( + char const* beginDoc, char const* endDoc, + Value* root, JSONCPP_STRING* errs) = 0; + + class JSON_API Factory { + public: + virtual ~Factory() {} + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual CharReader* newCharReader() const = 0; + }; // Factory +}; // CharReader + +/** \brief Build a CharReader implementation. + +Usage: +\code + using namespace Json; + CharReaderBuilder builder; + builder["collectComments"] = false; + Value value; + JSONCPP_STRING errs; + bool ok = parseFromStream(builder, std::cin, &value, &errs); +\endcode +*/ +class JSON_API CharReaderBuilder : public CharReader::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + These are case-sensitive. + Available settings (case-sensitive): + - `"collectComments": false or true` + - true to collect comment and allow writing them + back during serialization, false to discard comments. + This parameter is ignored if allowComments is false. + - `"allowComments": false or true` + - true if comments are allowed. + - `"strictRoot": false or true` + - true if root must be either an array or an object value + - `"allowDroppedNullPlaceholders": false or true` + - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) + - `"allowNumericKeys": false or true` + - true if numeric object keys are allowed. + - `"allowSingleQuotes": false or true` + - true if '' are allowed for strings (both keys and values) + - `"stackLimit": integer` + - Exceeding stackLimit (recursive depth of `readValue()`) will + cause an exception. + - This is a security issue (seg-faults caused by deeply nested JSON), + so the default is low. + - `"failIfExtra": false or true` + - If true, `parse()` returns false when extra non-whitespace trails + the JSON value in the input string. + - `"rejectDupKeys": false or true` + - If true, `parse()` returns false when a key is duplicated within an object. + - `"allowSpecialFloats": false or true` + - If true, special float values (NaNs and infinities) are allowed + and their values are lossfree restorable. + + You can examine 'settings_` yourself + to see the defaults. You can also write and read them just like any + JSON Value. + \sa setDefaults() + */ + Json::Value settings_; + + CharReaderBuilder(); + ~CharReaderBuilder() JSONCPP_OVERRIDE; + + CharReader* newCharReader() const JSONCPP_OVERRIDE; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + + /** A simple way to update a specific setting. + */ + Value& operator[](JSONCPP_STRING key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults + */ + static void setDefaults(Json::Value* settings); + /** Same as old Features::strictMode(). + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode + */ + static void strictMode(Json::Value* settings); +}; + +/** Consume entire stream and use its begin/end. + * Someday we might have a real StreamReader, but for now this + * is convenient. + */ +bool JSON_API parseFromStream( + CharReader::Factory const&, + JSONCPP_ISTREAM&, + Value* root, std::string* errs); + +/** \brief Read from 'sin' into 'root'. + + Always keep comments from the input JSON. + + This can be used to read a file into a particular sub-object. + For example: + \code + Json::Value root; + cin >> root["dir"]["file"]; + cout << root; + \endcode + Result: + \verbatim + { + "dir": { + "file": { + // The input stream JSON would be nested here. + } + } + } + \endverbatim + \throw std::exception on parse error. + \see Json::operator<<() +*/ +JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_READER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_WRITER_H_INCLUDED +#define JSON_WRITER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +class Value; + +/** + +Usage: +\code + using namespace Json; + void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { + std::unique_ptr const writer( + factory.newStreamWriter()); + writer->write(value, &std::cout); + std::cout << std::endl; // add lf and flush + } +\endcode +*/ +class JSON_API StreamWriter { +protected: + JSONCPP_OSTREAM* sout_; // not owned; will not delete +public: + StreamWriter(); + virtual ~StreamWriter(); + /** Write Value into document as configured in sub-class. + Do not take ownership of sout, but maintain a reference during function. + \pre sout != NULL + \return zero on success (For now, we always return zero, so check the stream instead.) + \throw std::exception possibly, depending on configuration + */ + virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; + + /** \brief A simple abstract factory. + */ + class JSON_API Factory { + public: + virtual ~Factory(); + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual StreamWriter* newStreamWriter() const = 0; + }; // Factory +}; // StreamWriter + +/** \brief Write into stringstream, then return string, for convenience. + * A StreamWriter will be created from the factory, used, and then deleted. + */ +JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); + + +/** \brief Build a StreamWriter implementation. + +Usage: +\code + using namespace Json; + Value value = ...; + StreamWriterBuilder builder; + builder["commentStyle"] = "None"; + builder["indentation"] = " "; // or whatever you like + std::unique_ptr writer( + builder.newStreamWriter()); + writer->write(value, &std::cout); + std::cout << std::endl; // add lf and flush +\endcode +*/ +class JSON_API StreamWriterBuilder : public StreamWriter::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + Available settings (case-sensitive): + - "commentStyle": "None" or "All" + - "indentation": "" + - "enableYAMLCompatibility": false or true + - slightly change the whitespace around colons + - "dropNullPlaceholders": false or true + - Drop the "null" string from the writer's output for nullValues. + Strictly speaking, this is not valid JSON. But when the output is being + fed to a browser's Javascript, it makes for smaller output and the + browser can handle the output just fine. + - "useSpecialFloats": false or true + - If true, outputs non-finite floating point values in the following way: + NaN values as "NaN", positive infinity as "Infinity", and negative infinity + as "-Infinity". + + You can examine 'settings_` yourself + to see the defaults. You can also write and read them just like any + JSON Value. + \sa setDefaults() + */ + Json::Value settings_; + + StreamWriterBuilder(); + ~StreamWriterBuilder() JSONCPP_OVERRIDE; + + /** + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + /** A simple way to update a specific setting. + */ + Value& operator[](JSONCPP_STRING key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults + */ + static void setDefaults(Json::Value* settings); +}; + +/** \brief Abstract class for writers. + * \deprecated Use StreamWriter. (And really, this is an implementation detail.) + */ +class JSON_API Writer { +public: + virtual ~Writer(); + + virtual JSONCPP_STRING write(const Value& root) = 0; +}; + +/** \brief Outputs a Value in JSON format + *without formatting (not human friendly). + * + * The JSON document is written in a single line. It is not intended for 'human' + *consumption, + * but may be usefull to support feature such as RPC where bandwith is limited. + * \sa Reader, Value + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API FastWriter : public Writer { + +public: + FastWriter(); + ~FastWriter() JSONCPP_OVERRIDE {} + + void enableYAMLCompatibility(); + + /** \brief Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's Javascript, it makes for smaller output and the + * browser can handle the output just fine. + */ + void dropNullPlaceholders(); + + void omitEndingLineFeed(); + +public: // overridden from Writer + JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; + +private: + void writeValue(const Value& value); + + JSONCPP_STRING document_; + bool yamlCompatiblityEnabled_; + bool dropNullPlaceholders_; + bool omitEndingLineFeed_; +}; + +/** \brief Writes a Value in JSON format in a + *human friendly way. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + *line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + *types, + * and all the values fit on one lines, then print the array on a single + *line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + *#CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API StyledWriter : public Writer { +public: + StyledWriter(); + ~StyledWriter() JSONCPP_OVERRIDE {} + +public: // overridden from Writer + /** \brief Serialize a Value in JSON format. + * \param root Value to serialize. + * \return String containing the JSON document that represents the root value. + */ + JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const JSONCPP_STRING& value); + void writeIndent(); + void writeWithIndent(const JSONCPP_STRING& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); + + typedef std::vector ChildValues; + + ChildValues childValues_; + JSONCPP_STRING document_; + JSONCPP_STRING indentString_; + unsigned int rightMargin_; + unsigned int indentSize_; + bool addChildValues_; +}; + +/** \brief Writes a Value in JSON format in a + human friendly way, + to a stream rather than to a string. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + types, + * and all the values fit on one lines, then print the array on a single + line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + #CommentPlacement. + * + * \param indentation Each level will be indented by this amount extra. + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API StyledStreamWriter { +public: + StyledStreamWriter(JSONCPP_STRING indentation = "\t"); + ~StyledStreamWriter() {} + +public: + /** \brief Serialize a Value in JSON format. + * \param out Stream to write to. (Can be ostringstream, e.g.) + * \param root Value to serialize. + * \note There is no point in deriving from Writer, since write() should not + * return a value. + */ + void write(JSONCPP_OSTREAM& out, const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const JSONCPP_STRING& value); + void writeIndent(); + void writeWithIndent(const JSONCPP_STRING& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); + + typedef std::vector ChildValues; + + ChildValues childValues_; + JSONCPP_OSTREAM* document_; + JSONCPP_STRING indentString_; + unsigned int rightMargin_; + JSONCPP_STRING indentation_; + bool addChildValues_ : 1; + bool indented_ : 1; +}; + +#if defined(JSON_HAS_INT64) +JSONCPP_STRING JSON_API valueToString(Int value); +JSONCPP_STRING JSON_API valueToString(UInt value); +#endif // if defined(JSON_HAS_INT64) +JSONCPP_STRING JSON_API valueToString(LargestInt value); +JSONCPP_STRING JSON_API valueToString(LargestUInt value); +JSONCPP_STRING JSON_API valueToString(double value); +JSONCPP_STRING JSON_API valueToString(bool value); +JSONCPP_STRING JSON_API valueToQuotedString(const char* value); + +/// \brief Output using the StyledStreamWriter. +/// \see Json::operator>>() +JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_WRITER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED +#define CPPTL_JSON_ASSERTIONS_H_INCLUDED + +#include +#include + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +/** It should not be possible for a maliciously designed file to + * cause an abort() or seg-fault, so these macros are used only + * for pre-condition violations and internal logic errors. + */ +#if JSON_USE_EXCEPTION + +// @todo <= add detail about condition in exception +# define JSON_ASSERT(condition) \ + {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} + +# define JSON_FAIL_MESSAGE(message) \ + { \ + JSONCPP_OSTRINGSTREAM oss; oss << message; \ + Json::throwLogicError(oss.str()); \ + abort(); \ + } + +#else // JSON_USE_EXCEPTION + +# define JSON_ASSERT(condition) assert(condition) + +// The call to assert() will show the failure message in debug builds. In +// release builds we abort, for a core-dump or debugger. +# define JSON_FAIL_MESSAGE(message) \ + { \ + JSONCPP_OSTRINGSTREAM oss; oss << message; \ + assert(false && oss.str().c_str()); \ + abort(); \ + } + + +#endif + +#define JSON_ASSERT_MESSAGE(condition, message) \ + if (!(condition)) { \ + JSON_FAIL_MESSAGE(message); \ + } + +#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_AMALGATED_H_INCLUDED diff --git a/hueplusplus/json/json.h b/hueplusplus/json/json.h deleted file mode 100644 index 94a1e2f..0000000 --- a/hueplusplus/json/json.h +++ /dev/null @@ -1,2139 +0,0 @@ -/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/). -/// It is intended to be used with #include "json/json.h" - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: LICENSE -// ////////////////////////////////////////////////////////////////////// - -/* -The JsonCpp library's source code, including accompanying documentation, -tests and demonstration applications, are licensed under the following -conditions... - -The author (Baptiste Lepilleur) explicitly disclaims copyright in all -jurisdictions which recognize such a disclaimer. In such jurisdictions, -this software is released into the Public Domain. - -In jurisdictions which do not recognize Public Domain property (e.g. Germany as of -2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is -released under the terms of the MIT License (see below). - -In jurisdictions which recognize Public Domain property, the user of this -software may choose to accept it either as 1) Public Domain, 2) under the -conditions of the MIT License (see below), or 3) under the terms of dual -Public Domain/MIT License conditions described here, as they choose. - -The MIT License is about as close to Public Domain as a license can get, and is -described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - -The full text of the MIT License follows: - -======================================================================== -Copyright (c) 2007-2010 Baptiste Lepilleur - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -======================================================================== -(END LICENSE TEXT) - -The MIT license is compatible with both the GPL and commercial -software, affording one all of the rights of Public Domain with the -minor nuisance of being required to keep the above copyright notice -and license text in the source code. Note also that by accepting the -Public Domain "license" you can re-license your copy using whatever -license you like. - -*/ - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: LICENSE -// ////////////////////////////////////////////////////////////////////// - - - - - -#ifndef JSON_AMALGATED_H_INCLUDED -# define JSON_AMALGATED_H_INCLUDED -/// If defined, indicates that the source file is amalgated -/// to prevent private header inclusion. -#define JSON_IS_AMALGAMATION - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/version.h -// ////////////////////////////////////////////////////////////////////// - -// DO NOT EDIT. This file (and "version") is generated by CMake. -// Run CMake configure step to update it. -#ifndef JSON_VERSION_H_INCLUDED -# define JSON_VERSION_H_INCLUDED - -# define JSONCPP_VERSION_STRING "1.7.4" -# define JSONCPP_VERSION_MAJOR 1 -# define JSONCPP_VERSION_MINOR 7 -# define JSONCPP_VERSION_PATCH 4 -# define JSONCPP_VERSION_QUALIFIER -# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) - -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif -#define JSONCPP_USING_SECURE_MEMORY 0 -// If non-zero, the library zeroes any memory that it has allocated before -// it frees its memory. - -#endif // JSON_VERSION_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/version.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/config.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef JSON_CONFIG_H_INCLUDED -#define JSON_CONFIG_H_INCLUDED -#include -#include //typdef String - -/// If defined, indicates that json library is embedded in CppTL library. -//# define JSON_IN_CPPTL 1 - -/// If defined, indicates that json may leverage CppTL library -//# define JSON_USE_CPPTL 1 -/// If defined, indicates that cpptl vector based map should be used instead of -/// std::map -/// as Value container. -//# define JSON_USE_CPPTL_SMALLMAP 1 - -// If non-zero, the library uses exceptions to report bad input instead of C -// assertion macros. The default is to use exceptions. -#ifndef JSON_USE_EXCEPTION -#define JSON_USE_EXCEPTION 1 -#endif - -/// If defined, indicates that the source file is amalgated -/// to prevent private header inclusion. -/// Remarks: it is automatically defined in the generated amalgated header. -// #define JSON_IS_AMALGAMATION - -#ifdef JSON_IN_CPPTL -#include -#ifndef JSON_USE_CPPTL -#define JSON_USE_CPPTL 1 -#endif -#endif - -#ifdef JSON_IN_CPPTL -#define JSON_API CPPTL_API -#elif defined(JSON_DLL_BUILD) -#if defined(_MSC_VER) || defined(__MINGW32__) -#define JSON_API __declspec(dllexport) -#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING -#endif // if defined(_MSC_VER) -#elif defined(JSON_DLL) -#if defined(_MSC_VER) || defined(__MINGW32__) -#define JSON_API __declspec(dllimport) -#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING -#endif // if defined(_MSC_VER) -#endif // ifdef JSON_IN_CPPTL -#if !defined(JSON_API) -#define JSON_API -#endif - -// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for -// integer -// Storages, and 64 bits integer support is disabled. -// #define JSON_NO_INT64 1 - -#if defined(_MSC_VER) // MSVC -# if _MSC_VER <= 1200 // MSVC 6 - // Microsoft Visual Studio 6 only support conversion from __int64 to double - // (no conversion from unsigned __int64). -# define JSON_USE_INT64_DOUBLE_CONVERSION 1 - // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' - // characters in the debug information) - // All projects I've ever seen with VS6 were using this globally (not bothering - // with pragma push/pop). -# pragma warning(disable : 4786) -# endif // MSVC 6 - -# if _MSC_VER >= 1500 // MSVC 2008 - /// Indicates that the following function is deprecated. -# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) -# endif - -#endif // defined(_MSC_VER) - -// In c++11 the override keyword allows you to explicity define that a function -// is intended to override the base-class version. This makes the code more -// managable and fixes a set of common hard-to-find bugs. -#if __cplusplus >= 201103L -# define JSONCPP_OVERRIDE override -#elif defined(_MSC_VER) && _MSC_VER > 1600 -# define JSONCPP_OVERRIDE override -#else -# define JSONCPP_OVERRIDE -#endif - -#ifndef JSON_HAS_RVALUE_REFERENCES - -#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // MSVC >= 2010 - -#ifdef __clang__ -#if __has_feature(cxx_rvalue_references) -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // has_feature - -#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) -#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // GXX_EXPERIMENTAL - -#endif // __clang__ || __GNUC__ - -#endif // not defined JSON_HAS_RVALUE_REFERENCES - -#ifndef JSON_HAS_RVALUE_REFERENCES -#define JSON_HAS_RVALUE_REFERENCES 0 -#endif - -#ifdef __clang__ -#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) -# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) -# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) -# endif // GNUC version -#endif // __clang__ || __GNUC__ - -#if !defined(JSONCPP_DEPRECATED) -#define JSONCPP_DEPRECATED(message) -#endif // if !defined(JSONCPP_DEPRECATED) - -#if __GNUC__ >= 6 -# define JSON_USE_INT64_DOUBLE_CONVERSION 1 -#endif - -#if !defined(JSON_IS_AMALGAMATION) - -# include "version.h" - -# if JSONCPP_USING_SECURE_MEMORY -# include "allocator.h" //typedef Allocator -# endif - -#endif // if !defined(JSON_IS_AMALGAMATION) - -namespace Json { -typedef int Int; -typedef unsigned int UInt; -#if defined(JSON_NO_INT64) -typedef int LargestInt; -typedef unsigned int LargestUInt; -#undef JSON_HAS_INT64 -#else // if defined(JSON_NO_INT64) -// For Microsoft Visual use specific types as long long is not supported -#if defined(_MSC_VER) // Microsoft Visual Studio -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#else // if defined(_MSC_VER) // Other platforms, use long long -typedef long long int Int64; -typedef unsigned long long int UInt64; -#endif // if defined(_MSC_VER) -typedef Int64 LargestInt; -typedef UInt64 LargestUInt; -#define JSON_HAS_INT64 -#endif // if defined(JSON_NO_INT64) -#if JSONCPP_USING_SECURE_MEMORY -#define JSONCPP_STRING std::basic_string, Json::SecureAllocator > -#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > -#define JSONCPP_OSTREAM std::basic_ostream> -#define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > -#define JSONCPP_ISTREAM std::istream -#else -#define JSONCPP_STRING std::string -#define JSONCPP_OSTRINGSTREAM std::ostringstream -#define JSONCPP_OSTREAM std::ostream -#define JSONCPP_ISTRINGSTREAM std::istringstream -#define JSONCPP_ISTREAM std::istream -#endif // if JSONCPP_USING_SECURE_MEMORY -} // end namespace Json - -#endif // JSON_CONFIG_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/config.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/forwards.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef JSON_FORWARDS_H_INCLUDED -#define JSON_FORWARDS_H_INCLUDED - -#if !defined(JSON_IS_AMALGAMATION) -#include "config.h" -#endif // if !defined(JSON_IS_AMALGAMATION) - -namespace Json { - -// writer.h -class FastWriter; -class StyledWriter; - -// reader.h -class Reader; - -// features.h -class Features; - -// value.h -typedef unsigned int ArrayIndex; -class StaticString; -class Path; -class PathArgument; -class Value; -class ValueIteratorBase; -class ValueIterator; -class ValueConstIterator; - -} // namespace Json - -#endif // JSON_FORWARDS_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/forwards.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/features.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef CPPTL_JSON_FEATURES_H_INCLUDED -#define CPPTL_JSON_FEATURES_H_INCLUDED - -#if !defined(JSON_IS_AMALGAMATION) -#include "forwards.h" -#endif // if !defined(JSON_IS_AMALGAMATION) - -namespace Json { - -/** \brief Configuration passed to reader and writer. - * This configuration object can be used to force the Reader or Writer - * to behave in a standard conforming way. - */ -class JSON_API Features { -public: - /** \brief A configuration that allows all features and assumes all strings - * are UTF-8. - * - C & C++ comments are allowed - * - Root object can be any JSON value - * - Assumes Value strings are encoded in UTF-8 - */ - static Features all(); - - /** \brief A configuration that is strictly compatible with the JSON - * specification. - * - Comments are forbidden. - * - Root object must be either an array or an object value. - * - Assumes Value strings are encoded in UTF-8 - */ - static Features strictMode(); - - /** \brief Initialize the configuration like JsonConfig::allFeatures; - */ - Features(); - - /// \c true if comments are allowed. Default: \c true. - bool allowComments_; - - /// \c true if root must be either an array or an object value. Default: \c - /// false. - bool strictRoot_; - - /// \c true if dropped null placeholders are allowed. Default: \c false. - bool allowDroppedNullPlaceholders_; - - /// \c true if numeric object key are allowed. Default: \c false. - bool allowNumericKeys_; -}; - -} // namespace Json - -#endif // CPPTL_JSON_FEATURES_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/features.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/value.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef CPPTL_JSON_H_INCLUDED -#define CPPTL_JSON_H_INCLUDED - -#if !defined(JSON_IS_AMALGAMATION) -#include "forwards.h" -#endif // if !defined(JSON_IS_AMALGAMATION) -#include -#include -#include - -#ifndef JSON_USE_CPPTL_SMALLMAP -#include -#else -#include -#endif -#ifdef JSON_USE_CPPTL -#include -#endif - -//Conditional NORETURN attribute on the throw functions would: -// a) suppress false positives from static code analysis -// b) possibly improve optimization opportunities. -#if !defined(JSONCPP_NORETURN) -# if defined(_MSC_VER) -# define JSONCPP_NORETURN __declspec(noreturn) -# elif defined(__GNUC__) -# define JSONCPP_NORETURN __attribute__ ((__noreturn__)) -# else -# define JSONCPP_NORETURN -# endif -#endif - -// Disable warning C4251: : needs to have dll-interface to -// be used by... -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(push) -#pragma warning(disable : 4251) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -/** \brief JSON (JavaScript Object Notation). - */ -namespace Json { - -/** Base class for all exceptions we throw. - * - * We use nothing but these internally. Of course, STL can throw others. - */ -class JSON_API Exception : public std::exception { -public: - Exception(JSONCPP_STRING const& msg); - ~Exception() throw() JSONCPP_OVERRIDE; - char const* what() const throw() JSONCPP_OVERRIDE; -protected: - JSONCPP_STRING msg_; -}; - -/** Exceptions which the user cannot easily avoid. - * - * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input - * - * \remark derived from Json::Exception - */ -class JSON_API RuntimeError : public Exception { -public: - RuntimeError(JSONCPP_STRING const& msg); -}; - -/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. - * - * These are precondition-violations (user bugs) and internal errors (our bugs). - * - * \remark derived from Json::Exception - */ -class JSON_API LogicError : public Exception { -public: - LogicError(JSONCPP_STRING const& msg); -}; - -/// used internally -JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg); -/// used internally -JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg); - -/** \brief Type of the value held by a Value object. - */ -enum ValueType { - nullValue = 0, ///< 'null' value - intValue, ///< signed integer value - uintValue, ///< unsigned integer value - realValue, ///< double value - stringValue, ///< UTF-8 string value - booleanValue, ///< bool value - arrayValue, ///< array value (ordered list) - objectValue ///< object value (collection of name/value pairs). -}; - -enum CommentPlacement { - commentBefore = 0, ///< a comment placed on the line before a value - commentAfterOnSameLine, ///< a comment just after a value on the same line - commentAfter, ///< a comment on the line after a value (only make sense for - /// root value) - numberOfCommentPlacement -}; - -//# ifdef JSON_USE_CPPTL -// typedef CppTL::AnyEnumerator EnumMemberNames; -// typedef CppTL::AnyEnumerator EnumValues; -//# endif - -/** \brief Lightweight wrapper to tag static string. - * - * Value constructor and objectValue member assignement takes advantage of the - * StaticString and avoid the cost of string duplication when storing the - * string or the member name. - * - * Example of usage: - * \code - * Json::Value aValue( StaticString("some text") ); - * Json::Value object; - * static const StaticString code("code"); - * object[code] = 1234; - * \endcode - */ -class JSON_API StaticString { -public: - explicit StaticString(const char* czstring) : c_str_(czstring) {} - - operator const char*() const { return c_str_; } - - const char* c_str() const { return c_str_; } - -private: - const char* c_str_; -}; - -/** \brief Represents a JSON value. - * - * This class is a discriminated union wrapper that can represents a: - * - signed integer [range: Value::minInt - Value::maxInt] - * - unsigned integer (range: 0 - Value::maxUInt) - * - double - * - UTF-8 string - * - boolean - * - 'null' - * - an ordered list of Value - * - collection of name/value pairs (javascript object) - * - * The type of the held value is represented by a #ValueType and - * can be obtained using type(). - * - * Values of an #objectValue or #arrayValue can be accessed using operator[]() - * methods. - * Non-const methods will automatically create the a #nullValue element - * if it does not exist. - * The sequence of an #arrayValue will be automatically resized and initialized - * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. - * - * The get() methods can be used to obtain default value in the case the - * required element does not exist. - * - * It is possible to iterate over the list of a #objectValue values using - * the getMemberNames() method. - * - * \note #Value string-length fit in size_t, but keys must be < 2^30. - * (The reason is an implementation detail.) A #CharReader will raise an - * exception if a bound is exceeded to avoid security holes in your app, - * but the Value API does *not* check bounds. That is the responsibility - * of the caller. - */ -class JSON_API Value { - friend class ValueIteratorBase; -public: - typedef std::vector Members; - typedef ValueIterator iterator; - typedef ValueConstIterator const_iterator; - typedef Json::UInt UInt; - typedef Json::Int Int; -#if defined(JSON_HAS_INT64) - typedef Json::UInt64 UInt64; - typedef Json::Int64 Int64; -#endif // defined(JSON_HAS_INT64) - typedef Json::LargestInt LargestInt; - typedef Json::LargestUInt LargestUInt; - typedef Json::ArrayIndex ArrayIndex; - - static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). - static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null - static Value const& nullSingleton(); ///< Prefer this to null or nullRef. - - /// Minimum signed integer value that can be stored in a Json::Value. - static const LargestInt minLargestInt; - /// Maximum signed integer value that can be stored in a Json::Value. - static const LargestInt maxLargestInt; - /// Maximum unsigned integer value that can be stored in a Json::Value. - static const LargestUInt maxLargestUInt; - - /// Minimum signed int value that can be stored in a Json::Value. - static const Int minInt; - /// Maximum signed int value that can be stored in a Json::Value. - static const Int maxInt; - /// Maximum unsigned int value that can be stored in a Json::Value. - static const UInt maxUInt; - -#if defined(JSON_HAS_INT64) - /// Minimum signed 64 bits int value that can be stored in a Json::Value. - static const Int64 minInt64; - /// Maximum signed 64 bits int value that can be stored in a Json::Value. - static const Int64 maxInt64; - /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. - static const UInt64 maxUInt64; -#endif // defined(JSON_HAS_INT64) - -private: -#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - class CZString { - public: - enum DuplicationPolicy { - noDuplication = 0, - duplicate, - duplicateOnCopy - }; - CZString(ArrayIndex index); - CZString(char const* str, unsigned length, DuplicationPolicy allocate); - CZString(CZString const& other); -#if JSON_HAS_RVALUE_REFERENCES - CZString(CZString&& other); -#endif - ~CZString(); - CZString& operator=(CZString other); - bool operator<(CZString const& other) const; - bool operator==(CZString const& other) const; - ArrayIndex index() const; - //const char* c_str() const; ///< \deprecated - char const* data() const; - unsigned length() const; - bool isStaticString() const; - - private: - void swap(CZString& other); - - struct StringStorage { - unsigned policy_: 2; - unsigned length_: 30; // 1GB max - }; - - char const* cstr_; // actually, a prefixed string, unless policy is noDup - union { - ArrayIndex index_; - StringStorage storage_; - }; - }; - -public: -#ifndef JSON_USE_CPPTL_SMALLMAP - typedef std::map ObjectValues; -#else - typedef CppTL::SmallMap ObjectValues; -#endif // ifndef JSON_USE_CPPTL_SMALLMAP -#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - -public: - /** \brief Create a default Value of the given type. - - This is a very useful constructor. - To create an empty array, pass arrayValue. - To create an empty object, pass objectValue. - Another Value can then be set to this one by assignment. -This is useful since clear() and resize() will not alter types. - - Examples: -\code -Json::Value null_value; // null -Json::Value arr_value(Json::arrayValue); // [] -Json::Value obj_value(Json::objectValue); // {} -\endcode - */ - Value(ValueType type = nullValue); - Value(Int value); - Value(UInt value); -#if defined(JSON_HAS_INT64) - Value(Int64 value); - Value(UInt64 value); -#endif // if defined(JSON_HAS_INT64) - Value(double value); - Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) - Value(const char* begin, const char* end); ///< Copy all, incl zeroes. - /** \brief Constructs a value from a static string. - - * Like other value string constructor but do not duplicate the string for - * internal storage. The given string must remain alive after the call to this - * constructor. - * \note This works only for null-terminated strings. (We cannot change the - * size of this class, so we have nowhere to store the length, - * which might be computed later for various operations.) - * - * Example of usage: - * \code - * static StaticString foo("some text"); - * Json::Value aValue(foo); - * \endcode - */ - Value(const StaticString& value); - Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. -#ifdef JSON_USE_CPPTL - Value(const CppTL::ConstString& value); -#endif - Value(bool value); - /// Deep copy. - Value(const Value& other); -#if JSON_HAS_RVALUE_REFERENCES - /// Move constructor - Value(Value&& other); -#endif - ~Value(); - - /// Deep copy, then swap(other). - /// \note Over-write existing comments. To preserve comments, use #swapPayload(). - Value& operator=(Value other); - /// Swap everything. - void swap(Value& other); - /// Swap values but leave comments and source offsets in place. - void swapPayload(Value& other); - - ValueType type() const; - - /// Compare payload only, not comments etc. - bool operator<(const Value& other) const; - bool operator<=(const Value& other) const; - bool operator>=(const Value& other) const; - bool operator>(const Value& other) const; - bool operator==(const Value& other) const; - bool operator!=(const Value& other) const; - int compare(const Value& other) const; - - const char* asCString() const; ///< Embedded zeroes could cause you trouble! -#if JSONCPP_USING_SECURE_MEMORY - unsigned getCStringLength() const; //Allows you to understand the length of the CString -#endif - JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. - /** Get raw char* of string-value. - * \return false if !string. (Seg-fault if str or end are NULL.) - */ - bool getString( - char const** begin, char const** end) const; -#ifdef JSON_USE_CPPTL - CppTL::ConstString asConstString() const; -#endif - Int asInt() const; - UInt asUInt() const; -#if defined(JSON_HAS_INT64) - Int64 asInt64() const; - UInt64 asUInt64() const; -#endif // if defined(JSON_HAS_INT64) - LargestInt asLargestInt() const; - LargestUInt asLargestUInt() const; - float asFloat() const; - double asDouble() const; - bool asBool() const; - - bool isNull() const; - bool isBool() const; - bool isInt() const; - bool isInt64() const; - bool isUInt() const; - bool isUInt64() const; - bool isIntegral() const; - bool isDouble() const; - bool isNumeric() const; - bool isString() const; - bool isArray() const; - bool isObject() const; - - bool isConvertibleTo(ValueType other) const; - - /// Number of values in array or object - ArrayIndex size() const; - - /// \brief Return true if empty array, empty object, or null; - /// otherwise, false. - bool empty() const; - - /// Return isNull() - bool operator!() const; - - /// Remove all object members and array elements. - /// \pre type() is arrayValue, objectValue, or nullValue - /// \post type() is unchanged - void clear(); - - /// Resize the array to size elements. - /// New elements are initialized to null. - /// May only be called on nullValue or arrayValue. - /// \pre type() is arrayValue or nullValue - /// \post type() is arrayValue - void resize(ArrayIndex size); - - /// Access an array element (zero based index ). - /// If the array contains less than index element, then null value are - /// inserted - /// in the array so that its size is index+1. - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - Value& operator[](ArrayIndex index); - - /// Access an array element (zero based index ). - /// If the array contains less than index element, then null value are - /// inserted - /// in the array so that its size is index+1. - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - Value& operator[](int index); - - /// Access an array element (zero based index ) - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - const Value& operator[](ArrayIndex index) const; - - /// Access an array element (zero based index ) - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - const Value& operator[](int index) const; - - /// If the array contains at least index+1 elements, returns the element - /// value, - /// otherwise returns defaultValue. - Value get(ArrayIndex index, const Value& defaultValue) const; - /// Return true if index < size(). - bool isValidIndex(ArrayIndex index) const; - /// \brief Append value to array at the end. - /// - /// Equivalent to jsonvalue[jsonvalue.size()] = value; - Value& append(const Value& value); - - /// Access an object value by name, create a null member if it does not exist. - /// \note Because of our implementation, keys are limited to 2^30 -1 chars. - /// Exceeding that will cause an exception. - Value& operator[](const char* key); - /// Access an object value by name, returns null if there is no member with - /// that name. - const Value& operator[](const char* key) const; - /// Access an object value by name, create a null member if it does not exist. - /// \param key may contain embedded nulls. - Value& operator[](const JSONCPP_STRING& key); - /// Access an object value by name, returns null if there is no member with - /// that name. - /// \param key may contain embedded nulls. - const Value& operator[](const JSONCPP_STRING& key) const; - /** \brief Access an object value by name, create a null member if it does not - exist. - - * If the object has no entry for that name, then the member name used to store - * the new entry is not duplicated. - * Example of use: - * \code - * Json::Value object; - * static const StaticString code("code"); - * object[code] = 1234; - * \endcode - */ - Value& operator[](const StaticString& key); -#ifdef JSON_USE_CPPTL - /// Access an object value by name, create a null member if it does not exist. - Value& operator[](const CppTL::ConstString& key); - /// Access an object value by name, returns null if there is no member with - /// that name. - const Value& operator[](const CppTL::ConstString& key) const; -#endif - /// Return the member named key if it exist, defaultValue otherwise. - /// \note deep copy - Value get(const char* key, const Value& defaultValue) const; - /// Return the member named key if it exist, defaultValue otherwise. - /// \note deep copy - /// \note key may contain embedded nulls. - Value get(const char* begin, const char* end, const Value& defaultValue) const; - /// Return the member named key if it exist, defaultValue otherwise. - /// \note deep copy - /// \param key may contain embedded nulls. - Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; -#ifdef JSON_USE_CPPTL - /// Return the member named key if it exist, defaultValue otherwise. - /// \note deep copy - Value get(const CppTL::ConstString& key, const Value& defaultValue) const; -#endif - /// Most general and efficient version of isMember()const, get()const, - /// and operator[]const - /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 - Value const* find(char const* begin, char const* end) const; - /// Most general and efficient version of object-mutators. - /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 - /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. - Value const* demand(char const* begin, char const* end); - /// \brief Remove and return the named member. - /// - /// Do nothing if it did not exist. - /// \return the removed Value, or null. - /// \pre type() is objectValue or nullValue - /// \post type() is unchanged - /// \deprecated - Value removeMember(const char* key); - /// Same as removeMember(const char*) - /// \param key may contain embedded nulls. - /// \deprecated - Value removeMember(const JSONCPP_STRING& key); - /// Same as removeMember(const char* begin, const char* end, Value* removed), - /// but 'key' is null-terminated. - bool removeMember(const char* key, Value* removed); - /** \brief Remove the named map member. - - Update 'removed' iff removed. - \param key may contain embedded nulls. - \return true iff removed (no exceptions) - */ - bool removeMember(JSONCPP_STRING const& key, Value* removed); - /// Same as removeMember(JSONCPP_STRING const& key, Value* removed) - bool removeMember(const char* begin, const char* end, Value* removed); - /** \brief Remove the indexed array element. - - O(n) expensive operations. - Update 'removed' iff removed. - \return true iff removed (no exceptions) - */ - bool removeIndex(ArrayIndex i, Value* removed); - - /// Return true if the object has a member named key. - /// \note 'key' must be null-terminated. - bool isMember(const char* key) const; - /// Return true if the object has a member named key. - /// \param key may contain embedded nulls. - bool isMember(const JSONCPP_STRING& key) const; - /// Same as isMember(JSONCPP_STRING const& key)const - bool isMember(const char* begin, const char* end) const; -#ifdef JSON_USE_CPPTL - /// Return true if the object has a member named key. - bool isMember(const CppTL::ConstString& key) const; -#endif - - /// \brief Return a list of the member names. - /// - /// If null, return an empty list. - /// \pre type() is objectValue or nullValue - /// \post if type() was nullValue, it remains nullValue - Members getMemberNames() const; - - //# ifdef JSON_USE_CPPTL - // EnumMemberNames enumMemberNames() const; - // EnumValues enumValues() const; - //# endif - - /// \deprecated Always pass len. - JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.") - void setComment(const char* comment, CommentPlacement placement); - /// Comments must be //... or /* ... */ - void setComment(const char* comment, size_t len, CommentPlacement placement); - /// Comments must be //... or /* ... */ - void setComment(const JSONCPP_STRING& comment, CommentPlacement placement); - bool hasComment(CommentPlacement placement) const; - /// Include delimiters and embedded newlines. - JSONCPP_STRING getComment(CommentPlacement placement) const; - - JSONCPP_STRING toStyledString() const; - - const_iterator begin() const; - const_iterator end() const; - - iterator begin(); - iterator end(); - - // Accessors for the [start, limit) range of bytes within the JSON text from - // which this value was parsed, if any. - void setOffsetStart(ptrdiff_t start); - void setOffsetLimit(ptrdiff_t limit); - ptrdiff_t getOffsetStart() const; - ptrdiff_t getOffsetLimit() const; - -private: - void initBasic(ValueType type, bool allocated = false); - - Value& resolveReference(const char* key); - Value& resolveReference(const char* key, const char* end); - - struct CommentInfo { - CommentInfo(); - ~CommentInfo(); - - void setComment(const char* text, size_t len); - - char* comment_; - }; - - // struct MemberNamesTransform - //{ - // typedef const char *result_type; - // const char *operator()( const CZString &name ) const - // { - // return name.c_str(); - // } - //}; - - union ValueHolder { - LargestInt int_; - LargestUInt uint_; - double real_; - bool bool_; - char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ - ObjectValues* map_; - } value_; - ValueType type_ : 8; - unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. - // If not allocated_, string_ must be null-terminated. - CommentInfo* comments_; - - // [start, limit) byte offsets in the source JSON text from which this Value - // was extracted. - ptrdiff_t start_; - ptrdiff_t limit_; -}; - -/** \brief Experimental and untested: represents an element of the "path" to - * access a node. - */ -class JSON_API PathArgument { -public: - friend class Path; - - PathArgument(); - PathArgument(ArrayIndex index); - PathArgument(const char* key); - PathArgument(const JSONCPP_STRING& key); - -private: - enum Kind { - kindNone = 0, - kindIndex, - kindKey - }; - JSONCPP_STRING key_; - ArrayIndex index_; - Kind kind_; -}; - -/** \brief Experimental and untested: represents a "path" to access a node. - * - * Syntax: - * - "." => root node - * - ".[n]" => elements at index 'n' of root node (an array value) - * - ".name" => member named 'name' of root node (an object value) - * - ".name1.name2.name3" - * - ".[0][1][2].name1[3]" - * - ".%" => member name is provided as parameter - * - ".[%]" => index is provied as parameter - */ -class JSON_API Path { -public: - Path(const JSONCPP_STRING& path, - const PathArgument& a1 = PathArgument(), - const PathArgument& a2 = PathArgument(), - const PathArgument& a3 = PathArgument(), - const PathArgument& a4 = PathArgument(), - const PathArgument& a5 = PathArgument()); - - const Value& resolve(const Value& root) const; - Value resolve(const Value& root, const Value& defaultValue) const; - /// Creates the "path" to access the specified node and returns a reference on - /// the node. - Value& make(Value& root) const; - -private: - typedef std::vector InArgs; - typedef std::vector Args; - - void makePath(const JSONCPP_STRING& path, const InArgs& in); - void addPathInArg(const JSONCPP_STRING& path, - const InArgs& in, - InArgs::const_iterator& itInArg, - PathArgument::Kind kind); - void invalidPath(const JSONCPP_STRING& path, int location); - - Args args_; -}; - -/** \brief base class for Value iterators. - * - */ -class JSON_API ValueIteratorBase { -public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef unsigned int size_t; - typedef int difference_type; - typedef ValueIteratorBase SelfType; - - bool operator==(const SelfType& other) const { return isEqual(other); } - - bool operator!=(const SelfType& other) const { return !isEqual(other); } - - difference_type operator-(const SelfType& other) const { - return other.computeDistance(*this); - } - - /// Return either the index or the member name of the referenced value as a - /// Value. - Value key() const; - - /// Return the index of the referenced Value, or -1 if it is not an arrayValue. - UInt index() const; - - /// Return the member name of the referenced Value, or "" if it is not an - /// objectValue. - /// \note Avoid `c_str()` on result, as embedded zeroes are possible. - JSONCPP_STRING name() const; - - /// Return the member name of the referenced Value. "" if it is not an - /// objectValue. - /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. - JSONCPP_DEPRECATED("Use `key = name();` instead.") - char const* memberName() const; - /// Return the member name of the referenced Value, or NULL if it is not an - /// objectValue. - /// \note Better version than memberName(). Allows embedded nulls. - char const* memberName(char const** end) const; - -protected: - Value& deref() const; - - void increment(); - - void decrement(); - - difference_type computeDistance(const SelfType& other) const; - - bool isEqual(const SelfType& other) const; - - void copy(const SelfType& other); - -private: - Value::ObjectValues::iterator current_; - // Indicates that iterator is for a null value. - bool isNull_; - -public: - // For some reason, BORLAND needs these at the end, rather - // than earlier. No idea why. - ValueIteratorBase(); - explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); -}; - -/** \brief const iterator for object and array value. - * - */ -class JSON_API ValueConstIterator : public ValueIteratorBase { - friend class Value; - -public: - typedef const Value value_type; - //typedef unsigned int size_t; - //typedef int difference_type; - typedef const Value& reference; - typedef const Value* pointer; - typedef ValueConstIterator SelfType; - - ValueConstIterator(); - ValueConstIterator(ValueIterator const& other); - -private: -/*! \internal Use by Value to create an iterator. - */ - explicit ValueConstIterator(const Value::ObjectValues::iterator& current); -public: - SelfType& operator=(const ValueIteratorBase& other); - - SelfType operator++(int) { - SelfType temp(*this); - ++*this; - return temp; - } - - SelfType operator--(int) { - SelfType temp(*this); - --*this; - return temp; - } - - SelfType& operator--() { - decrement(); - return *this; - } - - SelfType& operator++() { - increment(); - return *this; - } - - reference operator*() const { return deref(); } - - pointer operator->() const { return &deref(); } -}; - -/** \brief Iterator for object and array value. - */ -class JSON_API ValueIterator : public ValueIteratorBase { - friend class Value; - -public: - typedef Value value_type; - typedef unsigned int size_t; - typedef int difference_type; - typedef Value& reference; - typedef Value* pointer; - typedef ValueIterator SelfType; - - ValueIterator(); - explicit ValueIterator(const ValueConstIterator& other); - ValueIterator(const ValueIterator& other); - -private: -/*! \internal Use by Value to create an iterator. - */ - explicit ValueIterator(const Value::ObjectValues::iterator& current); -public: - SelfType& operator=(const SelfType& other); - - SelfType operator++(int) { - SelfType temp(*this); - ++*this; - return temp; - } - - SelfType operator--(int) { - SelfType temp(*this); - --*this; - return temp; - } - - SelfType& operator--() { - decrement(); - return *this; - } - - SelfType& operator++() { - increment(); - return *this; - } - - reference operator*() const { return deref(); } - - pointer operator->() const { return &deref(); } -}; - -} // namespace Json - - -namespace std { -/// Specialize std::swap() for Json::Value. -template<> -inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } -} - - -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(pop) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -#endif // CPPTL_JSON_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/value.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/reader.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef CPPTL_JSON_READER_H_INCLUDED -#define CPPTL_JSON_READER_H_INCLUDED - -#if !defined(JSON_IS_AMALGAMATION) -#include "features.h" -#include "value.h" -#endif // if !defined(JSON_IS_AMALGAMATION) -#include -#include -#include -#include -#include - -// Disable warning C4251: : needs to have dll-interface to -// be used by... -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(push) -#pragma warning(disable : 4251) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -namespace Json { - -/** \brief Unserialize a JSON document into a - *Value. - * - * \deprecated Use CharReader and CharReaderBuilder. - */ -class JSON_API Reader { -public: - typedef char Char; - typedef const Char* Location; - - /** \brief An error tagged with where in the JSON text it was encountered. - * - * The offsets give the [start, limit) range of bytes within the text. Note - * that this is bytes, not codepoints. - * - */ - struct StructuredError { - ptrdiff_t offset_start; - ptrdiff_t offset_limit; - JSONCPP_STRING message; - }; - - /** \brief Constructs a Reader allowing all features - * for parsing. - */ - Reader(); - - /** \brief Constructs a Reader allowing the specified feature set - * for parsing. - */ - Reader(const Features& features); - - /** \brief Read a Value from a JSON - * document. - * \param document UTF-8 encoded string containing the document to read. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them - * back during - * serialization, \c false to discard comments. - * This parameter is ignored if - * Features::allowComments_ - * is \c false. - * \return \c true if the document was successfully parsed, \c false if an - * error occurred. - */ - bool - parse(const std::string& document, Value& root, bool collectComments = true); - - /** \brief Read a Value from a JSON - document. - * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the - document to read. - * \param endDoc Pointer on the end of the UTF-8 encoded string of the - document to read. - * Must be >= beginDoc. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them - back during - * serialization, \c false to discard comments. - * This parameter is ignored if - Features::allowComments_ - * is \c false. - * \return \c true if the document was successfully parsed, \c false if an - error occurred. - */ - bool parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments = true); - - /// \brief Parse from input stream. - /// \see Json::operator>>(std::istream&, Json::Value&). - bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); - - /** \brief Returns a user friendly string that list errors in the parsed - * document. - * \return Formatted error message with the list of errors with their location - * in - * the parsed document. An empty string is returned if no error - * occurred - * during parsing. - * \deprecated Use getFormattedErrorMessages() instead (typo fix). - */ - JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") - JSONCPP_STRING getFormatedErrorMessages() const; - - /** \brief Returns a user friendly string that list errors in the parsed - * document. - * \return Formatted error message with the list of errors with their location - * in - * the parsed document. An empty string is returned if no error - * occurred - * during parsing. - */ - JSONCPP_STRING getFormattedErrorMessages() const; - - /** \brief Returns a vector of structured erros encounted while parsing. - * \return A (possibly empty) vector of StructuredError objects. Currently - * only one error can be returned, but the caller should tolerate - * multiple - * errors. This can occur if the parser recovers from a non-fatal - * parse error and then encounters additional errors. - */ - std::vector getStructuredErrors() const; - - /** \brief Add a semantic error message. - * \param value JSON Value location associated with the error - * \param message The error message. - * \return \c true if the error was successfully added, \c false if the - * Value offset exceeds the document size. - */ - bool pushError(const Value& value, const JSONCPP_STRING& message); - - /** \brief Add a semantic error message with extra context. - * \param value JSON Value location associated with the error - * \param message The error message. - * \param extra Additional JSON Value location to contextualize the error - * \return \c true if the error was successfully added, \c false if either - * Value offset exceeds the document size. - */ - bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); - - /** \brief Return whether there are any errors. - * \return \c true if there are no errors to report \c false if - * errors have occurred. - */ - bool good() const; - -private: - enum TokenType { - tokenEndOfStream = 0, - tokenObjectBegin, - tokenObjectEnd, - tokenArrayBegin, - tokenArrayEnd, - tokenString, - tokenNumber, - tokenTrue, - tokenFalse, - tokenNull, - tokenArraySeparator, - tokenMemberSeparator, - tokenComment, - tokenError - }; - - class Token { - public: - TokenType type_; - Location start_; - Location end_; - }; - - class ErrorInfo { - public: - Token token_; - JSONCPP_STRING message_; - Location extra_; - }; - - typedef std::deque Errors; - - bool readToken(Token& token); - void skipSpaces(); - bool match(Location pattern, int patternLength); - bool readComment(); - bool readCStyleComment(); - bool readCppStyleComment(); - bool readString(); - void readNumber(); - bool readValue(); - bool readObject(Token& token); - bool readArray(Token& token); - bool decodeNumber(Token& token); - bool decodeNumber(Token& token, Value& decoded); - bool decodeString(Token& token); - bool decodeString(Token& token, JSONCPP_STRING& decoded); - bool decodeDouble(Token& token); - bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); - bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const JSONCPP_STRING& message, - Token& token, - TokenType skipUntilToken); - void skipUntilSpace(); - Value& currentValue(); - Char getNextChar(); - void - getLocationLineAndColumn(Location location, int& line, int& column) const; - JSONCPP_STRING getLocationLineAndColumn(Location location) const; - void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); - - typedef std::stack Nodes; - Nodes nodes_; - Errors errors_; - JSONCPP_STRING document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value* lastValue_; - JSONCPP_STRING commentsBefore_; - Features features_; - bool collectComments_; -}; // Reader - -/** Interface for reading JSON from a char array. - */ -class JSON_API CharReader { -public: - virtual ~CharReader() {} - /** \brief Read a Value from a JSON - document. - * The document must be a UTF-8 encoded string containing the document to read. - * - * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the - document to read. - * \param endDoc Pointer on the end of the UTF-8 encoded string of the - document to read. - * Must be >= beginDoc. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param errs [out] Formatted error messages (if not NULL) - * a user friendly string that lists errors in the parsed - * document. - * \return \c true if the document was successfully parsed, \c false if an - error occurred. - */ - virtual bool parse( - char const* beginDoc, char const* endDoc, - Value* root, JSONCPP_STRING* errs) = 0; - - class JSON_API Factory { - public: - virtual ~Factory() {} - /** \brief Allocate a CharReader via operator new(). - * \throw std::exception if something goes wrong (e.g. invalid settings) - */ - virtual CharReader* newCharReader() const = 0; - }; // Factory -}; // CharReader - -/** \brief Build a CharReader implementation. - -Usage: -\code - using namespace Json; - CharReaderBuilder builder; - builder["collectComments"] = false; - Value value; - JSONCPP_STRING errs; - bool ok = parseFromStream(builder, std::cin, &value, &errs); -\endcode -*/ -class JSON_API CharReaderBuilder : public CharReader::Factory { -public: - // Note: We use a Json::Value so that we can add data-members to this class - // without a major version bump. - /** Configuration of this builder. - These are case-sensitive. - Available settings (case-sensitive): - - `"collectComments": false or true` - - true to collect comment and allow writing them - back during serialization, false to discard comments. - This parameter is ignored if allowComments is false. - - `"allowComments": false or true` - - true if comments are allowed. - - `"strictRoot": false or true` - - true if root must be either an array or an object value - - `"allowDroppedNullPlaceholders": false or true` - - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) - - `"allowNumericKeys": false or true` - - true if numeric object keys are allowed. - - `"allowSingleQuotes": false or true` - - true if '' are allowed for strings (both keys and values) - - `"stackLimit": integer` - - Exceeding stackLimit (recursive depth of `readValue()`) will - cause an exception. - - This is a security issue (seg-faults caused by deeply nested JSON), - so the default is low. - - `"failIfExtra": false or true` - - If true, `parse()` returns false when extra non-whitespace trails - the JSON value in the input string. - - `"rejectDupKeys": false or true` - - If true, `parse()` returns false when a key is duplicated within an object. - - `"allowSpecialFloats": false or true` - - If true, special float values (NaNs and infinities) are allowed - and their values are lossfree restorable. - - You can examine 'settings_` yourself - to see the defaults. You can also write and read them just like any - JSON Value. - \sa setDefaults() - */ - Json::Value settings_; - - CharReaderBuilder(); - ~CharReaderBuilder() JSONCPP_OVERRIDE; - - CharReader* newCharReader() const JSONCPP_OVERRIDE; - - /** \return true if 'settings' are legal and consistent; - * otherwise, indicate bad settings via 'invalid'. - */ - bool validate(Json::Value* invalid) const; - - /** A simple way to update a specific setting. - */ - Value& operator[](JSONCPP_STRING key); - - /** Called by ctor, but you can use this to reset settings_. - * \pre 'settings' != NULL (but Json::null is fine) - * \remark Defaults: - * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults - */ - static void setDefaults(Json::Value* settings); - /** Same as old Features::strictMode(). - * \pre 'settings' != NULL (but Json::null is fine) - * \remark Defaults: - * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode - */ - static void strictMode(Json::Value* settings); -}; - -/** Consume entire stream and use its begin/end. - * Someday we might have a real StreamReader, but for now this - * is convenient. - */ -bool JSON_API parseFromStream( - CharReader::Factory const&, - JSONCPP_ISTREAM&, - Value* root, std::string* errs); - -/** \brief Read from 'sin' into 'root'. - - Always keep comments from the input JSON. - - This can be used to read a file into a particular sub-object. - For example: - \code - Json::Value root; - cin >> root["dir"]["file"]; - cout << root; - \endcode - Result: - \verbatim - { - "dir": { - "file": { - // The input stream JSON would be nested here. - } - } - } - \endverbatim - \throw std::exception on parse error. - \see Json::operator<<() -*/ -JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); - -} // namespace Json - -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(pop) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -#endif // CPPTL_JSON_READER_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/reader.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/writer.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef JSON_WRITER_H_INCLUDED -#define JSON_WRITER_H_INCLUDED - -#if !defined(JSON_IS_AMALGAMATION) -#include "value.h" -#endif // if !defined(JSON_IS_AMALGAMATION) -#include -#include -#include - -// Disable warning C4251: : needs to have dll-interface to -// be used by... -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(push) -#pragma warning(disable : 4251) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -namespace Json { - -class Value; - -/** - -Usage: -\code - using namespace Json; - void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { - std::unique_ptr const writer( - factory.newStreamWriter()); - writer->write(value, &std::cout); - std::cout << std::endl; // add lf and flush - } -\endcode -*/ -class JSON_API StreamWriter { -protected: - JSONCPP_OSTREAM* sout_; // not owned; will not delete -public: - StreamWriter(); - virtual ~StreamWriter(); - /** Write Value into document as configured in sub-class. - Do not take ownership of sout, but maintain a reference during function. - \pre sout != NULL - \return zero on success (For now, we always return zero, so check the stream instead.) - \throw std::exception possibly, depending on configuration - */ - virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; - - /** \brief A simple abstract factory. - */ - class JSON_API Factory { - public: - virtual ~Factory(); - /** \brief Allocate a CharReader via operator new(). - * \throw std::exception if something goes wrong (e.g. invalid settings) - */ - virtual StreamWriter* newStreamWriter() const = 0; - }; // Factory -}; // StreamWriter - -/** \brief Write into stringstream, then return string, for convenience. - * A StreamWriter will be created from the factory, used, and then deleted. - */ -JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); - - -/** \brief Build a StreamWriter implementation. - -Usage: -\code - using namespace Json; - Value value = ...; - StreamWriterBuilder builder; - builder["commentStyle"] = "None"; - builder["indentation"] = " "; // or whatever you like - std::unique_ptr writer( - builder.newStreamWriter()); - writer->write(value, &std::cout); - std::cout << std::endl; // add lf and flush -\endcode -*/ -class JSON_API StreamWriterBuilder : public StreamWriter::Factory { -public: - // Note: We use a Json::Value so that we can add data-members to this class - // without a major version bump. - /** Configuration of this builder. - Available settings (case-sensitive): - - "commentStyle": "None" or "All" - - "indentation": "" - - "enableYAMLCompatibility": false or true - - slightly change the whitespace around colons - - "dropNullPlaceholders": false or true - - Drop the "null" string from the writer's output for nullValues. - Strictly speaking, this is not valid JSON. But when the output is being - fed to a browser's Javascript, it makes for smaller output and the - browser can handle the output just fine. - - "useSpecialFloats": false or true - - If true, outputs non-finite floating point values in the following way: - NaN values as "NaN", positive infinity as "Infinity", and negative infinity - as "-Infinity". - - You can examine 'settings_` yourself - to see the defaults. You can also write and read them just like any - JSON Value. - \sa setDefaults() - */ - Json::Value settings_; - - StreamWriterBuilder(); - ~StreamWriterBuilder() JSONCPP_OVERRIDE; - - /** - * \throw std::exception if something goes wrong (e.g. invalid settings) - */ - StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; - - /** \return true if 'settings' are legal and consistent; - * otherwise, indicate bad settings via 'invalid'. - */ - bool validate(Json::Value* invalid) const; - /** A simple way to update a specific setting. - */ - Value& operator[](JSONCPP_STRING key); - - /** Called by ctor, but you can use this to reset settings_. - * \pre 'settings' != NULL (but Json::null is fine) - * \remark Defaults: - * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults - */ - static void setDefaults(Json::Value* settings); -}; - -/** \brief Abstract class for writers. - * \deprecated Use StreamWriter. (And really, this is an implementation detail.) - */ -class JSON_API Writer { -public: - virtual ~Writer(); - - virtual JSONCPP_STRING write(const Value& root) = 0; -}; - -/** \brief Outputs a Value in JSON format - *without formatting (not human friendly). - * - * The JSON document is written in a single line. It is not intended for 'human' - *consumption, - * but may be usefull to support feature such as RPC where bandwith is limited. - * \sa Reader, Value - * \deprecated Use StreamWriterBuilder. - */ -class JSON_API FastWriter : public Writer { - -public: - FastWriter(); - ~FastWriter() JSONCPP_OVERRIDE {} - - void enableYAMLCompatibility(); - - /** \brief Drop the "null" string from the writer's output for nullValues. - * Strictly speaking, this is not valid JSON. But when the output is being - * fed to a browser's Javascript, it makes for smaller output and the - * browser can handle the output just fine. - */ - void dropNullPlaceholders(); - - void omitEndingLineFeed(); - -public: // overridden from Writer - JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; - -private: - void writeValue(const Value& value); - - JSONCPP_STRING document_; - bool yamlCompatiblityEnabled_; - bool dropNullPlaceholders_; - bool omitEndingLineFeed_; -}; - -/** \brief Writes a Value in JSON format in a - *human friendly way. - * - * The rules for line break and indent are as follow: - * - Object value: - * - if empty then print {} without indent and line break - * - if not empty the print '{', line break & indent, print one value per - *line - * and then unindent and line break and print '}'. - * - Array value: - * - if empty then print [] without indent and line break - * - if the array contains no object value, empty array or some other value - *types, - * and all the values fit on one lines, then print the array on a single - *line. - * - otherwise, it the values do not fit on one line, or the array contains - * object or non empty array, then print one value per line. - * - * If the Value have comments then they are outputed according to their - *#CommentPlacement. - * - * \sa Reader, Value, Value::setComment() - * \deprecated Use StreamWriterBuilder. - */ -class JSON_API StyledWriter : public Writer { -public: - StyledWriter(); - ~StyledWriter() JSONCPP_OVERRIDE {} - -public: // overridden from Writer - /** \brief Serialize a Value in JSON format. - * \param root Value to serialize. - * \return String containing the JSON document that represents the root value. - */ - JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; - -private: - void writeValue(const Value& value); - void writeArrayValue(const Value& value); - bool isMultineArray(const Value& value); - void pushValue(const JSONCPP_STRING& value); - void writeIndent(); - void writeWithIndent(const JSONCPP_STRING& value); - void indent(); - void unindent(); - void writeCommentBeforeValue(const Value& root); - void writeCommentAfterValueOnSameLine(const Value& root); - bool hasCommentForValue(const Value& value); - static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); - - typedef std::vector ChildValues; - - ChildValues childValues_; - JSONCPP_STRING document_; - JSONCPP_STRING indentString_; - unsigned int rightMargin_; - unsigned int indentSize_; - bool addChildValues_; -}; - -/** \brief Writes a Value in JSON format in a - human friendly way, - to a stream rather than to a string. - * - * The rules for line break and indent are as follow: - * - Object value: - * - if empty then print {} without indent and line break - * - if not empty the print '{', line break & indent, print one value per - line - * and then unindent and line break and print '}'. - * - Array value: - * - if empty then print [] without indent and line break - * - if the array contains no object value, empty array or some other value - types, - * and all the values fit on one lines, then print the array on a single - line. - * - otherwise, it the values do not fit on one line, or the array contains - * object or non empty array, then print one value per line. - * - * If the Value have comments then they are outputed according to their - #CommentPlacement. - * - * \param indentation Each level will be indented by this amount extra. - * \sa Reader, Value, Value::setComment() - * \deprecated Use StreamWriterBuilder. - */ -class JSON_API StyledStreamWriter { -public: - StyledStreamWriter(JSONCPP_STRING indentation = "\t"); - ~StyledStreamWriter() {} - -public: - /** \brief Serialize a Value in JSON format. - * \param out Stream to write to. (Can be ostringstream, e.g.) - * \param root Value to serialize. - * \note There is no point in deriving from Writer, since write() should not - * return a value. - */ - void write(JSONCPP_OSTREAM& out, const Value& root); - -private: - void writeValue(const Value& value); - void writeArrayValue(const Value& value); - bool isMultineArray(const Value& value); - void pushValue(const JSONCPP_STRING& value); - void writeIndent(); - void writeWithIndent(const JSONCPP_STRING& value); - void indent(); - void unindent(); - void writeCommentBeforeValue(const Value& root); - void writeCommentAfterValueOnSameLine(const Value& root); - bool hasCommentForValue(const Value& value); - static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); - - typedef std::vector ChildValues; - - ChildValues childValues_; - JSONCPP_OSTREAM* document_; - JSONCPP_STRING indentString_; - unsigned int rightMargin_; - JSONCPP_STRING indentation_; - bool addChildValues_ : 1; - bool indented_ : 1; -}; - -#if defined(JSON_HAS_INT64) -JSONCPP_STRING JSON_API valueToString(Int value); -JSONCPP_STRING JSON_API valueToString(UInt value); -#endif // if defined(JSON_HAS_INT64) -JSONCPP_STRING JSON_API valueToString(LargestInt value); -JSONCPP_STRING JSON_API valueToString(LargestUInt value); -JSONCPP_STRING JSON_API valueToString(double value); -JSONCPP_STRING JSON_API valueToString(bool value); -JSONCPP_STRING JSON_API valueToQuotedString(const char* value); - -/// \brief Output using the StyledStreamWriter. -/// \see Json::operator>>() -JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root); - -} // namespace Json - -#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma warning(pop) -#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) - -#endif // JSON_WRITER_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/writer.h -// ////////////////////////////////////////////////////////////////////// - - - - - - -// ////////////////////////////////////////////////////////////////////// -// Beginning of content of file: include/json/assertions.h -// ////////////////////////////////////////////////////////////////////// - -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED -#define CPPTL_JSON_ASSERTIONS_H_INCLUDED - -#include -#include - -#if !defined(JSON_IS_AMALGAMATION) -#include "config.h" -#endif // if !defined(JSON_IS_AMALGAMATION) - -/** It should not be possible for a maliciously designed file to - * cause an abort() or seg-fault, so these macros are used only - * for pre-condition violations and internal logic errors. - */ -#if JSON_USE_EXCEPTION - -// @todo <= add detail about condition in exception -# define JSON_ASSERT(condition) \ - {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} - -# define JSON_FAIL_MESSAGE(message) \ - { \ - JSONCPP_OSTRINGSTREAM oss; oss << message; \ - Json::throwLogicError(oss.str()); \ - abort(); \ - } - -#else // JSON_USE_EXCEPTION - -# define JSON_ASSERT(condition) assert(condition) - -// The call to assert() will show the failure message in debug builds. In -// release builds we abort, for a core-dump or debugger. -# define JSON_FAIL_MESSAGE(message) \ - { \ - JSONCPP_OSTRINGSTREAM oss; oss << message; \ - assert(false && oss.str().c_str()); \ - abort(); \ - } - - -#endif - -#define JSON_ASSERT_MESSAGE(condition, message) \ - if (!(condition)) { \ - JSON_FAIL_MESSAGE(message); \ - } - -#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED - -// ////////////////////////////////////////////////////////////////////// -// End of content of file: include/json/assertions.h -// ////////////////////////////////////////////////////////////////////// - - - - - -#endif //ifndef JSON_AMALGATED_H_INCLUDED -- libgit2 0.21.4