Blynk library for embedded hardware. Works with Arduino, ESP8266, Raspberry Pi, Intel Edison/Galileo, LinkIt ONE, Particle Core/Photon, Energia, ARM mbed, etc. http://www.blynk.cc/

Dependents:   Blynk_RBL_BLE_Nano Blynk_MicroBit Blynk_Serial Blynk_RBL_BLE_Nano

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlynkParam.h Source File

BlynkParam.h

Go to the documentation of this file.
00001 /**
00002  * @file       BlynkParam.h
00003  * @author     Volodymyr Shymanskyy
00004  * @license    This project is released under the MIT License (MIT)
00005  * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
00006  * @date       Jan 2015
00007  * @brief      Container for handler parameters
00008  *
00009  */
00010 
00011 #ifndef BlynkParam_h
00012 #define BlynkParam_h
00013 
00014 #include <string.h>
00015 #include <stdlib.h>
00016 #include <Blynk/BlynkConfig.h>
00017 #include <Blynk/BlynkDebug.h>
00018 
00019 #define BLYNK_PARAM_KV(k, v) k "\0" v "\0"
00020 
00021 class BlynkParam
00022 {
00023 public:
00024     class iterator
00025     {
00026     public:
00027         iterator(char* c) : ptr(c) {}
00028         static iterator invalid() { return iterator(NULL); }
00029 
00030         operator const char* () const   { return asStr(); }
00031         operator int () const           { return asInt(); }
00032         const char* asStr() const       { return ptr; }
00033         const char* asString() const    { return ptr; }
00034         int         asInt() const       { return atoi(ptr); }
00035         long        asLong() const      { return atol(ptr); }
00036         //long long   asLongLong() const  { return atoll(ptr); }
00037 #ifndef BLYNK_NO_FLOAT
00038         double      asDouble() const    { return atof(ptr); }
00039         float       asFloat() const     { return atof(ptr); }
00040 #endif
00041         bool isValid() const            { return ptr != NULL; }
00042         bool isEmpty() const            { return *ptr == '\0'; }
00043 
00044         bool operator <  (const iterator& it) const { return ptr < it.ptr; }
00045         bool operator >= (const iterator& it) const { return ptr >= it.ptr; }
00046 
00047         iterator& operator ++() {
00048             ptr += strlen(ptr)+1;
00049             return *this;
00050         }
00051     private:
00052         const char* ptr;
00053     };
00054 
00055 public:
00056     explicit
00057     BlynkParam(void* addr, size_t length)
00058         : buff((char*)addr), len(length), buff_size(length)
00059     {}
00060 
00061     explicit
00062     BlynkParam(void* addr, size_t length, size_t buffsize)
00063         : buff((char*)addr), len(length), buff_size(buffsize)
00064     {}
00065 
00066     const char* asStr() const       { return buff; }
00067     const char* asString() const    { return buff; }
00068     int         asInt() const       { return atoi(buff); }
00069     long        asLong() const      { return atol(buff); }
00070     //long long   asLongLong() const  { return atoll(buff); }
00071 #ifndef BLYNK_NO_FLOAT
00072     double      asDouble() const    { return atof(buff); }
00073     float       asFloat() const     { return atof(buff); }
00074 #endif
00075     bool isEmpty() const            { return *buff == '\0'; }
00076 
00077     iterator begin() const { return iterator(buff); }
00078     iterator end() const   { return iterator(buff+len); }
00079 
00080     iterator operator[](int index) const;
00081     iterator operator[](const char* key) const;
00082 
00083     void*  getBuffer() const { return (void*)buff; }
00084     size_t getLength() const { return len; }
00085 
00086     // Modification
00087     void add(int value);
00088     void add(unsigned int value);
00089     void add(long value);
00090     void add(unsigned long value);
00091     void add(long long value);
00092     void add(unsigned long long value);
00093 #ifndef BLYNK_NO_FLOAT
00094     void add(float value);
00095     void add(double value);
00096 #endif
00097     void add(const char* str);
00098     void add(const void* b, size_t l);
00099 #if defined(ARDUINO) || defined(SPARK) || defined(PARTICLE)
00100     void add(const String& str);
00101 #if defined(BLYNK_HAS_PROGMEM)
00102     void add(const __FlashStringHelper* str);
00103 #endif
00104 #endif
00105 
00106     template<typename T, typename... Args>
00107     void add_multi(T last) {
00108         add(last);
00109     }
00110 
00111     template<typename T, typename... Args>
00112     void add_multi(T head, Args... tail) {
00113         add(head);
00114         add_multi(tail...);
00115     }
00116 
00117     template <typename TV>
00118     void add_key(const char* key, const TV& val) {
00119         add(key);
00120         add(val);
00121     }
00122 
00123 protected:
00124     char*    buff;
00125     size_t   len;
00126     size_t   buff_size;
00127 };
00128 
00129 
00130 class BlynkParamAllocated
00131     : public BlynkParam
00132 {
00133 public:
00134     BlynkParamAllocated(size_t size)
00135         : BlynkParam(malloc(size), 0, size)
00136     {}
00137     ~BlynkParamAllocated() {
00138         free(buff);
00139     }
00140 };
00141 
00142 inline
00143 BlynkParam::iterator BlynkParam::operator[](int index) const
00144 {
00145     const iterator e = end();
00146     for (iterator it = begin(); it < e; ++it) {
00147         if (!index--) {
00148             return it;
00149         }
00150     }
00151     return iterator::invalid();
00152 }
00153 
00154 inline
00155 BlynkParam::iterator BlynkParam::operator[](const char* key) const
00156 {
00157     const iterator e = end();
00158     for (iterator it = begin(); it < e; ++it) {
00159         if (!strcmp(it.asStr(), key)) {
00160             return ++it;
00161         }
00162         ++it;
00163         if (it >= e) break;
00164     }
00165     return iterator::invalid();
00166 }
00167 
00168 inline
00169 void BlynkParam::add(const void* b, size_t l)
00170 {
00171     if (len + l > buff_size)
00172         return;
00173     memcpy(buff+len, b, l);
00174     len += l;
00175 }
00176 
00177 inline
00178 void BlynkParam::add(const char* str)
00179 {
00180     if (str == NULL) {
00181         buff[len++] = '\0';
00182         return;
00183     }
00184     add(str, strlen(str)+1);
00185 }
00186 
00187 #if defined(ARDUINO) || defined(SPARK) || defined(PARTICLE)
00188 inline
00189 void BlynkParam::add(const String& str)
00190 {
00191 #if defined(ARDUINO_AVR_DIGISPARK) \
00192     || defined(__ARDUINO_X86__) \
00193     || defined(__RFduino__)
00194 
00195     size_t len = str.length()+1;
00196     char buff[len];
00197     const_cast<String&>(str).toCharArray(buff, len);
00198     add(buff, len);
00199 #else
00200     add(str.c_str());
00201 #endif
00202 }
00203 
00204 #if defined(BLYNK_HAS_PROGMEM)
00205 
00206 inline
00207 void BlynkParam::add(const __FlashStringHelper* ifsh)
00208 {
00209     PGM_P p = reinterpret_cast<PGM_P>(ifsh);
00210     size_t l = strlen_P(p) + 1;
00211     if (len + l > buff_size)
00212         return;
00213     memcpy_P(buff+len, p, l);
00214     len += l;
00215     buff[len] = '\0';
00216 }
00217 
00218 #endif
00219 
00220 #endif
00221 
00222 #if defined(__AVR__) || defined (ARDUINO_ARCH_ARC32)
00223 
00224     #include <stdlib.h>
00225 
00226     inline
00227     void BlynkParam::add(int value)
00228     {
00229         char str[2 + 8 * sizeof(value)];
00230         itoa(value, str, 10);
00231         add(str);
00232     }
00233 
00234     inline
00235     void BlynkParam::add(unsigned int value)
00236     {
00237         char str[1 + 8 * sizeof(value)];
00238         utoa(value, str, 10);
00239         add(str);
00240     }
00241 
00242     inline
00243     void BlynkParam::add(long value)
00244     {
00245         char str[2 + 8 * sizeof(value)];
00246         ltoa(value, str, 10);
00247         add(str);
00248     }
00249 
00250     inline
00251     void BlynkParam::add(unsigned long value)
00252     {
00253         char str[1 + 8 * sizeof(value)];
00254         ultoa(value, str, 10);
00255         add(str);
00256     }
00257 
00258     inline
00259     void BlynkParam::add(long long value)  // TODO: this currently adds just a long
00260     {
00261         char str[2 + 8 * sizeof(value)];
00262         ltoa(value, str, 10);
00263         add(str);
00264     }
00265 
00266     inline
00267     void BlynkParam::add(unsigned long long value) // TODO: this currently adds just a long
00268     {
00269         char str[1 + 8 * sizeof(value)];
00270         ultoa(value, str, 10);
00271         add(str);
00272     }
00273 
00274 #ifndef BLYNK_NO_FLOAT
00275 
00276     inline
00277     void BlynkParam::add(float value)
00278     {
00279         char str[33];
00280         dtostrf(value, 5, 3, str);
00281         add(str);
00282     }
00283 
00284     inline
00285     void BlynkParam::add(double value)
00286     {
00287         char str[33];
00288         dtostrf(value, 5, 7, str);
00289         add(str);
00290     }
00291 #endif
00292 
00293 #else
00294 
00295     #include <stdio.h>
00296 
00297     inline
00298     void BlynkParam::add(int value)
00299     {
00300         len += snprintf(buff+len, buff_size-len, "%i", value)+1;
00301     }
00302 
00303     inline
00304     void BlynkParam::add(unsigned int value)
00305     {
00306         len += snprintf(buff+len, buff_size-len, "%u", value)+1;
00307     }
00308 
00309     inline
00310     void BlynkParam::add(long value)
00311     {
00312         len += snprintf(buff+len, buff_size-len, "%li", value)+1;
00313     }
00314 
00315     inline
00316     void BlynkParam::add(unsigned long value)
00317     {
00318         len += snprintf(buff+len, buff_size-len, "%lu", value)+1;
00319     }
00320 
00321     inline
00322     void BlynkParam::add(long long value)
00323     {
00324         len += snprintf(buff+len, buff_size-len, "%lli", value)+1;
00325     }
00326 
00327     inline
00328     void BlynkParam::add(unsigned long long value)
00329     {
00330         len += snprintf(buff+len, buff_size-len, "%llu", value)+1;
00331     }
00332 
00333 #ifndef BLYNK_NO_FLOAT
00334 
00335 #if defined(ESP8266)
00336 
00337     extern char* dtostrf_internal(double number, signed char width, unsigned char prec, char *s);
00338 
00339     inline
00340     void BlynkParam::add(float value)
00341     {
00342         char str[33];
00343         dtostrf_internal(value, 5, 3, str);
00344         add(str);
00345     }
00346 
00347     inline
00348     void BlynkParam::add(double value)
00349     {
00350         char str[33];
00351         dtostrf_internal(value, 5, 7, str);
00352         add(str);
00353     }
00354 
00355 #else
00356 
00357     inline
00358     void BlynkParam::add(float value)
00359     {
00360         len += snprintf(buff+len, buff_size-len, "%2.3f", value)+1;
00361     }
00362 
00363     inline
00364     void BlynkParam::add(double value)
00365     {
00366         len += snprintf(buff+len, buff_size-len, "%2.7f", value)+1;
00367     }
00368 
00369 #endif
00370 
00371 #endif
00372 
00373 #endif
00374 
00375 
00376 #endif