std::string Value::toJSON() const { std::string result; switch(_type){ case UNDEFINED: result = "null"; break; case INT32: result = std::to_string(_int32Value); break; case INT64: result = std::to_string(_int64Value); break; case DOUBLE: result = std::to_string(_doubleValue); break; case BOOL: result = _boolValue ? "true" : "false"; break; case STRING: result = "\""+escapeJSON(_stringValue)+"\""; break; case BINARY: throw std::runtime_error{"BINARY data type is not representable in json"}; break; case DATETIME: result = std::to_string(_datetimeValue.count()); break; case ARRAY: result = "["; if( this->size() )for( size_t i = 0; i <= size()-1; ++i ) { result += _arrayValue[i].toJSON(); if( i < size()-1 ) { result += ","; } } result += "]"; break; case OBJECT: result += "{"; size_t current = 0; for( auto & kv : _objectValue ) { result += "\""; result += escapeJSON( kv.first ); result += "\":"; result += kv.second.toJSON(); if( current++ < size()-1 ) { result += ","; } } result += "}"; break; } return result; }
EXPORT char * Z$F_F2J (char * sz) { int len = strlen(sz); char * sz_result = (char *) ib_util_malloc (len*2+4); escapeJSON(sz,sz_result); return sz_result; }
int rrd_xport_format_addprints(int flags,stringbuffer_t *buffer,image_desc_t *im) { /* initialize buffer */ stringbuffer_t prints={1024,0,NULL,NULL}; stringbuffer_t rules={1024,0,NULL,NULL}; stringbuffer_t gprints={4096,0,NULL,NULL}; char buf[256]; char dbuf[1024]; char* val; char* timefmt=NULL; if (im->xlab_user.minsec!=-1.0) { timefmt=im->xlab_user.stst; } /* define some other stuff based on flags */ int json=0; if (flags &1) { json=1; } // int showtime=0; if (flags &2) { showtime=1;} -> unused here // int enumds=0; if (flags &4) { enumds=1;} -> unused here /* define some values */ time_t now = time(NULL); struct tm tmvdef; localtime_r(&now, &tmvdef); double printval=DNAN; /* iterate over all fields and start the work writing to the correct buffers */ for (long i = 0; i < im->gdes_c; i++) { long vidx = im->gdes[i].vidx; char* entry; switch (im->gdes[i].gf) { case GF_PRINT: case GF_GPRINT: { /* PRINT and GPRINT can now print VDEF generated values. * There's no need to do any calculations on them as these * calculations were already made. * we do not support the deprecated version here */ printval=DNAN; /* decide to which buffer we print to*/ stringbuffer_t *usebuffer=&gprints; char* usetag="gprint"; if (im->gdes[i].gf==GF_PRINT) { usebuffer=&prints; usetag="print"; } /* get the value */ if (im->gdes[vidx].gf == GF_VDEF) { /* simply use vals */ printval = im->gdes[vidx].vf.val; localtime_r(&im->gdes[vidx].vf.when, &tmvdef); } else { int max_ii = ((im->gdes[vidx].end - im->gdes[vidx].start) / im->gdes[vidx].step * im->gdes[vidx].ds_cnt); printval = DNAN; long validsteps = 0; for (long ii = im->gdes[vidx].ds; ii < max_ii; ii += im->gdes[vidx].ds_cnt) { if (!finite(im->gdes[vidx].data[ii])) continue; if (isnan(printval)) { printval = im->gdes[vidx].data[ii]; validsteps++; continue; } switch (im->gdes[i].cf) { case CF_HWPREDICT: case CF_MHWPREDICT: case CF_DEVPREDICT: case CF_DEVSEASONAL: case CF_SEASONAL: case CF_AVERAGE: validsteps++; printval += im->gdes[vidx].data[ii]; break; case CF_MINIMUM: printval = min(printval, im->gdes[vidx].data[ii]); break; case CF_FAILURES: case CF_MAXIMUM: printval = max(printval, im->gdes[vidx].data[ii]); break; case CF_LAST: printval = im->gdes[vidx].data[ii]; } } if (im->gdes[i].cf == CF_AVERAGE || im->gdes[i].cf > CF_LAST) { if (validsteps > 1) { printval = (printval / validsteps); } } } /* we handle PRINT and GPRINT the same - format now*/ if (im->gdes[i].strftm) { if (im->gdes[vidx].vf.never == 1) { time_clean(buf, im->gdes[i].format); } else { strftime(dbuf,sizeof(dbuf), im->gdes[i].format, &tmvdef); } } else if (bad_format_print(im->gdes[i].format)) { rrd_set_error ("bad format for PRINT in \"%s'", im->gdes[i].format); return -1; } else { rrd_snprintf(dbuf,sizeof(dbuf), im->gdes[i].format, printval,""); } /* print */ if (json) { escapeJSON(dbuf,sizeof(dbuf)); snprintf(buf,sizeof(buf),",\n { \"%s\": \"%s\" }",usetag,dbuf); } else { snprintf(buf,sizeof(buf)," <%s>%s</%s>\n",usetag,dbuf,usetag); } addToBuffer(usebuffer,buf,0); } break; case GF_COMMENT: if (json) { strncpy(dbuf,im->gdes[i].legend,sizeof(dbuf)); escapeJSON(dbuf,sizeof(dbuf)); snprintf(buf,sizeof(buf),",\n { \"comment\": \"%s\" }",dbuf); } else { snprintf(buf,sizeof(buf)," <comment>%s</comment>\n",im->gdes[i].legend); } addToBuffer(&gprints,buf,0); break; case GF_LINE: entry = im->gdes[i].legend; /* I do not know why the legend is "spaced", but let us skip it */ while(isspace(*entry)){entry++;} if (json) { snprintf(buf,sizeof(buf),",\n { \"line\": \"%s\" }",entry); } else { snprintf(buf,sizeof(buf)," <line>%s</line>\n",entry); } addToBuffer(&gprints,buf,0); break; case GF_AREA: if (json) { snprintf(buf,sizeof(buf),",\n { \"area\": \"%s\" }",im->gdes[i].legend); } else { snprintf(buf,sizeof(buf)," <area>%s</area>\n",im->gdes[i].legend); } addToBuffer(&gprints,buf,0); break; case GF_STACK: if (json) { snprintf(buf,sizeof(buf),",\n { \"stack\": \"%s\" }",im->gdes[i].legend); } else { snprintf(buf,sizeof(buf)," <stack>%s</stack>\n",im->gdes[i].legend); } addToBuffer(&gprints,buf,0); break; case GF_TEXTALIGN: val=""; switch (im->gdes[i].txtalign) { case TXA_LEFT: val="left"; break; case TXA_RIGHT: val="right"; break; case TXA_CENTER: val="center"; break; case TXA_JUSTIFIED: val="justified"; break; } if (json) { snprintf(buf,sizeof(buf),",\n { \"align\": \"%s\" }",val); } else { snprintf(buf,sizeof(buf)," <align>%s</align>\n",val); } addToBuffer(&gprints,buf,0); break; case GF_HRULE: /* This does not work as expected - Tobi please help!!! */ rrd_snprintf(dbuf,sizeof(dbuf),"%0.10e",im->gdes[i].vf.val); /* and output it */ if (json) { snprintf(buf,sizeof(buf),",\n { \"hrule\": \"%s\" }",dbuf); } else { snprintf(buf,sizeof(buf)," <hrule>%s</hrule>\n",dbuf); } addToBuffer(&rules,buf,0); break; case GF_VRULE: if (timefmt) { struct tm loc; localtime_r(&im->gdes[i].xrule,&loc); strftime(dbuf,254,timefmt,&loc); } else { snprintf(dbuf,254,"%lld",(long long int)im->gdes[i].vf.when); } /* and output it */ if (json) { snprintf(buf,sizeof(buf),",\n { \"vrule\": \"%s\" }",dbuf); } else { snprintf(buf,sizeof(buf)," <vrule>%s</vrule>\n",dbuf); } addToBuffer(&rules,buf,0); break; default: break; } } /* now add prints */ if (prints.len) { if (json){ snprintf(buf,sizeof(buf)," \"%s\": [\n","prints"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)prints.data+2,prints.len-2); addToBuffer(buffer,"\n ],\n",0); } else { snprintf(buf,sizeof(buf)," <%s>\n", "prints"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)prints.data,prints.len); snprintf(buf,sizeof(buf)," </%s>\n", "prints"); addToBuffer(buffer,buf,0); } free(prints.data); } /* now add gprints */ if (gprints.len) { if (json){ snprintf(buf,sizeof(buf)," ,\"%s\": [\n","gprints"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)gprints.data+2,gprints.len-2); addToBuffer(buffer,"\n ]\n",0); } else { snprintf(buf,sizeof(buf)," <%s>\n", "gprints"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)gprints.data,gprints.len); snprintf(buf,sizeof(buf)," </%s>\n", "gprints"); addToBuffer(buffer,buf,0); } free(gprints.data); } /* now add rules */ if (rules.len) { if (json){ snprintf(buf,sizeof(buf)," ,\"%s\": [\n","rules"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)rules.data+2,rules.len-2); addToBuffer(buffer,"\n ]\n",0); } else { snprintf(buf,sizeof(buf)," <%s>\n", "rules"); addToBuffer(buffer,buf,0); addToBuffer(buffer,(char*)rules.data,rules.len); snprintf(buf,sizeof(buf)," </%s>\n", "rules"); addToBuffer(buffer,buf,0); } free(rules.data); } /* and return */ return 0; }