MIDAS
Loading...
Searching...
No Matches
mjsonrpc.cxx File Reference
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <map>
#include "mjson.h"
#include "midas.h"
#include "msystem.h"
#include "mstrlcpy.h"
#include "mjsonrpc.h"
#include <mutex>
#include "history.h"
Include dependency graph for mjsonrpc.cxx:

Go to the source code of this file.

Classes

class  JsonHistoryBuffer
 
class  BinaryHistoryBuffer
 
struct  EventStashEntry
 
struct  MethodsTableEntry
 
struct  NestedLine
 
class  NestedOutput
 

Typedefs

typedef std::map< std::string, MidasHistoryInterface * > MhiMap
 
typedef std::map< std::string, MethodsTableEntryMethodsTable
 
typedef MethodsTable::iterator MethodsTableIterator
 

Functions

static double GetTimeSec ()
 
MJsonNode * mjsonrpc_make_error (int code, const char *message, const char *data)
 
MJsonNode * mjsonrpc_make_result (MJsonNode *node)
 
MJsonNode * mjsonrpc_make_result (const char *name, MJsonNode *value, const char *name2, MJsonNode *value2, const char *name3, MJsonNode *value3)
 
MJsonNode * mjsonrpc_make_result (const char *name, MJsonNode *value, const char *name2, MJsonNode *value2, const char *name3, MJsonNode *value3, const char *name4, MJsonNode *value4)
 
const MJsonNode * mjsonrpc_get_param (const MJsonNode *params, const char *name, MJsonNode **error)
 
const MJsonNodeVectormjsonrpc_get_param_array (const MJsonNode *params, const char *name, MJsonNode **error)
 
static std::string remove (const std::string s, char c)
 
static MJsonNode * xnull (const MJsonNode *params)
 
static MJsonNode * js_cm_exist (const MJsonNode *params)
 
static MJsonNode * js_cm_shutdown (const MJsonNode *params)
 
static MJsonNode * start_program (const MJsonNode *params)
 
static MJsonNode * exec_script (const MJsonNode *params)
 
static int parse_array_index_list (const char *method, const char *path, std::vector< unsigned > *list)
 
static MJsonNode * js_db_get_values (const MJsonNode *params)
 
static MJsonNode * js_db_ls (const MJsonNode *params)
 
static MJsonNode * js_db_copy (const MJsonNode *params)
 
static MJsonNode * js_db_paste (const MJsonNode *params)
 
static MJsonNode * js_db_create (const MJsonNode *params)
 
static MJsonNode * js_db_delete (const MJsonNode *params)
 
static MJsonNode * js_db_resize (const MJsonNode *params)
 
static MJsonNode * js_db_resize_string (const MJsonNode *params)
 
static MJsonNode * js_db_key (const MJsonNode *params)
 
static MJsonNode * js_db_rename (const MJsonNode *params)
 
static MJsonNode * js_db_link (const MJsonNode *params)
 
static MJsonNode * js_db_reorder (const MJsonNode *params)
 
static MJsonNode * js_db_sor (const MJsonNode *params)
 
static MJsonNode * js_db_scl (const MJsonNode *params)
 
static MJsonNode * js_cm_msg_facilities (const MJsonNode *params)
 
static MJsonNode * js_cm_msg1 (const MJsonNode *params)
 
static MJsonNode * js_cm_msg_retrieve (const MJsonNode *params)
 
static MJsonNode * js_al_reset_alarm (const MJsonNode *params)
 
static MJsonNode * js_al_trigger_alarm (const MJsonNode *params)
 
static MJsonNode * js_al_trigger_class (const MJsonNode *params)
 
static MJsonNode * js_hs_get_active_events (const MJsonNode *params)
 
static MidasHistoryInterfaceGetHistory (const char *name)
 
static void js_hs_exit ()
 
static MJsonNode * js_hs_get_channels (const MJsonNode *params)
 
static MJsonNode * js_hs_get_events (const MJsonNode *params)
 
static MJsonNode * js_hs_reopen (const MJsonNode *params)
 
static MJsonNode * js_hs_get_tags (const MJsonNode *params)
 
static MJsonNode * js_hs_get_last_written (const MJsonNode *params)
 
static MJsonNode * js_hs_read (const MJsonNode *params)
 
static MJsonNode * js_hs_read_binned (const MJsonNode *params)
 
static MJsonNode * js_hs_read_arraybuffer (const MJsonNode *params)
 
static MJsonNode * js_hs_read_binned_arraybuffer (const MJsonNode *params)
 
static MJsonNode * js_hs_image_retrieve (const MJsonNode *params)
 
static MJsonNode * js_el_retrieve (const MJsonNode *params)
 
static MJsonNode * js_el_query (const MJsonNode *params)
 
static MJsonNode * js_el_delete (const MJsonNode *params)
 
static MJsonNode * jrpc (const MJsonNode *params)
 
static MJsonNode * brpc (const MJsonNode *params)
 
static MJsonNode * js_cm_transition (const MJsonNode *params)
 
static const EVENT_HEADERCopyEvent (const EVENT_HEADER *pevent)
 
static void StashEvent (const std::string buffer_name, int event_id, int trigger_mask, const EVENT_HEADER *pevent)
 
static void MatchEvent (const std::string buffer_name, const EVENT_HEADER *pevent)
 
static void DeleteEventStash ()
 
static const EVENT_HEADERFindEvent (const std::string buffer_name, int event_id, int trigger_mask, int last_event_id, int last_trigger_mask, DWORD last_serial_number, DWORD last_time_stamp)
 
static MJsonNode * js_bm_receive_event (const MJsonNode *params)
 
static MJsonNode * js_ss_millitime (const MJsonNode *params)
 
static MJsonNode * get_alarms (const MJsonNode *params)
 
static MJsonNode * js_make_subdir (const MJsonNode *params)
 
static MJsonNode * js_ext_list_files (const MJsonNode *params)
 
static MJsonNode * js_ext_save_file (const MJsonNode *params)
 
static MJsonNode * js_ext_read_file (const MJsonNode *params)
 
static MJsonNode * js_read_binary_file (const MJsonNode *params)
 
static MJsonNode * get_debug (const MJsonNode *params)
 
static MJsonNode * set_debug (const MJsonNode *params)
 
static MJsonNode * get_sleep (const MJsonNode *params)
 
static MJsonNode * set_sleep (const MJsonNode *params)
 
static MJsonNode * get_time (const MJsonNode *params)
 
static MJsonNode * set_time (const MJsonNode *params)
 
static MJsonNode * get_schema (const MJsonNode *params)
 
static MJsonNode * js_get_timezone (const MJsonNode *params)
 
void mjsonrpc_add_handler (const char *method, mjsonrpc_handler_t *handler, bool needs_locking)
 
void mjsonrpc_set_std_mutex (void *mutex)
 
void mjsonrpc_init ()
 
void mjsonrpc_exit ()
 
static MJsonNode * mjsonrpc_make_schema (MethodsTable *h)
 
MJsonNode * mjsonrpc_get_schema ()
 
static std::string indent (int x, const char *p=" ")
 
static std::string mjsonrpc_schema_to_html_anything (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
static std::string mjsonrpc_schema_to_html_object (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
static std::string mjsonrpc_schema_to_html_array (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
std::string mjsonrpc_schema_to_text (const MJsonNode *schema)
 
static void add (std::string *s, const char *text)
 
static MJsonNode * mjsonrpc_handle_request (const MJsonNode *request)
 
MJsonNode * mjsonrpc_decode_post_data (const char *post_data)
 

Variables

int mjsonrpc_debug = 0
 
static int mjsonrpc_sleep = 0
 
static int mjsonrpc_time = 0
 
static MJsonNode * gNullNode = NULL
 
static MhiMap gHistoryChannels
 
static std::mutex gEventStashMutex
 
static std::vector< EventStashEntry * > gEventStash
 
static MethodsTable gMethodsTable
 
static std::mutex * gMutex = NULL
 

Typedef Documentation

◆ MethodsTable

typedef std::map<std::string, MethodsTableEntry> MethodsTable

Definition at line 4637 of file mjsonrpc.cxx.

◆ MethodsTableIterator

typedef MethodsTable::iterator MethodsTableIterator

Definition at line 4638 of file mjsonrpc.cxx.

◆ MhiMap

typedef std::map<std::string,MidasHistoryInterface*> MhiMap

Definition at line 1694 of file mjsonrpc.cxx.

Function Documentation

◆ add()

static void add ( std::string *  s,
const char text 
)
static

Definition at line 5101 of file mjsonrpc.cxx.

5102{
5103 assert(s != NULL);
5104 if (s->length() > 0)
5105 *s += ", ";
5106 *s += text;
5107}
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:

◆ brpc()

static MJsonNode * brpc ( const MJsonNode *  params)
static

Definition at line 3423 of file mjsonrpc.cxx.

3424{
3425 if (!params) {
3426 MJSO* doc = MJSO::I();
3427 doc->D("make RPC call into frontend program via RPC_BRPC");
3428 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3429 doc->P("cmd", MJSON_STRING, "Command passed to client");
3430 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3431 doc->P("max_reply_length?", MJSON_INT, "Optional maximum length of client reply. MIDAS RPC does not support returning data of arbitrary length, maximum length has to be known ahead of time.");
3432 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3433 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3434 return doc;
3435 }
3436
3437 MJsonNode* error = NULL;
3438
3439 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3440 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3441 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3442 int max_reply_length = mjsonrpc_get_param(params, "max_reply_length", NULL)->GetInt();
3443
3444 int status;
3445
3446 int buf_length = 1024;
3447
3450
3451 char* buf = (char*)malloc(buf_length);
3452 buf[0] = 0;
3453
3454 HNDLE hconn;
3455
3456 status = cm_connect_client(name.c_str(), &hconn);
3457
3458 if (status != RPC_SUCCESS) {
3459 free(buf);
3460 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3461 }
3462
3463 status = rpc_client_call(hconn, RPC_BRPC, cmd.c_str(), args.c_str(), buf, &buf_length);
3464
3465 // disconnect return status ignored on purpose.
3466 // disconnect not needed, there is no limit on number
3467 // of connections. dead and closed connections are reaped
3468 // automatically. K.O. Feb 2021.
3469 // cm_disconnect_client(hconn, FALSE);
3470
3471 if (status != RPC_SUCCESS) {
3472 free(buf);
3473 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3474 }
3475
3476 return MJsonNode::MakeArrayBuffer(buf, buf_length);
3477}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2766
#define RPC_SUCCESS
Definition midas.h:698
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
const MJsonNode * mjsonrpc_get_param(const MJsonNode *params, const char *name, MJsonNode **error)
Definition mjsonrpc.cxx:178
#define RPC_BRPC
Definition mrpc.h:131
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13480
INT HNDLE
Definition midas.h:132
#define name(x)
Definition midas_macro.h:24
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CopyEvent()

static const EVENT_HEADER * CopyEvent ( const EVENT_HEADER pevent)
static

Definition at line 3545 of file mjsonrpc.cxx.

3546{
3547 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3548 //size_t total_size = ALIGN8(event_size);
3550 assert(ptr);
3551 memcpy(ptr, pevent, event_size);
3552 return ptr;
3553}
int event_size
Definition msysmon.cxx:527
DWORD data_size
Definition midas.h:856
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteEventStash()

static void DeleteEventStash ( )
static

Definition at line 3633 of file mjsonrpc.cxx.

3634{
3635 std::lock_guard<std::mutex> guard(gEventStashMutex);
3636 for (size_t i=0; i<gEventStash.size(); i++) {
3637 if (gEventStash[i]) {
3638 delete gEventStash[i];
3639 gEventStash[i] = NULL;
3640 }
3641 }
3642}
INT i
Definition mdump.cxx:32
static std::vector< EventStashEntry * > gEventStash
static std::mutex gEventStashMutex
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exec_script()

static MJsonNode * exec_script ( const MJsonNode *  params)
static

Definition at line 519 of file mjsonrpc.cxx.

520{
521 if (!params) {
522 MJSO* doc = MJSO::I();
523 doc->D("execute custom script defined in ODB /Script (scripts show in the menu) or /CustomScript (scripts from custom pages)");
524 doc->P("script?", MJSON_STRING, "Execute ODB /Script/xxx");
525 doc->P("customscript?", MJSON_STRING, "Execute ODB /CustomScript/xxx");
526 doc->R("status", MJSON_INT, "return status of cm_exec_script()");
527 return doc;
528 }
529
530 std::string script = mjsonrpc_get_param(params, "script", NULL)->GetString();
531 std::string customscript = mjsonrpc_get_param(params, "customscript", NULL)->GetString();
532
533 std::string path;
534
535 if (script.length() > 0) {
536 path += "/Script";
537 path += "/";
538 path += script;
539 } else if (customscript.length() > 0) {
540 path += "/CustomScript";
541 path += "/";
542 path += customscript;
543 }
544
545 int status = 0;
546
547 if (path.length() > 0) {
548 status = cm_exec_script(path.c_str());
549 }
550
551 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
552}
int cm_exec_script(const char *odb_path_to_script)
Definition midas.cxx:5469
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindEvent()

static const EVENT_HEADER * FindEvent ( const std::string  buffer_name,
int  event_id,
int  trigger_mask,
int  last_event_id,
int  last_trigger_mask,
DWORD  last_serial_number,
DWORD  last_time_stamp 
)
static

Definition at line 3644 of file mjsonrpc.cxx.

3645{
3646 std::lock_guard<std::mutex> guard(gEventStashMutex);
3647 for (EventStashEntry* s : gEventStash) {
3648 if (s->buffer_name != buffer_name)
3649 continue;
3650 if (bm_match_event(event_id, trigger_mask, s->pevent)) {
3651 if (s->pevent->event_id == last_event_id
3652 && s->pevent->trigger_mask == last_trigger_mask
3653 && s->pevent->serial_number == last_serial_number
3654 && s->pevent->time_stamp == last_time_stamp) {
3655 //s->Print(); printf(", already sent for %d,0x%x\n", event_id, trigger_mask);
3656 return NULL;
3657 } else {
3658 //s->Print(); printf(", serving for %d,0x%x\n", event_id, trigger_mask);
3659 return CopyEvent(s->pevent);
3660 }
3661 }
3662 }
3663 return NULL;
3664}
INT bm_match_event(short int event_id, short int trigger_mask, const EVENT_HEADER *pevent)
Definition midas.cxx:6023
char buffer_name[NAME_LENGTH]
Definition mevb.cxx:45
#define trigger_mask
#define event_id
static const EVENT_HEADER * CopyEvent(const EVENT_HEADER *pevent)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_alarms()

static MJsonNode * get_alarms ( const MJsonNode *  params)
static

Definition at line 3852 of file mjsonrpc.cxx.

3853{
3854 if (!params) {
3855 MJSO* doc = MJSO::I();
3856 doc->D("get alarm data");
3857 doc->P("get_all?", MJSON_BOOL, "get all alarms, even in alarm system not active and alarms not triggered");
3858 doc->R("status", MJSON_INT, "return status of midas library calls");
3859 doc->R("alarm_system_active", MJSON_BOOL, "value of ODB \"/Alarms/alarm system active\"");
3860 doc->R("alarms", MJSON_OBJECT, "alarm data, keyed by alarm name");
3861 doc->R("alarms[].triggered", MJSON_BOOL, "alarm is triggered");
3862 doc->R("alarms[].active", MJSON_BOOL, "alarm is enabled");
3863 doc->R("alarms[].class", MJSON_STRING, "alarm class");
3864 doc->R("alarms[].type", MJSON_INT, "alarm type AT_xxx");
3865 doc->R("alarms[].bgcolor", MJSON_STRING, "display background color");
3866 doc->R("alarms[].fgcolor", MJSON_STRING, "display foreground color");
3867 doc->R("alarms[].message", MJSON_STRING, "alarm ODB message field");
3868 doc->R("alarms[].condition", MJSON_STRING, "alarm ODB condition field");
3869 doc->R("alarms[].evaluated_value?", MJSON_STRING, "evaluated alarm condition (AT_EVALUATED alarms only)");
3870 doc->R("alarms[].periodic_next_time?", MJSON_STRING, "next time the periodic alarm will fire (AT_PERIODIC alarms only)");
3871 doc->R("alarms[].time_triggered_first", MJSON_STRING, "time when alarm was triggered");
3872 doc->R("alarms[].show_to_user", MJSON_STRING, "final alarm text shown to user by mhttpd");
3873 return doc;
3874 }
3875
3876 //MJsonNode* error = NULL;
3877
3878 bool get_all = mjsonrpc_get_param(params, "get_all", NULL)->GetBool();
3879
3880 int status;
3881 HNDLE hDB;
3882
3884
3885 if (status != DB_SUCCESS) {
3886 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3887 }
3888
3889 int flag;
3890 int size;
3891 int alarm_system_active = 0;
3892
3893 /* check global alarm flag */
3894 flag = TRUE;
3895 size = sizeof(flag);
3896 status = db_get_value(hDB, 0, "/Alarms/Alarm System active", &flag, &size, TID_BOOL, TRUE);
3897
3898 if (status != DB_SUCCESS) {
3899 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3900 }
3901
3903
3905 if (!get_all) {
3906 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
3907 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
3908 "alarms", MJsonNode::MakeObject());
3909 }
3910
3911 /* go through all alarms */
3912 HNDLE hkey;
3913 status = db_find_key(hDB, 0, "/Alarms/Alarms", &hkey);
3914
3915 if (status != DB_SUCCESS) {
3916 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3917 }
3918
3919 MJsonNode* alarms = MJsonNode::MakeObject();
3920
3921 for (int i = 0;; i++) {
3922 HNDLE hsubkey;
3923 KEY key;
3924
3926
3927 if (!hsubkey)
3928 break;
3929
3931
3932 const char* name = key.name;
3933
3934 flag = 0;
3935 size = sizeof(flag);
3936 status = db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, TRUE);
3937
3938 // skip un-triggered alarms
3939 if (!flag)
3940 if (!get_all)
3941 continue;
3942
3943 MJsonNode* a = MJsonNode::MakeObject();
3944
3945 a->AddToObject("triggered", MJsonNode::MakeBool(flag!=0));
3946
3947 flag = 1;
3948 size = sizeof(BOOL);
3949 status = db_get_value(hDB, hsubkey, "Active", &flag, &size, TID_BOOL, TRUE);
3950
3951 a->AddToObject("active", MJsonNode::MakeBool(flag!=0));
3952
3953 char alarm_class[NAME_LENGTH];
3954 strcpy(alarm_class, "Alarm");
3955 size = sizeof(alarm_class);
3956 status = db_get_value(hDB, hsubkey, "Alarm Class", alarm_class, &size, TID_STRING, TRUE);
3957
3958 ss_repair_utf8(alarm_class);
3959 a->AddToObject("class", MJsonNode::MakeString(alarm_class));
3960
3961 int atype = 0;
3962 size = sizeof(atype);
3963 status = db_get_value(hDB, hsubkey, "Type", &atype, &size, TID_INT, TRUE);
3964
3965 a->AddToObject("type", MJsonNode::MakeInt(atype));
3966
3967 char str[256];
3968
3969 char bgcol[256];
3970 strcpy(bgcol, "red");
3971
3972 if (strlen(alarm_class) > 0) {
3973 sprintf(str, "/Alarms/Classes/%s/Display BGColor", alarm_class);
3974 size = sizeof(bgcol);
3975 status = db_get_value(hDB, 0, str, bgcol, &size, TID_STRING, TRUE);
3976 }
3977
3979 a->AddToObject("bgcolor", MJsonNode::MakeString(bgcol));
3980
3981 char fgcol[256];
3982 strcpy(fgcol, "black");
3983
3984 if (strlen(alarm_class) > 0) {
3985 sprintf(str, "/Alarms/Classes/%s/Display FGColor", alarm_class);
3986 size = sizeof(fgcol);
3987 status = db_get_value(hDB, 0, str, fgcol, &size, TID_STRING, TRUE);
3988 }
3989
3991 a->AddToObject("fgcolor", MJsonNode::MakeString(fgcol));
3992
3993 flag = 1;
3994 if (strlen(alarm_class) > 0) {
3995 size = sizeof(BOOL);
3996 sprintf(str, "/Alarms/Classes/%s/Alarm sound", alarm_class);
3997 status = db_get_value(hDB, 0, str, &flag, &size, TID_BOOL, TRUE);
3998 }
3999 a->AddToObject("alarm_sound", MJsonNode::MakeBool(flag!=0));
4000
4001 char msg[256];
4002 msg[0] = 0;
4003 size = sizeof(msg);
4004 status = db_get_value(hDB, hsubkey, "Alarm Message", msg, &size, TID_STRING, TRUE);
4005
4006 ss_repair_utf8(msg);
4007 a->AddToObject("message", MJsonNode::MakeString(msg));
4008
4009 char cond[256];
4010 cond[0] = 0;
4011 size = sizeof(cond);
4012 status = db_get_value(hDB, hsubkey, "Condition", cond, &size, TID_STRING, TRUE);
4013
4014 ss_repair_utf8(cond);
4015 a->AddToObject("condition", MJsonNode::MakeString(cond));
4016
4017 std::string show_to_user;
4018
4019 if (atype == AT_EVALUATED) {
4020 /* retrieve value */
4021 std::string value;
4023 show_to_user = msprintf(msg, value.c_str());
4025 a->AddToObject("evaluated_value", MJsonNode::MakeString(value.c_str()));
4026 } else
4027 show_to_user = msg;
4028
4030 a->AddToObject("show_to_user", MJsonNode::MakeString(show_to_user.c_str()));
4031
4032 str[0] = 0;
4033 size = sizeof(str);
4034 status = db_get_value(hDB, hsubkey, "Time triggered first", str, &size, TID_STRING, TRUE);
4035
4037 a->AddToObject("time_triggered_first", MJsonNode::MakeString(str));
4038
4039 if (atype == AT_PERIODIC) {
4040 DWORD last = 0;
4041 size = sizeof(last);
4042 db_get_value(hDB, hsubkey, "Checked last", &last, &size, TID_DWORD, TRUE);
4043
4044 if (last == 0) {
4045 last = ss_time();
4046 db_set_value(hDB, hsubkey, "Checked last", &last, size, 1, TID_DWORD);
4047 }
4048
4049 int interval = 0;
4050 size = sizeof(interval);
4051 db_get_value(hDB, hsubkey, "Check interval", &interval, &size, TID_INT, TRUE);
4052
4054
4055 char ctimebuf[32];
4057
4058 //ss_repair_utf8(ctimebuf); redundant!
4059 a->AddToObject("periodic_next_time", MJsonNode::MakeString(ctimebuf));
4060 }
4061
4062 alarms->AddToObject(name, a);
4063 }
4064
4065 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
4066 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
4067 "alarms", alarms);
4068}
BOOL al_evaluate_condition(const char *alarm_name, const char *condition, std::string *pvalue)
Definition alarm.cxx:41
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
#define DB_SUCCESS
Definition midas.h:631
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TID_BOOL
Definition midas.h:340
#define TID_STRING
Definition midas.h:346
#define TID_INT
Definition midas.h:338
#define TID_DWORD
Definition midas.h:336
DWORD ss_time()
Definition system.cxx:3462
bool ss_repair_utf8(char *string)
Definition system.cxx:8157
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5725
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
HNDLE hDB
main ODB handle
Definition mana.cxx:207
KEY key
Definition mdump.cxx:34
std::string msprintf(const char *format,...)
Definition midas.cxx:410
DWORD BOOL
Definition midas.h:105
#define AT_PERIODIC
Definition midas.h:1443
#define TRUE
Definition midas.h:182
#define AT_EVALUATED
Definition midas.h:1442
#define NAME_LENGTH
Definition midas.h:272
double value[100]
Definition odbhist.cxx:42
char str[256]
Definition odbhist.cxx:33
Definition midas.h:1026
char name[NAME_LENGTH]
Definition midas.h:1029
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_debug()

static MJsonNode * get_debug ( const MJsonNode *  params)
static

Definition at line 4508 of file mjsonrpc.cxx.

4509{
4510 if (!params) {
4511 MJSO *doc = MJSO::I();
4512 doc->D("get current value of mjsonrpc_debug");
4513 doc->P(NULL, 0, "there are no input parameters");
4514 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_debug");
4515 return doc;
4516 }
4517
4518 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4519}
int mjsonrpc_debug
Definition mjsonrpc.cxx:112
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_schema()

static MJsonNode * get_schema ( const MJsonNode *  params)
static

Definition at line 4589 of file mjsonrpc.cxx.

4590{
4591 if (!params) {
4592 MJSO* doc = MJSO::I();
4593 doc->D("Get the MIDAS JSON-RPC schema JSON object");
4594 doc->P(NULL, 0, "there are no input parameters");
4595 doc->R(NULL, MJSON_OBJECT, "returns the MIDAS JSON-RPC schema JSON object");
4596 return doc;
4597 }
4598
4600}
MJsonNode * mjsonrpc_get_schema()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_sleep()

static MJsonNode * get_sleep ( const MJsonNode *  params)
static

Definition at line 4535 of file mjsonrpc.cxx.

4536{
4537 if (!params) {
4538 MJSO *doc = MJSO::I();
4539 doc->D("get current value of mjsonrpc_sleep");
4540 doc->P(NULL, 0, "there are no input parameters");
4541 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_sleep");
4542 return doc;
4543 }
4544
4545 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4546}
static int mjsonrpc_sleep
Definition mjsonrpc.cxx:113
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_time()

static MJsonNode * get_time ( const MJsonNode *  params)
static

Definition at line 4562 of file mjsonrpc.cxx.

4563{
4564 if (!params) {
4565 MJSO *doc = MJSO::I();
4566 doc->D("get current value of mjsonrpc_time");
4567 doc->P(NULL, 0, "there are no input parameters");
4568 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_time");
4569 return doc;
4570 }
4571
4572 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4573}
static int mjsonrpc_time
Definition mjsonrpc.cxx:114
Here is the call graph for this function:

◆ GetHistory()

static MidasHistoryInterface * GetHistory ( const char name)
static

Definition at line 1698 of file mjsonrpc.cxx.

1699{
1700 // empty name means use the default reader channel
1701
1702 MhiMap::iterator ci = gHistoryChannels.find(name);
1703 if (ci != gHistoryChannels.end()) {
1704 return ci->second;
1705 };
1706
1707 int verbose = 0;
1708
1709 HNDLE hDB;
1711
1712 HNDLE hKey = 0;
1713
1714 if (strlen(name) < 1) {
1716 if (status != HS_SUCCESS) {
1717 return NULL;
1718 }
1719 } else {
1721 int status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1722 if (status != DB_SUCCESS) {
1723 return NULL;
1724 }
1726 if (status != DB_SUCCESS) {
1727 return NULL;
1728 }
1729 }
1730
1732
1734 if (status != HS_SUCCESS || mh==NULL) {
1735 cm_msg(MERROR, "GetHistory", "Cannot configure history, hs_get_history() status %d", status);
1736 return NULL;
1737 }
1738
1739 //printf("hs_get_history: \"%s\" -> mh %p\n", name, mh);
1740
1742
1743 // cm_msg(MINFO, "GetHistory", "Reading history channel \"%s\" from channel \'%s\' type \'%s\'", name, mh->name, mh->type);
1744
1745 return mh;
1746}
#define HS_SUCCESS
Definition midas.h:727
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
#define HS_GET_INACTIVE
Definition history.h:37
#define HS_GET_READER
Definition history.h:35
int hs_find_reader_channel(HNDLE hDB, HNDLE *hKeyOut, int debug_flag)
int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
HNDLE hKey
BOOL verbose
Definition mana.cxx:255
MidasHistoryInterface * mh
static MhiMap gHistoryChannels
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTimeSec()

static double GetTimeSec ( )
static

Definition at line 116 of file mjsonrpc.cxx.

117{
118 struct timeval tv;
120 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
121}
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
Here is the call graph for this function:
Here is the caller graph for this function:

◆ indent()

static std::string indent ( int  x,
const char p = " " 
)
static

Definition at line 4795 of file mjsonrpc.cxx.

4796{
4797 if (x<1)
4798 return "";
4799 std::string s;
4800 for (int i=0; i<x; i++)
4801 s += p;
4802 return s;
4803}
Here is the caller graph for this function:

◆ jrpc()

static MJsonNode * jrpc ( const MJsonNode *  params)
static

Definition at line 3357 of file mjsonrpc.cxx.

3358{
3359 if (!params) {
3360 MJSO* doc = MJSO::I();
3361 doc->D("make RPC call into frontend program via RPC_JRPC");
3362 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3363 doc->P("cmd", MJSON_STRING, "Command passed to client");
3364 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3365 doc->P("max_reply_length?", MJSON_INT, "Optional maximum length of client reply. MIDAS RPC does not support returning strings of arbitrary length, maximum length has to be known ahead of time.");
3366 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3367 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3368 return doc;
3369 }
3370
3371 MJsonNode* error = NULL;
3372
3373 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3374 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3375 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3376 int max_reply_length = mjsonrpc_get_param(params, "max_reply_length", NULL)->GetInt();
3377
3378 int status;
3379
3380 int buf_length = 1024;
3381
3384
3385 char* buf = (char*)malloc(buf_length);
3386 buf[0] = 0;
3387
3388 HNDLE hconn;
3389
3390 status = cm_connect_client(name.c_str(), &hconn);
3391
3392 if (status != RPC_SUCCESS) {
3393 free(buf);
3394 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3395 }
3396
3397 status = rpc_client_call(hconn, RPC_JRPC, cmd.c_str(), args.c_str(), buf, buf_length);
3398
3399 // disconnect return status ignored on purpose.
3400 // disconnect not needed, there is no limit on number
3401 // of connections. dead and closed connections are reaped
3402 // automatically. K.O. Feb 2021.
3403 // cm_disconnect_client(hconn, FALSE);
3404
3405 if (status != RPC_SUCCESS) {
3406 free(buf);
3407 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3408 }
3409
3410 ss_repair_utf8(buf);
3411 MJsonNode* reply = MJsonNode::MakeString(buf);
3412 free(buf);
3413
3414 return mjsonrpc_make_result("reply", reply, "status", MJsonNode::MakeInt(SUCCESS));
3415}
#define RPC_JRPC
Definition mrpc.h:130
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_reset_alarm()

static MJsonNode * js_al_reset_alarm ( const MJsonNode *  params)
static

Definition at line 1588 of file mjsonrpc.cxx.

1589{
1590 if (!params) {
1591 MJSO* doc = MJSO::I();
1592 doc->D("reset alarms");
1593 doc->P("alarms[]", MJSON_STRING, "array of alarm names");
1594 doc->R("status[]", MJSON_INT, "return status of al_reset_alarm() for each alarm");
1595 return doc;
1596 }
1597
1598 MJsonNode* error = NULL;
1599
1600 const MJsonNodeVector* alarms = mjsonrpc_get_param_array(params, "alarms", &error); if (error) return error;
1601
1602 MJsonNode* sresult = MJsonNode::MakeArray();
1603
1604 for (unsigned i=0; i<alarms->size(); i++) {
1605 int status = al_reset_alarm((*alarms)[i]->GetString().c_str());
1606 sresult->AddToArray(MJsonNode::MakeInt(status));
1607 }
1608
1609 return mjsonrpc_make_result("status", sresult);
1610}
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:525
const MJsonNodeVector * mjsonrpc_get_param_array(const MJsonNode *params, const char *name, MJsonNode **error)
Definition mjsonrpc.cxx:201
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_trigger_alarm()

static MJsonNode * js_al_trigger_alarm ( const MJsonNode *  params)
static

Definition at line 1612 of file mjsonrpc.cxx.

1613{
1614 if (!params) {
1615 MJSO* doc = MJSO::I();
1616 doc->D("trigger an alarm");
1617 doc->P("name", MJSON_STRING, "alarm name");
1618 doc->P("message", MJSON_STRING, "alarm message");
1619 doc->P("class", MJSON_STRING, "alarm class");
1620 doc->P("condition", MJSON_STRING, "alarm condition");
1621 doc->P("type", MJSON_INT, "alarm type (AT_xxx)");
1622 doc->R("status", MJSON_INT, "return status of al_trigger_alarm()");
1623 return doc;
1624 }
1625
1626 MJsonNode* error = NULL;
1627
1628 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString(); if (error) return error;
1629 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1630 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1631 std::string condition = mjsonrpc_get_param(params, "condition", &error)->GetString(); if (error) return error;
1632 int type = mjsonrpc_get_param(params, "type", &error)->GetInt(); if (error) return error;
1633
1634 int status = al_trigger_alarm(name.c_str(), message.c_str(), xclass.c_str(), condition.c_str(), type);
1635
1636 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1637}
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
Definition alarm.cxx:283
INT type
Definition mana.cxx:269
#define message(type, str)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_trigger_class()

static MJsonNode * js_al_trigger_class ( const MJsonNode *  params)
static

Definition at line 1639 of file mjsonrpc.cxx.

1640{
1641 if (!params) {
1642 MJSO* doc = MJSO::I();
1643 doc->D("trigger an alarm");
1644 doc->P("class", MJSON_STRING, "alarm class");
1645 doc->P("message", MJSON_STRING, "alarm message");
1646 doc->P("first?", MJSON_BOOL, "see al_trigger_class() in midas.c");
1647 doc->R("status", MJSON_INT, "return status of al_trigger_class()");
1648 return doc;
1649 }
1650
1651 MJsonNode* error = NULL;
1652
1653 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1654 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1655 bool first = mjsonrpc_get_param(params, "first", NULL)->GetBool();
1656
1657 int status = al_trigger_class(xclass.c_str(), message.c_str(), first);
1658
1659 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1660}
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
Definition alarm.cxx:413
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_bm_receive_event()

static MJsonNode * js_bm_receive_event ( const MJsonNode *  params)
static

Definition at line 3666 of file mjsonrpc.cxx.

3667{
3668 if (!params) {
3669 MJSO* doc = MJSO::I();
3670 doc->D("read event buffers");
3671 doc->P("buffer_name", MJSON_STRING, "name of event buffer");
3672 doc->P("event_id?", MJSON_INT, "requested event id, -1 means any event id");
3673 doc->P("trigger_mask?", MJSON_INT, "requested trigger mask, -1 means any trigger mask");
3674 doc->P("get_recent?", MJSON_BOOL, "get last available event that matches this event request");
3675 doc->P("last_event_header[]?", MJSON_INT, "do not resend an event we already received: event header of last received event [event_id,trigger_mask,serial_number,time_stamp]");
3676 doc->P("timeout_millisec?", MJSON_NUMBER, "how long to wait for an event");
3677 doc->R("binary data", MJSON_ARRAYBUFFER, "binary event data");
3678 doc->R("status", MJSON_INT, "return status of bm_open_buffer(), bm_request_event(), bm_set_cache_size(), bm_receive_alloc()");
3679 return doc;
3680 }
3681
3682 MJsonNode* error = NULL;
3683
3684 std::string buffer_name = mjsonrpc_get_param(params, "buffer_name", &error)->GetString(); if (error) return error;
3685 int event_id = mjsonrpc_get_param(params, "event_id", NULL)->GetInt();
3686 int trigger_mask = mjsonrpc_get_param(params, "trigger_mask", NULL)->GetInt();
3687 bool get_recent = mjsonrpc_get_param(params, "get_recent", NULL)->GetBool();
3688 const MJsonNodeVector* last_event_header = mjsonrpc_get_param(params, "last_event_header", NULL)->GetArray();
3689 int timeout_millisec = mjsonrpc_get_param(params, "timeout_millisec", NULL)->GetInt();
3690
3691 int last_event_id = 0;
3692 int last_trigger_mask = 0;
3693 int last_serial_number = 0;
3694 int last_time_stamp = 0;
3695
3696 if (last_event_header && last_event_header->size() > 0) {
3697 if (last_event_header->size() != 4) {
3698 return mjsonrpc_make_error(-32602, "Invalid params", "last_event_header should be an array with 4 elements");
3699 }
3700
3701 last_event_id = (*last_event_header)[0]->GetInt();
3702 last_trigger_mask = (*last_event_header)[1]->GetInt();
3703 last_serial_number = (*last_event_header)[2]->GetInt();
3704 last_time_stamp = (*last_event_header)[3]->GetInt();
3705 }
3706
3707 //printf("last event header: %d %d %d %d\n", last_event_id, last_trigger_mask, last_serial_number, last_time_stamp);
3708
3709 if (event_id == 0)
3711
3712 if (trigger_mask == 0)
3714
3715 //printf("js_bm_receive_event: buffer \"%s\", event_id %d, trigger_mask 0x%04x\n", buffer_name.c_str(), event_id, trigger_mask);
3716
3717 int status;
3718
3719 HNDLE buffer_handle = 0;
3720
3721 status = bm_get_buffer_handle(buffer_name.c_str(), &buffer_handle);
3722
3723 if (status != BM_SUCCESS) {
3724 // if buffer not already open, we need to open it,
3725 // but we must hold a lock in case multiple RPC handler threads
3726 // try to open it at the same time. K.O.
3727 static std::mutex gMutex;
3728 std::lock_guard<std::mutex> lock_guard(gMutex); // lock the mutex
3729
3730 // we have the lock. now we check if some other thread
3731 // opened the buffer while we were waiting for the lock. K.O.
3732 status = bm_get_buffer_handle(buffer_name.c_str(), &buffer_handle);
3733
3734 if (status != BM_SUCCESS) {
3735 status = bm_open_buffer(buffer_name.c_str(), 0, &buffer_handle);
3736 if (status != BM_SUCCESS && status != BM_CREATED) {
3737 MJsonNode* result = MJsonNode::MakeObject();
3738 result->AddToObject("status", MJsonNode::MakeInt(status));
3739 return mjsonrpc_make_result(result);
3740 }
3741 status = bm_set_cache_size(buffer_handle, 0, 0);
3742 if (status != BM_SUCCESS) {
3743 MJsonNode* result = MJsonNode::MakeObject();
3744 result->AddToObject("status", MJsonNode::MakeInt(status));
3745 return mjsonrpc_make_result(result);
3746 }
3747 int request_id = 0;
3748 status = bm_request_event(buffer_handle, EVENTID_ALL, TRIGGER_ALL, GET_NONBLOCKING, &request_id, NULL);
3749 if (status != BM_SUCCESS) {
3750 MJsonNode* result = MJsonNode::MakeObject();
3751 result->AddToObject("status", MJsonNode::MakeInt(status));
3752 return mjsonrpc_make_result(result);
3753 }
3754 }
3755 }
3756
3757 if (timeout_millisec <= 0)
3758 timeout_millisec = 100.0;
3759
3760 double start_time = ss_time_sec();
3761 double end_time = start_time + timeout_millisec/1000.0;
3762
3763 // in "GET_RECENT" mode, we read all avialable events from the event buffer
3764 // and save them in the event stash (MatchEvent()), after we empty the event
3765 // buffer (BM_ASYNC_RETURN), we send the last saved event. K.O.
3766
3767 while (1) {
3768 EVENT_HEADER* pevent = NULL;
3769
3770 status = bm_receive_event_alloc(buffer_handle, &pevent, BM_NO_WAIT);
3771
3772 if (status == BM_SUCCESS) {
3773 //printf("got event_id %d, trigger_mask 0x%04x\n", pevent->event_id, pevent->trigger_mask);
3774
3775 if (get_recent) {
3776 if (bm_match_event(event_id, trigger_mask, pevent)) {
3778 } else {
3779 MatchEvent(buffer_name, pevent);
3780 }
3781 free(pevent);
3782 pevent = NULL;
3783 } else {
3784 if (bm_match_event(event_id, trigger_mask, pevent)) {
3786
3787 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3788 //size_t total_size = ALIGN8(event_size);
3789 return MJsonNode::MakeArrayBuffer((char*)pevent, event_size);
3790 }
3791
3792 MatchEvent(buffer_name, pevent);
3793
3794 free(pevent);
3795 pevent = NULL;
3796 }
3797 } else if (status == BM_ASYNC_RETURN) {
3798 if (get_recent) {
3799 //printf("bm_async_return!\n");
3800 break;
3801 }
3802 ss_sleep(10);
3803 } else {
3804 MJsonNode* result = MJsonNode::MakeObject();
3805 result->AddToObject("status", MJsonNode::MakeInt(status));
3806 return mjsonrpc_make_result(result);
3807 }
3808
3809 if (ss_time_sec() > end_time) {
3810 //printf("timeout!\n");
3811 break;
3812 }
3813 }
3814
3816 if (pevent) {
3817 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3818 //size_t total_size = ALIGN8(event_size);
3819 return MJsonNode::MakeArrayBuffer((char*)pevent, event_size);
3820 }
3821
3822 MJsonNode* result = MJsonNode::MakeObject();
3823 result->AddToObject("status", MJsonNode::MakeInt(BM_ASYNC_RETURN));
3824 return mjsonrpc_make_result(result);
3825}
INT bm_open_buffer(const char *buffer_name, INT buffer_size, INT *buffer_handle)
Definition midas.cxx:6725
INT bm_request_event(HNDLE buffer_handle, short int event_id, short int trigger_mask, INT sampling_type, HNDLE *request_id, EVENT_HANDLER *func)
Definition midas.cxx:8473
INT bm_set_cache_size(INT buffer_handle, size_t read_size, size_t write_size)
Definition midas.cxx:8148
INT bm_get_buffer_handle(const char *buffer_name, INT *buffer_handle)
Definition midas.cxx:7083
INT bm_receive_event_alloc(INT buffer_handle, EVENT_HEADER **ppevent, int timeout_msec)
Definition midas.cxx:10739
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define BM_CREATED
Definition midas.h:606
#define GET_NONBLOCKING
Definition midas.h:322
#define TRIGGER_ALL
Definition midas.h:538
#define BM_NO_WAIT
Definition midas.h:366
#define EVENTID_ALL
Definition midas.h:537
MJsonNode * mjsonrpc_make_error(int code, const char *message, const char *data)
Definition mjsonrpc.cxx:123
double ss_time_sec()
Definition system.cxx:3467
INT ss_sleep(INT millisec)
Definition system.cxx:3628
static void StashEvent(const std::string buffer_name, int event_id, int trigger_mask, const EVENT_HEADER *pevent)
static std::mutex * gMutex
static const EVENT_HEADER * FindEvent(const std::string buffer_name, int event_id, int trigger_mask, int last_event_id, int last_trigger_mask, DWORD last_serial_number, DWORD last_time_stamp)
static void MatchEvent(const std::string buffer_name, const EVENT_HEADER *pevent)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_exist()

static MJsonNode * js_cm_exist ( const MJsonNode *  params)
static

Definition at line 432 of file mjsonrpc.cxx.

433{
434 if (!params) {
435 MJSO* doc = MJSO::I();
436 doc->D("calls MIDAS cm_exist() to check if given MIDAS program is running");
437 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
438 doc->P("unique?", MJSON_BOOL, "bUnique argument to cm_exist()");
439 doc->R("status", MJSON_INT, "return status of cm_exist()");
440 return doc;
441 }
442
443 MJsonNode* error = NULL;
444
445 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString();
446 if (error)
447 return error;
448
449 int unique = mjsonrpc_get_param(params, "unique", NULL)->GetBool();
450
451 int status = cm_exist(name.c_str(), unique);
452
453 if (mjsonrpc_debug)
454 printf("cm_exist(%s,%d) -> %d\n", name.c_str(), unique, status);
455
456 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
457}
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg1()

static MJsonNode * js_cm_msg1 ( const MJsonNode *  params)
static

Definition at line 1509 of file mjsonrpc.cxx.

1510{
1511 if (!params) {
1512 MJSO *doc = MJSO::I();
1513 doc->D("Generate a midas message using cm_msg1()");
1514 doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
1515 doc->P("user?", MJSON_STRING, "message user, default is \"javascript_commands\"");
1516 doc->P("type?", MJSON_INT, "message type, MT_xxx from midas.h, default is MT_INFO");
1517 doc->P("message", MJSON_STRING, "message text");
1518 doc->R("status", MJSON_INT, "return status of cm_msg1()");
1519 return doc;
1520 }
1521
1522 MJsonNode* error = NULL;
1523
1524 std::string facility = mjsonrpc_get_param(params, "facility", NULL)->GetString();
1525 std::string user = mjsonrpc_get_param(params, "user", NULL)->GetString();
1526 int type = mjsonrpc_get_param(params, "type", NULL)->GetInt();
1527 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1528
1529 if (facility.size() <1)
1530 facility = "midas";
1531 if (user.size()<1)
1532 user = "javascript_commands";
1533 if (type == 0)
1534 type = MT_INFO;
1535
1536 int status = cm_msg1(type, __FILE__, __LINE__, facility.c_str(), user.c_str(), "%s", message.c_str());
1537
1538 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1539}
#define MT_INFO
Definition midas.h:543
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:973
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg_facilities()

static MJsonNode * js_cm_msg_facilities ( const MJsonNode *  params)
static

Definition at line 1484 of file mjsonrpc.cxx.

1485{
1486 if (!params) {
1487 MJSO* doc = MJSO::I();
1488 doc->D("get message facilities using cm_msg_facilities()");
1489 doc->R("status", MJSON_INT, "return status of cm_msg_facilities()");
1490 doc->R("facilities[]", MJSON_STRING, "array of facility names");
1491 return doc;
1492 }
1493
1495
1497
1498 MJsonNode* facilities = MJsonNode::MakeArray();
1499
1500 for (unsigned i=0; i<list.size(); i++) {
1502 facilities->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1503 }
1504
1505 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status),
1506 "facilities", facilities);
1507}
INT EXPRT cm_msg_facilities(STRING_LIST *list)
Definition midas.cxx:504
std::vector< std::string > STRING_LIST
Definition midas.h:246
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg_retrieve()

static MJsonNode * js_cm_msg_retrieve ( const MJsonNode *  params)
static

Definition at line 1541 of file mjsonrpc.cxx.

1542{
1543 if (!params) {
1544 MJSO *doc = MJSO::I();
1545 doc->D("Retrieve midas messages using cm_msg_retrieve2()");
1546 doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
1547 doc->P("min_messages?", MJSON_INT, "get at least this many messages, default is 1");
1548 doc->P("time?", MJSON_NUMBER, "start from given timestamp, value 0 means give me newest messages, default is 0");
1549 doc->R("num_messages", MJSON_INT, "number of messages returned");
1550 doc->R("messages", MJSON_STRING, "messages separated by \\n");
1551 doc->R("status", MJSON_INT, "return status of cm_msg_retrieve2()");
1552 return doc;
1553 }
1554
1555 std::string facility = mjsonrpc_get_param(params, "facility", NULL)->GetString();
1556 int min_messages = mjsonrpc_get_param(params, "min_messages", NULL)->GetInt();
1557 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1558
1559 if (facility.size() < 1)
1560 facility = "midas";
1561
1562 int num_messages = 0;
1563 char* messages = NULL;
1564
1566
1567 MJsonNode* result = MJsonNode::MakeObject();
1568
1569 result->AddToObject("status", MJsonNode::MakeInt(status));
1570 result->AddToObject("num_messages", MJsonNode::MakeInt(num_messages));
1571
1572 if (messages) {
1574 result->AddToObject("messages", MJsonNode::MakeString(messages));
1575 free(messages);
1576 messages = NULL;
1577 }
1578
1579 return mjsonrpc_make_result(result);
1580}
INT cm_msg_retrieve2(const char *facility, time_t t, INT n_message, char **messages, int *num_messages)
Definition midas.cxx:1264
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_shutdown()

static MJsonNode * js_cm_shutdown ( const MJsonNode *  params)
static

Definition at line 459 of file mjsonrpc.cxx.

460{
461 if (!params) {
462 MJSO *doc = MJSO::I();
463 doc->D("calls MIDAS cm_shutdown() to stop given MIDAS program");
464 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
465 doc->P("unique?", MJSON_BOOL, "bUnique argument to cm_shutdown()");
466 doc->R("status", MJSON_INT, "return status of cm_shutdown()");
467 return doc;
468 }
469
470 MJsonNode* error = NULL;
471
472 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString();
473 if (error)
474 return error;
475
476 int unique = mjsonrpc_get_param(params, "unique", NULL)->GetBool();
477
478 int status = cm_shutdown(name.c_str(), unique);
479
480 if (mjsonrpc_debug)
481 printf("cm_shutdown(%s,%d) -> %d\n", name.c_str(), unique, status);
482
483 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
484}
INT cm_shutdown(const char *name, BOOL bUnique)
Definition midas.cxx:7408
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_transition()

static MJsonNode * js_cm_transition ( const MJsonNode *  params)
static

Definition at line 3485 of file mjsonrpc.cxx.

3486{
3487 if (!params) {
3488 MJSO* doc = MJSO::I();
3489 doc->D("start and stop runs");
3490 doc->P("transition", MJSON_STRING, "requested transition: TR_START, TR_STOP, TR_PAUSE, TR_RESUME");
3491 doc->P("run_number?", MJSON_INT, "New run number, value 0 means /runinfo/run_number + 1, default is 0");
3492 doc->P("async_flag?", MJSON_INT, "Transition type. Default is multithreaded transition TR_MTHREAD");
3493 doc->P("debug_flag?", MJSON_INT, "See cm_transition(), value 1: trace to stdout, value 2: trace to midas.log");
3494 doc->R("status", MJSON_INT, "return status of cm_transition()");
3495 doc->R("error_string?", MJSON_STRING, "return error string from cm_transition()");
3496 return doc;
3497 }
3498
3499 MJsonNode* error = NULL;
3500
3501 std::string xtransition = mjsonrpc_get_param(params, "transition", &error)->GetString(); if (error) return error;
3502 int run_number = mjsonrpc_get_param(params, "run_number", NULL)->GetInt();
3503 int async_flag = mjsonrpc_get_param(params, "async_flag", NULL)->GetInt();
3504 int debug_flag = mjsonrpc_get_param(params, "debug_flag", NULL)->GetInt();
3505
3506 int status;
3507
3508 int transition = 0;
3509
3510 if (xtransition == "TR_START")
3512 else if (xtransition == "TR_STOP")
3514 else if (xtransition == "TR_PAUSE")
3516 else if (xtransition == "TR_RESUME")
3518 else {
3519 return mjsonrpc_make_error(15, "invalid value of \"transition\"", xtransition.c_str());
3520 }
3521
3522 if (async_flag == 0)
3523 async_flag = TR_MTHREAD;
3524
3525 char error_str[1024];
3526
3527 status = cm_transition(transition, run_number, error_str, sizeof(error_str), async_flag, debug_flag);
3528
3529 MJsonNode* result = MJsonNode::MakeObject();
3530
3531 result->AddToObject("status", MJsonNode::MakeInt(status));
3532 if (strlen(error_str) > 0) {
3534 result->AddToObject("error_string", MJsonNode::MakeString(error_str));
3535 }
3536 return mjsonrpc_make_result(result);
3537}
INT transition(INT run_number, char *error)
Definition consume.cxx:35
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5294
#define TR_RESUME
Definition midas.h:408
#define TR_PAUSE
Definition midas.h:407
#define TR_START
Definition midas.h:405
#define TR_MTHREAD
Definition midas.h:361
#define TR_STOP
Definition midas.h:406
INT run_number[2]
Definition mana.cxx:246
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_copy()

static MJsonNode * js_db_copy ( const MJsonNode *  params)
static

Definition at line 860 of file mjsonrpc.cxx.

861{
862 if (!params) {
863 MJSO* doc = MJSO::I();
864 doc->D("get complete ODB data in the \"save\" json encoding, suitable for reloading with odbedit command \"load\"");
865 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths");
866 doc->R("data[]", MJSON_OBJECT, "keys and values of ODB data for each path");
867 doc->R("status[]", MJSON_INT, "return status of db_copy_json_save() for each path");
868 return doc;
869 }
870
871 MJsonNode* error = NULL;
872
873 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
874
875 MJsonNode* dresult = MJsonNode::MakeArray();
876 MJsonNode* sresult = MJsonNode::MakeArray();
877
878 HNDLE hDB;
880
881 for (unsigned i=0; i<paths->size(); i++) {
882 int status = 0;
883 HNDLE hkey;
884 std::string path = (*paths)[i]->GetString();
885
886 status = db_find_key(hDB, 0, path.c_str(), &hkey);
887 if (status != DB_SUCCESS) {
888 dresult->AddToArray(MJsonNode::MakeNull());
889 sresult->AddToArray(MJsonNode::MakeInt(status));
890 continue;
891 }
892
893 char* buf = NULL;
894 int bufsize = 0;
895 int end = 0;
896
898
899 if (status == DB_SUCCESS) {
900 ss_repair_utf8(buf);
901 dresult->AddToArray(MJsonNode::MakeJSON(buf));
902 sresult->AddToArray(MJsonNode::MakeInt(status));
903 } else {
904 dresult->AddToArray(MJsonNode::MakeNull());
905 sresult->AddToArray(MJsonNode::MakeInt(status));
906 }
907
908 if (buf)
909 free(buf);
910 }
911
912 return mjsonrpc_make_result("data", dresult, "status", sresult);
913}
INT db_copy_json_save(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10475
#define end
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_create()

static MJsonNode * js_db_create ( const MJsonNode *  params)
static

Definition at line 1030 of file mjsonrpc.cxx.

1031{
1032 if (!params) {
1033 MJSO* doc = MJSO::I();
1034 doc->D("Create new ODB entries");
1035 MJSO* o = doc->PA("array of ODB paths to be created")->AddObject("", "arguments to db_create_key() and db_set_num_values()");
1036 o->Add("path", MJSON_STRING, "ODB path to be created");
1037 o->Add("type", MJSON_INT, "MIDAS TID_xxx type");
1038 o->Add("array_length?", MJSON_INT, "optional array length, default is 1");
1039 o->Add("string_length?", MJSON_INT, "for TID_STRING, optional string length, default is NAME_LENGTH");
1040 doc->R("status[]", MJSON_INT, "return status of db_create_key(), db_set_num_values() and db_set_data() (for TID_STRING) for each path");
1041 return doc;
1042 }
1043
1044 MJsonNode* sresult = MJsonNode::MakeArray();
1045
1046 const MJsonNodeVector* pp = params->GetArray();
1047
1048 if (!pp) {
1049 delete sresult;
1050 return mjsonrpc_make_error(-32602, "Invalid params", "parameters must be an array of objects");
1051 }
1052
1053 HNDLE hDB;
1055
1056 for (unsigned i=0; i<pp->size(); i++) {
1057 const MJsonNode* p = (*pp)[i];
1058 std::string path = mjsonrpc_get_param(p, "path", NULL)->GetString();
1059 int type = mjsonrpc_get_param(p, "type", NULL)->GetInt();
1060 int array_length = mjsonrpc_get_param(p, "array_length", NULL)->GetInt();
1061 int string_length = mjsonrpc_get_param(p, "string_length", NULL)->GetInt();
1062
1063 //printf("create odb [%s], type %d, array %d, string %d\n", path.c_str(), type, array_length, string_length);
1064
1065 if (string_length == 0)
1067
1068 int status = db_create_key(hDB, 0, path.c_str(), type);
1069
1070 if (status == DB_SUCCESS && string_length > 0 && type == TID_STRING) {
1071 HNDLE hKey;
1072 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1073 if (status == DB_SUCCESS) {
1074 char* buf = (char*)calloc(1, string_length);
1075 assert(buf != NULL);
1076 int size = string_length;
1077 status = db_set_data(hDB, hKey, buf, size, 1, TID_STRING);
1078 free(buf);
1079 }
1080 }
1081
1082 if (status == DB_SUCCESS && array_length > 1) {
1083 HNDLE hKey;
1084 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1085 if (status == DB_SUCCESS)
1087 }
1088
1089 sresult->AddToArray(MJsonNode::MakeInt(status));
1090 }
1091
1092 return mjsonrpc_make_result("status", sresult);
1093}
MJSO * AddObject(const char *name, const char *description)
Definition mjsonrpc.cxx:385
void Add(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:356
MJSO * PA(const char *description)
Definition mjsonrpc.cxx:326
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3308
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7215
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7502
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_delete()

static MJsonNode * js_db_delete ( const MJsonNode *  params)
static

Definition at line 1095 of file mjsonrpc.cxx.

1096{
1097 if (!params) {
1098 MJSO* doc = MJSO::I();
1099 doc->D("delete ODB keys");
1100 doc->P("paths[]", MJSON_STRING, "array of ODB paths to delete");
1101 doc->R("status[]", MJSON_INT, "return status of db_delete_key() for each path");
1102 return doc;
1103 }
1104
1105 MJsonNode* error = NULL;
1106
1107 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1108
1109 MJsonNode* sresult = MJsonNode::MakeArray();
1110
1111 HNDLE hDB;
1113
1114 for (unsigned i=0; i<paths->size(); i++) {
1115 int status = 0;
1116 HNDLE hkey;
1117 std::string path = (*paths)[i]->GetString();
1118
1119 status = db_find_link(hDB, 0, path.c_str(), &hkey);
1120 if (status != DB_SUCCESS) {
1121 sresult->AddToArray(MJsonNode::MakeInt(status));
1122 continue;
1123 }
1124
1125 status = db_delete_key(hDB, hkey, false);
1126 sresult->AddToArray(MJsonNode::MakeInt(status));
1127 }
1128
1129 return mjsonrpc_make_result("status", sresult);
1130}
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3856
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4274
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_get_values()

static MJsonNode * js_db_get_values ( const MJsonNode *  params)
static

Definition at line 640 of file mjsonrpc.cxx.

641{
642 if (!params) {
643 MJSO* doc = MJSO::I();
644 doc->D("get values of ODB data from given subtrees");
645 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths, see note on array indices");
646 doc->P("omit_names?", MJSON_BOOL, "omit the /name entries");
647 doc->P("omit_last_written?", MJSON_BOOL, "omit the /last_written entries and the last_written[] result");
648 doc->P("omit_tid?", MJSON_BOOL, "omit the tid[] result");
649 doc->P("omit_old_timestamp?", MJSON_NUMBER, "omit data older than given ODB timestamp");
650 doc->P("preserve_case?", MJSON_BOOL, "preserve the capitalization of ODB key names (WARNING: ODB is not case sensitive); note that this will also have side effect of setting the omit_names option");
651 doc->R("data[]", 0, "values of ODB data for each path, all key names are in lower case, all symlinks are followed");
652 doc->R("status[]", MJSON_INT, "return status of db_copy_json_values() or db_copy_json_index() for each path");
653 doc->R("tid?[]", MJSON_INT, "odb type id for each path, absent if omit_tid is true");
654 doc->R("last_written?[]", MJSON_NUMBER, "last_written value of the ODB subtree for each path, absent if omit_last_written is true");
655 return doc;
656 }
657
658 MJsonNode* error = NULL;
659
660 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
661
662 bool omit_names = mjsonrpc_get_param(params, "omit_names", NULL)->GetBool();
663 bool omit_last_written = mjsonrpc_get_param(params, "omit_last_written", NULL)->GetBool();
664 bool omit_tid = mjsonrpc_get_param(params, "omit_tid", NULL)->GetBool();
665 double xomit_old_timestamp = mjsonrpc_get_param(params, "omit_old_timestamp", NULL)->GetDouble();
667 bool preserve_case = mjsonrpc_get_param(params, "preserve_case", NULL)->GetBool();
668
669 MJsonNode* dresult = MJsonNode::MakeArray();
670 MJsonNode* sresult = MJsonNode::MakeArray();
671 MJsonNode* tresult = MJsonNode::MakeArray();
672 MJsonNode* lwresult = MJsonNode::MakeArray();
673
674 HNDLE hDB;
676
677 for (unsigned i=0; i<paths->size(); i++) {
678 int status = 0;
679 HNDLE hkey;
680 KEY key;
681 std::string path = (*paths)[i]->GetString();
682
683 status = db_find_key(hDB, 0, path.c_str(), &hkey);
684 if (status != DB_SUCCESS) {
685 dresult->AddToArray(MJsonNode::MakeNull());
686 sresult->AddToArray(MJsonNode::MakeInt(status));
687 tresult->AddToArray(MJsonNode::MakeNull());
688 lwresult->AddToArray(MJsonNode::MakeNull());
689 continue;
690 }
691
693 if (status != DB_SUCCESS) {
694 dresult->AddToArray(MJsonNode::MakeNull());
695 sresult->AddToArray(MJsonNode::MakeInt(status));
696 tresult->AddToArray(MJsonNode::MakeNull());
697 lwresult->AddToArray(MJsonNode::MakeNull());
698 continue;
699 }
700
701 if (path.find("[") != std::string::npos) {
702 std::vector<unsigned> list;
703 status = parse_array_index_list("js_db_get_values", path.c_str(), &list);
704
705 if (status != SUCCESS) {
706 dresult->AddToArray(MJsonNode::MakeNull());
707 sresult->AddToArray(MJsonNode::MakeInt(status));
708 tresult->AddToArray(MJsonNode::MakeInt(key.type));
709 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
710 continue;
711 }
712
713 if (list.size() > 1) {
714 MJsonNode *ddresult = MJsonNode::MakeArray();
715 MJsonNode *ssresult = MJsonNode::MakeArray();
716
717 for (unsigned i=0; i<list.size(); i++) {
718 char* buf = NULL;
719 int bufsize = 0;
720 int end = 0;
721
723 if (status == DB_SUCCESS) {
724 ss_repair_utf8(buf);
725 ddresult->AddToArray(MJsonNode::MakeJSON(buf));
726 ssresult->AddToArray(MJsonNode::MakeInt(status));
727 } else {
728 ddresult->AddToArray(MJsonNode::MakeNull());
729 ssresult->AddToArray(MJsonNode::MakeInt(status));
730 }
731
732 if (buf)
733 free(buf);
734 }
735
736 dresult->AddToArray(ddresult);
737 sresult->AddToArray(ssresult);
738 tresult->AddToArray(MJsonNode::MakeInt(key.type));
739 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
740
741 } else {
742 char* buf = NULL;
743 int bufsize = 0;
744 int end = 0;
745
746 status = db_copy_json_index(hDB, hkey, list[0], &buf, &bufsize, &end);
747 if (status == DB_SUCCESS) {
748 ss_repair_utf8(buf);
749 dresult->AddToArray(MJsonNode::MakeJSON(buf));
750 sresult->AddToArray(MJsonNode::MakeInt(status));
751 tresult->AddToArray(MJsonNode::MakeInt(key.type));
752 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
753 } else {
754 dresult->AddToArray(MJsonNode::MakeNull());
755 sresult->AddToArray(MJsonNode::MakeInt(status));
756 tresult->AddToArray(MJsonNode::MakeInt(key.type));
757 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
758 }
759
760 if (buf)
761 free(buf);
762 }
763 } else {
764 char* buf = NULL;
765 int bufsize = 0;
766 int end = 0;
767
770
771 if (status == DB_SUCCESS) {
772 ss_repair_utf8(buf);
773 dresult->AddToArray(MJsonNode::MakeJSON(buf));
774 sresult->AddToArray(MJsonNode::MakeInt(status));
775 tresult->AddToArray(MJsonNode::MakeInt(key.type));
776 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
777 } else {
778 dresult->AddToArray(MJsonNode::MakeNull());
779 sresult->AddToArray(MJsonNode::MakeInt(status));
780 tresult->AddToArray(MJsonNode::MakeInt(key.type));
781 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
782 }
783
784 if (buf)
785 free(buf);
786 }
787 }
788
789 MJsonNode* result = MJsonNode::MakeObject();
790
791 result->AddToObject("data", dresult);
792 result->AddToObject("status", sresult);
793 if (!omit_tid)
794 result->AddToObject("tid", tresult);
795 else
796 delete tresult;
798 result->AddToObject("last_written", lwresult);
799 else
800 delete lwresult;
801
802 return mjsonrpc_make_result(result);
803}
INT db_copy_json_index(HNDLE hDB, HNDLE hKey, int index, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10219
INT db_copy_json_values(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int omit_names, int omit_last_written, time_t omit_old_timestamp, int preserve_case)
Definition odb.cxx:10443
static int parse_array_index_list(const char *method, const char *path, std::vector< unsigned > *list)
Definition mjsonrpc.cxx:560
DWORD type
Definition midas.h:1027
INT last_written
Definition midas.h:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_key()

static MJsonNode * js_db_key ( const MJsonNode *  params)
static

Definition at line 1234 of file mjsonrpc.cxx.

1235{
1236 if (!params) {
1237 MJSO* doc = MJSO::I();
1238 doc->D("get ODB keys");
1239 doc->P("paths[]", MJSON_STRING, "array of ODB paths");
1240 doc->R("status[]", MJSON_INT, "return status of db_key() for each path");
1241 doc->R("keys[]", MJSON_OBJECT, "key data for each path");
1242 doc->R("keys[].type", MJSON_INT, "key type TID_xxx");
1243 doc->R("keys[].num_values", MJSON_INT, "array length, 1 for normal entries");
1244 doc->R("keys[].name", MJSON_STRING, "key name");
1245 doc->R("keys[].total_size", MJSON_INT, "data total size in bytes");
1246 doc->R("keys[].item_size", MJSON_INT, "array element size, string length for TID_STRING");
1247 doc->R("keys[].access_mode", MJSON_INT, "access mode bitmap of MODE_xxx");
1248 doc->R("keys[].notify_count", MJSON_INT, "number of hotlinks attached to this key");
1249 doc->R("keys[].last_written", MJSON_INT, "timestamp when data was last updated");
1250 return doc;
1251 }
1252
1253 MJsonNode* error = NULL;
1254
1255 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1256
1257 MJsonNode* kresult = MJsonNode::MakeArray();
1258 MJsonNode* sresult = MJsonNode::MakeArray();
1259
1260 HNDLE hDB;
1262
1263 for (unsigned i=0; i<paths->size(); i++) {
1264 int status = 0;
1265 HNDLE hkey;
1266 KEY key;
1267 std::string path = (*paths)[i]->GetString();
1268
1269 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1270 if (status != DB_SUCCESS) {
1271 kresult->AddToArray(MJsonNode::MakeNull());
1272 sresult->AddToArray(MJsonNode::MakeInt(status));
1273 continue;
1274 }
1275
1277 if (status != DB_SUCCESS) {
1278 kresult->AddToArray(MJsonNode::MakeNull());
1279 sresult->AddToArray(MJsonNode::MakeInt(status));
1280 continue;
1281 }
1282
1283 MJsonNode* jkey = MJsonNode::MakeObject();
1284
1285 jkey->AddToObject("type", MJsonNode::MakeInt(key.type));
1286 jkey->AddToObject("num_values", MJsonNode::MakeInt(key.num_values));
1288 jkey->AddToObject("name", MJsonNode::MakeString(key.name));
1289 jkey->AddToObject("total_size", MJsonNode::MakeInt(key.total_size));
1290 jkey->AddToObject("item_size", MJsonNode::MakeInt(key.item_size));
1291 jkey->AddToObject("access_mode", MJsonNode::MakeInt(key.access_mode));
1292 jkey->AddToObject("notify_count", MJsonNode::MakeInt(key.notify_count));
1293 jkey->AddToObject("last_written", MJsonNode::MakeInt(key.last_written));
1294
1295 kresult->AddToArray(jkey);
1296 sresult->AddToArray(MJsonNode::MakeInt(status));
1297 }
1298
1299 return mjsonrpc_make_result("keys", kresult, "status", sresult);
1300}
INT num_values
Definition midas.h:1028
WORD notify_count
Definition midas.h:1034
INT total_size
Definition midas.h:1031
WORD access_mode
Definition midas.h:1033
INT item_size
Definition midas.h:1032
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_link()

static MJsonNode * js_db_link ( const MJsonNode *  params)
static

Definition at line 1352 of file mjsonrpc.cxx.

1353{
1354 if (!params) {
1355 MJSO* doc = MJSO::I();
1356 doc->D("Create ODB symlinks");
1357 doc->P("new_links[]", MJSON_STRING, "array of new symlinks to be created");
1358 doc->P("target_paths[]", MJSON_STRING, "array of existing ODB paths for each link");
1359 doc->R("status[]", MJSON_INT, "return status of db_create_link() for each path");
1360 return doc;
1361 }
1362
1363 MJsonNode* error = NULL;
1364
1365 const MJsonNodeVector* target_paths = mjsonrpc_get_param_array(params, "target_paths", &error); if (error) return error;
1366 const MJsonNodeVector* new_links = mjsonrpc_get_param_array(params, "new_links", &error); if (error) return error;
1367
1368 if (target_paths->size() != new_links->size()) {
1369 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"target_paths\" and \"new_links\" should have the same length");
1370 }
1371
1372 MJsonNode* sresult = MJsonNode::MakeArray();
1373
1374 HNDLE hDB;
1376
1377 for (unsigned i=0; i<new_links->size(); i++) {
1378 int status = 0;
1379 std::string target_path = (*target_paths)[i]->GetString();
1380 std::string new_link = (*new_links)[i]->GetString();
1381 if (new_link.length() < 1) {
1382 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1383 continue;
1384 }
1385
1386 status = db_create_link(hDB, 0, new_link.c_str(), target_path.c_str());
1387
1388 sresult->AddToArray(MJsonNode::MakeInt(status));
1389 }
1390
1391 return mjsonrpc_make_result("status", sresult);
1392}
#define DB_INVALID_PARAM
Definition midas.h:639
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:3601
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_ls()

static MJsonNode * js_db_ls ( const MJsonNode *  params)
static

Definition at line 805 of file mjsonrpc.cxx.

806{
807 if (!params) {
808 MJSO* doc = MJSO::I();
809 doc->D("get contents of given ODB subdirectory in the \"ls\" json encoding - similar to odbedit command \"ls -l\"");
810 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths");
811 doc->R("data[]", MJSON_OBJECT, "keys and values of ODB data for each path");
812 doc->R("status[]", MJSON_INT, "return status of db_copy_json_ls() for each path");
813 return doc;
814 }
815
816 MJsonNode* error = NULL;
817
818 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
819
820 MJsonNode* dresult = MJsonNode::MakeArray();
821 MJsonNode* sresult = MJsonNode::MakeArray();
822
823 HNDLE hDB;
825
826 for (unsigned i=0; i<paths->size(); i++) {
827 int status = 0;
828 HNDLE hkey;
829 std::string path = (*paths)[i]->GetString();
830
831 status = db_find_key(hDB, 0, path.c_str(), &hkey);
832 if (status != DB_SUCCESS) {
833 dresult->AddToArray(MJsonNode::MakeNull());
834 sresult->AddToArray(MJsonNode::MakeInt(status));
835 continue;
836 }
837
838 char* buf = NULL;
839 int bufsize = 0;
840 int end = 0;
841
843
844 if (status == DB_SUCCESS) {
845 ss_repair_utf8(buf);
846 dresult->AddToArray(MJsonNode::MakeJSON(buf));
847 sresult->AddToArray(MJsonNode::MakeInt(status));
848 } else {
849 dresult->AddToArray(MJsonNode::MakeNull());
850 sresult->AddToArray(MJsonNode::MakeInt(status));
851 }
852
853 if (buf)
854 free(buf);
855 }
856
857 return mjsonrpc_make_result("data", dresult, "status", sresult);
858}
INT db_copy_json_ls(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10421
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_paste()

static MJsonNode * js_db_paste ( const MJsonNode *  params)
static

Definition at line 915 of file mjsonrpc.cxx.

916{
917 if (!params) {
918 MJSO* doc = MJSO::I();
919 doc->D("write data into ODB");
920 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths, see note on array indices");
921 doc->P("values[]", 0, "array of data values written to ODB via db_paste_json() for each path");
922 doc->R("status[]", MJSON_INT, "array of return status of db_paste_json() for each path");
923 return doc;
924 }
925
926 MJsonNode* error = NULL;
927
928 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
929 const MJsonNodeVector* values = mjsonrpc_get_param_array(params, "values", &error); if (error) return error;
930
931 if (paths->size() != values->size()) {
932 return mjsonrpc_make_error(-32602, "Invalid params", "paths and values should have the same length");
933 }
934
935 MJsonNode* sresult = MJsonNode::MakeArray();
936
937 HNDLE hDB;
939
940 for (unsigned i=0; i<paths->size(); i++) {
941 int status = 0;
942 HNDLE hkey;
943 std::string path = (*paths)[i]->GetString();
944
945 status = db_find_key(hDB, 0, path.c_str(), &hkey);
946 if (status != DB_SUCCESS) {
947 sresult->AddToArray(MJsonNode::MakeInt(status));
948 continue;
949 }
950
951 const MJsonNode* v = (*values)[i];
952 assert(v != NULL);
953
954 if (path.find("[*]") != std::string::npos) {
955
956 KEY key;
958 for (int j=0 ; j<key.num_values ; j++)
960
961 } else if (path.find("[") != std::string::npos) {
962 std::vector<unsigned> list;
963 status = parse_array_index_list("js_db_paste", path.c_str(), &list);
964
965 if (status != SUCCESS) {
966 sresult->AddToArray(MJsonNode::MakeInt(status));
967 continue;
968 }
969
970 // supported permutations of array indices and data values:
971 // single index: intarray[1] -> data should be a single value: MJSON_ARRAY is rejected right here, MJSON_OBJECT is rejected by db_paste
972 // multiple index intarray[1,2,3] -> data should be an array of equal length, or
973 // multiple index intarray[1,2,3] -> if data is a single value, all array elements are set to this same value
974
975 if (list.size() < 1) {
976 cm_msg(MERROR, "js_db_paste", "invalid array indices for array path \"%s\"", path.c_str());
977 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
978 continue;
979 } else if (list.size() == 1) {
980 if (v->GetType() == MJSON_ARRAY) {
981 cm_msg(MERROR, "js_db_paste", "unexpected array of values for array path \"%s\"", path.c_str());
982 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
983 continue;
984 }
985
987 sresult->AddToArray(MJsonNode::MakeInt(status));
988 } else if ((list.size() > 1) && (v->GetType() == MJSON_ARRAY)) {
989 const MJsonNodeVector* vvalues = v->GetArray();
990
991 if (list.size() != vvalues->size()) {
992 cm_msg(MERROR, "js_db_paste", "length of values array %d should be same as number of indices %d for array path \"%s\"", (int)vvalues->size(), (int)list.size(), path.c_str());
993 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
994 continue;
995 }
996
997 MJsonNode *ssresult = MJsonNode::MakeArray();
998
999 for (unsigned j =0; j <list.size(); j++) {
1000 const MJsonNode* vv = (*vvalues)[j];
1001
1002 if (vv == NULL) {
1003 cm_msg(MERROR, "js_db_paste", "internal error: NULL array value at index %d for array path \"%s\"", j, path.c_str());
1004 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
1005 continue;
1006 }
1007
1009 ssresult->AddToArray(MJsonNode::MakeInt(status));
1010 }
1011
1012 sresult->AddToArray(ssresult);
1013 } else {
1014 MJsonNode *ssresult = MJsonNode::MakeArray();
1015 for (unsigned j =0; j <list.size(); j++) {
1017 ssresult->AddToArray(MJsonNode::MakeInt(status));
1018 }
1019 sresult->AddToArray(ssresult);
1020 }
1021 } else {
1023 sresult->AddToArray(MJsonNode::MakeInt(status));
1024 }
1025 }
1026
1027 return mjsonrpc_make_result("status", sresult);
1028}
#define DB_TYPE_MISMATCH
Definition midas.h:645
INT EXPRT db_paste_json_node(HNDLE hDB, HNDLE hKeyRoot, int index, const MJsonNode *node)
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_rename()

static MJsonNode * js_db_rename ( const MJsonNode *  params)
static

Definition at line 1302 of file mjsonrpc.cxx.

1303{
1304 if (!params) {
1305 MJSO* doc = MJSO::I();
1306 doc->D("Change size of ODB arrays");
1307 doc->P("paths[]", MJSON_STRING, "array of ODB paths to rename");
1308 doc->P("new_names[]", MJSON_STRING, "array of new names for each ODB path");
1309 doc->R("status[]", MJSON_INT, "return status of db_rename_key() for each path");
1310 return doc;
1311 }
1312
1313 MJsonNode* error = NULL;
1314
1315 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1316 const MJsonNodeVector* names = mjsonrpc_get_param_array(params, "new_names", &error); if (error) return error;
1317
1318 if (paths->size() != names->size()) {
1319 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_names\" should have the same length");
1320 }
1321
1322 MJsonNode* sresult = MJsonNode::MakeArray();
1323
1324 HNDLE hDB;
1326
1327 for (unsigned i=0; i<paths->size(); i++) {
1328 int status = 0;
1329 HNDLE hkey;
1330 std::string path = (*paths)[i]->GetString();
1331
1332 status = db_find_link(hDB, 0, path.c_str(), &hkey);
1333 if (status != DB_SUCCESS) {
1334 sresult->AddToArray(MJsonNode::MakeInt(status));
1335 continue;
1336 }
1337
1338 std::string new_name = (*names)[i]->GetString();
1339 if (new_name.length() < 1) {
1340 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1341 continue;
1342 }
1343
1344 status = db_rename_key(hDB, hkey, new_name.c_str());
1345
1346 sresult->AddToArray(MJsonNode::MakeInt(status));
1347 }
1348
1349 return mjsonrpc_make_result("status", sresult);
1350}
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6261
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_reorder()

static MJsonNode * js_db_reorder ( const MJsonNode *  params)
static

Definition at line 1394 of file mjsonrpc.cxx.

1395{
1396 if (!params) {
1397 MJSO* doc = MJSO::I();
1398 doc->D("Change order of ODB keys in a subdirectory");
1399 doc->P("paths[]", MJSON_STRING, "array of new symlinks to be created");
1400 doc->P("indices[]", MJSON_INT, "array of existing ODB paths for each link");
1401 doc->R("status[]", MJSON_INT, "return status of db_reorder_key() for each path");
1402 return doc;
1403 }
1404
1405 MJsonNode* error = NULL;
1406
1407 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1408 const MJsonNodeVector* indices = mjsonrpc_get_param_array(params, "indices", &error); if (error) return error;
1409
1410 if (paths->size() != indices->size()) {
1411 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"indices\" should have the same length");
1412 }
1413
1414 MJsonNode* sresult = MJsonNode::MakeArray();
1415
1416 HNDLE hDB;
1418
1419 for (unsigned i=0; i<paths->size(); i++) {
1420 int status = 0;
1421 HNDLE hkey;
1422 std::string path = (*paths)[i]->GetString();
1423 int index = (*indices)[i]->GetInt();
1424
1425 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1426 if (status != DB_SUCCESS) {
1427 sresult->AddToArray(MJsonNode::MakeInt(status));
1428 continue;
1429 }
1430
1432
1433 sresult->AddToArray(MJsonNode::MakeInt(status));
1434 }
1435
1436 return mjsonrpc_make_result("status", sresult);
1437}
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6361
INT index
Definition mana.cxx:271
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_resize()

static MJsonNode * js_db_resize ( const MJsonNode *  params)
static

Definition at line 1132 of file mjsonrpc.cxx.

1133{
1134 if (!params) {
1135 MJSO* doc = MJSO::I();
1136 doc->D("Change size of ODB arrays");
1137 doc->P("paths[]", MJSON_STRING, "array of ODB paths to resize");
1138 doc->P("new_lengths[]", MJSON_INT, "array of new lengths for each ODB path");
1139 doc->R("status[]", MJSON_INT, "return status of db_set_num_values() for each path");
1140 return doc;
1141 }
1142
1143 MJsonNode* error = NULL;
1144
1145 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1146 const MJsonNodeVector* lengths = mjsonrpc_get_param_array(params, "new_lengths", &error); if (error) return error;
1147
1148 if (paths->size() != lengths->size()) {
1149 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_lengths\" should have the same length");
1150 }
1151
1152 MJsonNode* sresult = MJsonNode::MakeArray();
1153
1154 HNDLE hDB;
1156
1157 for (unsigned i=0; i<paths->size(); i++) {
1158 int status = 0;
1159 HNDLE hkey;
1160 std::string path = (*paths)[i]->GetString();
1161
1162 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1163 if (status != DB_SUCCESS) {
1164 sresult->AddToArray(MJsonNode::MakeInt(status));
1165 continue;
1166 }
1167
1168 int length = (*lengths)[i]->GetInt();
1169 if (length < 1) {
1170 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1171 continue;
1172 }
1173
1175 sresult->AddToArray(MJsonNode::MakeInt(status));
1176 }
1177
1178 return mjsonrpc_make_result("status", sresult);
1179}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_resize_string()

static MJsonNode * js_db_resize_string ( const MJsonNode *  params)
static

Definition at line 1181 of file mjsonrpc.cxx.

1182{
1183 if (!params) {
1184 MJSO* doc = MJSO::I();
1185 doc->D("Change size of ODB string arrays");
1186 doc->P("paths[]", MJSON_STRING, "array of ODB paths to resize");
1187 doc->P("new_lengths[]", MJSON_INT, "array of new lengths for each ODB path");
1188 doc->P("new_string_lengths[]", MJSON_INT, "array of new string lengths for each ODB path");
1189 doc->R("status[]", MJSON_INT, "return status of db_resize_string() for each path");
1190 return doc;
1191 }
1192
1193 MJsonNode* error = NULL;
1194
1195 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1196 const MJsonNodeVector* lengths = mjsonrpc_get_param_array(params, "new_lengths", &error); if (error) return error;
1197 const MJsonNodeVector* string_lengths = mjsonrpc_get_param_array(params, "new_string_lengths", &error); if (error) return error;
1198
1199 if (paths->size() != lengths->size()) {
1200 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_lengths\" should have the same length");
1201 }
1202
1203 if (paths->size() != string_lengths->size()) {
1204 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_string_lengths\" should have the same length");
1205 }
1206
1207 MJsonNode* sresult = MJsonNode::MakeArray();
1208
1209 HNDLE hDB;
1211
1212 for (unsigned i=0; i<paths->size(); i++) {
1213 std::string path = (*paths)[i]->GetString();
1214
1215 int length = (*lengths)[i]->GetInt();
1216 if (length < 0) {
1217 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1218 continue;
1219 }
1220
1221 int string_length = (*string_lengths)[i]->GetInt();
1222 if (length < 0) {
1223 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1224 continue;
1225 }
1226
1227 int status = db_resize_string(hDB, 0, path.c_str(), length, string_length);
1228 sresult->AddToArray(MJsonNode::MakeInt(status));
1229 }
1230
1231 return mjsonrpc_make_result("status", sresult);
1232}
INT EXPRT db_resize_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int num_values, int max_string_length)
Definition odb.cxx:14026
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_scl()

static MJsonNode * js_db_scl ( const MJsonNode *  params)
static

Definition at line 1461 of file mjsonrpc.cxx.

1462{
1463 if (!params) {
1464 MJSO* doc = MJSO::I();
1465 doc->D("Show ODB clients");
1466 doc->R("scl", MJSON_JSON, "return value of db_scl()");
1467 return doc;
1468 }
1469
1470 HNDLE hDB;
1472
1473 MJsonNode* scl = db_scl(hDB);
1474
1475 return mjsonrpc_make_result("scl", scl);
1476}
MJsonNode * db_scl(HNDLE hDB)
Definition odb.cxx:14112
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_sor()

static MJsonNode * js_db_sor ( const MJsonNode *  params)
static

Definition at line 1439 of file mjsonrpc.cxx.

1440{
1441 if (!params) {
1442 MJSO* doc = MJSO::I();
1443 doc->D("Show ODB open records starting from given ODB path");
1444 doc->P("path?", MJSON_STRING, "ODB path");
1445 doc->R("sor", MJSON_JSON, "return value of db_sor()");
1446 return doc;
1447 }
1448
1449 MJsonNode* error = NULL;
1450
1451 std::string path = mjsonrpc_get_param(params, "path", NULL)->GetString(); if (error) return error;
1452
1453 HNDLE hDB;
1455
1456 MJsonNode* sor = db_sor(hDB, path.c_str());
1457
1458 return mjsonrpc_make_result("sor", sor);
1459}
MJsonNode * db_sor(HNDLE hDB, const char *root_path)
Definition odb.cxx:14162
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_delete()

static MJsonNode * js_el_delete ( const MJsonNode *  params)
static

Definition at line 3334 of file mjsonrpc.cxx.

3335{
3336 if (!params) {
3337 MJSO* doc = MJSO::I();
3338 doc->D("Delete elog message");
3339 doc->P("tag", MJSON_STRING, "tag of message to delete");
3340 doc->R("status", MJSON_INT, "return status of el_delete");
3341 return doc;
3342 }
3343
3344 MJsonNode* error = NULL;
3345 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
3346 int status = el_delete_message(tag.c_str());
3347 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3348}
INT el_delete_message(const char *tag)
Definition elog.cxx:1014
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_query()

static MJsonNode * js_el_query ( const MJsonNode *  params)
static

Definition at line 3059 of file mjsonrpc.cxx.

3060{
3061 if (!params) {
3062 MJSO* doc = MJSO::I();
3063 doc->D("Query elog messages");
3064 doc->P("last_n_hours?", MJSON_INT, "return messages from the last N hours");
3065 doc->R("status", MJSON_INT, "return status of el_retrieve");
3066 doc->R("msg[].tag", MJSON_STRING, "message tag");
3067 return doc;
3068 }
3069
3070 //MJsonNode* error = NULL;
3071
3072 //int last_n = mjsonrpc_get_param(params, "last_n_hours", &error)->GetInt(); if (error) return error;
3073 int last_n = mjsonrpc_get_param(params, "last_n_hours", NULL)->GetInt();
3074
3075 std::string pd1 = mjsonrpc_get_param(params, "d1", NULL)->GetString();
3076 std::string pm1 = mjsonrpc_get_param(params, "m1", NULL)->GetString();
3077 std::string py1 = mjsonrpc_get_param(params, "y1", NULL)->GetString();
3078
3079 std::string pd2 = mjsonrpc_get_param(params, "d2", NULL)->GetString();
3080 std::string pm2 = mjsonrpc_get_param(params, "m2", NULL)->GetString();
3081 std::string py2 = mjsonrpc_get_param(params, "y2", NULL)->GetString();
3082
3083 std::string pr1 = mjsonrpc_get_param(params, "r1", NULL)->GetString();
3084 std::string pr2 = mjsonrpc_get_param(params, "r2", NULL)->GetString();
3085
3086 std::string ptype = mjsonrpc_get_param(params, "type", NULL)->GetString();
3087 std::string psystem = mjsonrpc_get_param(params, "system", NULL)->GetString();
3088 std::string pauthor = mjsonrpc_get_param(params, "author", NULL)->GetString();
3089 std::string psubject = mjsonrpc_get_param(params, "subject", NULL)->GetString();
3090 std::string psubtext = mjsonrpc_get_param(params, "subtext", NULL)->GetString();
3091
3092 MJsonNode* msg_array = MJsonNode::MakeArray();
3093
3094 int i, size, run, status;
3095 char date[80], author[80], type[80], system[80], subject[256], text[10000],
3096 orig_tag[80], reply_tag[80], attachment[3][256], encoding[80];
3097 char str[256], str2[10000], tag[256];
3098 struct tm tms;
3099
3100 // month name from midas.c
3101 extern const char *mname[];
3102
3103 /*---- convert end date to ltime ----*/
3104
3105 int y1 = -1;
3106 int m1 = -1;
3107 int d1 = -1;
3108
3109 int y2 = -1;
3110 int m2 = -1;
3111 int d2 = -1;
3112
3113 int r1 = -1;
3114 int r2 = -1;
3115
3116 if (pr1.length()>0)
3117 r1 = atoi(pr1.c_str());
3118
3119 if (pr2.length()>0)
3120 r2 = atoi(pr2.c_str());
3121
3122 time_t ltime_start = 0;
3123 time_t ltime_end = 0;
3124
3125 if (!last_n) {
3126 // decode starting date year, day and month
3127
3128 if (py1.length() > 0)
3129 y1 = atoi(py1.c_str());
3130
3131 if (pd1.length() > 0)
3132 d1 = atoi(pd1.c_str());
3133
3134 mstrlcpy(str, pm1.c_str(), sizeof(str));
3135 for (m1 = 0; m1 < 12; m1++)
3136 if (equal_ustring(str, mname[m1]))
3137 break;
3138 if (m1 == 12)
3139 m1 = 0;
3140
3141 if (pd2.length() > 0) {
3142 d2 = atoi(pd2.c_str());
3143 }
3144
3145 if (py2.length() > 0) {
3146 // decode ending date year, day and month
3147
3148 mstrlcpy(str, pm2.c_str(), sizeof(str));
3149 for (m2 = 0; m2 < 12; m2++)
3150 if (equal_ustring(str, mname[m2]))
3151 break;
3152 if (m2 == 12) {
3153 m2 = 0;
3154 }
3155 }
3156
3157 if (py2.length() > 0) {
3158 y2 = atoi(py2.c_str());
3159 }
3160
3161 if (y2>=0 && m2>=0 && d2>=0) {
3162 memset(&tms, 0, sizeof(struct tm));
3163 tms.tm_year = y2 % 100;
3164 tms.tm_mon = m2;
3165 tms.tm_mday = d2;
3166 tms.tm_hour = 24;
3167
3168 if (tms.tm_year < 90)
3169 tms.tm_year += 100;
3171 }
3172 }
3173
3174 /*---- do query ----*/
3175
3176 tag[0] = 0;
3177
3178 if (last_n) {
3179 ss_tzset(); // required for localtime_r()
3180 time_t now = time(NULL);
3181 ltime_start = now - 3600 * last_n;
3182 struct tm tms;
3184 sprintf(tag, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
3185 } else if (r1 > 0) {
3186 /* do run query */
3187 el_search_run(r1, tag);
3188 } else if (y1>=0 && m1>=0 && d1>=0) {
3189 /* do date-date query */
3190 sprintf(tag, "%02d%02d%02d.0", y1 % 100, m1 + 1, d1);
3191 }
3192
3193#if 0
3194 printf("js_el_query: y1 %d, m1 %d, d1 %d, y2 %d, m2 %d, d2 %d, r1 %d, r2 %d, last_n_hours %d, start time %lu, end time %lu, tag [%s]\n",
3195 y1, m1, d1,
3196 y2, m2, d2,
3197 r1, r2,
3198 last_n,
3200 ltime_end,
3201 tag);
3202#endif
3203
3204 do {
3205 size = sizeof(text);
3206 status = el_retrieve(tag, date, &run, author, type, system, subject,
3207 text, &size, orig_tag, reply_tag,
3209
3210 std::string this_tag = tag;
3211
3212 //printf("js_el_query: el_retrieve: size %d, status %d, tag [%s], run %d, tags [%s] [%s]\n", size, status, tag, run, orig_tag, reply_tag);
3213
3214 mstrlcat(tag, "+1", sizeof(tag));
3215
3216 /* check for end run */
3217 if ((r2 > 0) && (r2 < run)) {
3218 break;
3219 }
3220
3221 /* convert date to unix format */
3222 memset(&tms, 0, sizeof(struct tm));
3223 tms.tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
3224 tms.tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
3225 tms.tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
3226 tms.tm_hour = (date[11] - '0') * 10 + (date[12] - '0');
3227 tms.tm_min = (date[14] - '0') * 10 + (date[15] - '0');
3228 tms.tm_sec = (date[17] - '0') * 10 + (date[18] - '0');
3229
3230 if (tms.tm_year < 90)
3231 tms.tm_year += 100;
3232
3234
3235 //printf("js_el_query: ltime: start %ld, end %ld, current %ld\n", ltime_start, ltime_end, ltime_current);
3236
3237 /* check for start date */
3238 if (ltime_start > 0)
3240 continue;
3241
3242 /* check for end date */
3243 if (ltime_end > 0) {
3245 break;
3246 }
3247
3248 if (status == EL_SUCCESS) {
3249 /* do filtering */
3250 if ((ptype.length()>0) && !equal_ustring(ptype.c_str(), type))
3251 continue;
3252 if ((psystem.length()>0) && !equal_ustring(psystem.c_str(), system))
3253 continue;
3254
3255 if (pauthor.length()>0) {
3256 mstrlcpy(str, pauthor.c_str(), sizeof(str));
3257 for (i = 0; i < (int) strlen(str); i++)
3258 str[i] = toupper(str[i]);
3259 str[i] = 0;
3260 for (i = 0; i < (int) strlen(author) && author[i] != '@'; i++)
3261 str2[i] = toupper(author[i]);
3262 str2[i] = 0;
3263
3264 if (strstr(str2, str) == NULL)
3265 continue;
3266 }
3267
3268 if (psubject.length()>0) {
3269 mstrlcpy(str, psubject.c_str(), sizeof(str));
3270 for (i = 0; i < (int) strlen(str); i++)
3271 str[i] = toupper(str[i]);
3272 str[i] = 0;
3273 for (i = 0; i < (int) strlen(subject); i++)
3274 str2[i] = toupper(subject[i]);
3275 str2[i] = 0;
3276
3277 if (strstr(str2, str) == NULL)
3278 continue;
3279 }
3280
3281 if (psubtext.length()>0) {
3282 mstrlcpy(str, psubtext.c_str(), sizeof(str));
3283 for (i = 0; i < (int) strlen(str); i++)
3284 str[i] = toupper(str[i]);
3285 str[i] = 0;
3286 for (i = 0; i < (int) strlen(text); i++)
3287 str2[i] = toupper(text[i]);
3288 str2[i] = 0;
3289
3290 if (strstr(str2, str) == NULL)
3291 continue;
3292 }
3293
3294 /* filter passed: display line */
3295
3296 MJsonNode* msg = MJsonNode::MakeObject();
3297
3299 msg->AddToObject("tag", MJsonNode::MakeString(this_tag.c_str()));
3301 msg->AddToObject("date", MJsonNode::MakeString(date));
3302 msg->AddToObject("run", MJsonNode::MakeInt(run));
3303 ss_repair_utf8(author);
3304 msg->AddToObject("author", MJsonNode::MakeString(author));
3306 msg->AddToObject("type", MJsonNode::MakeString(type));
3308 msg->AddToObject("system", MJsonNode::MakeString(system));
3310 msg->AddToObject("subject", MJsonNode::MakeString(subject));
3311 ss_repair_utf8(text);
3312 msg->AddToObject("text", MJsonNode::MakeString(text));
3314 msg->AddToObject("orig_tag", MJsonNode::MakeString(orig_tag));
3316 msg->AddToObject("reply_tag", MJsonNode::MakeString(reply_tag));
3318 msg->AddToObject("attachment0", MJsonNode::MakeString(attachment[0]));
3320 msg->AddToObject("attachment1", MJsonNode::MakeString(attachment[1]));
3322 msg->AddToObject("attachment2", MJsonNode::MakeString(attachment[2]));
3324 msg->AddToObject("encoding", MJsonNode::MakeString(encoding));
3325
3326 msg_array->AddToArray(msg);
3327 }
3328
3329 } while (status == EL_SUCCESS);
3330
3331 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "msg", msg_array);
3332}
INT el_search_run(int run, char *return_tag)
Definition elog.cxx:950
INT el_retrieve(char *tag, char *date, int *run, char *author, char *type, char *syst, char *subject, char *text, int *textsize, char *orig_tag, char *reply_tag, char *attachment1, char *attachment2, char *attachment3, char *encoding)
Definition elog.cxx:770
#define EL_SUCCESS
Definition midas.h:745
time_t ss_mktime(struct tm *tms)
Definition system.cxx:3365
void ss_tzset()
Definition system.cxx:3355
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
const char * mname[]
Definition midas.cxx:144
MUTEX_T * tm
Definition odbedit.cxx:39
DWORD run
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_retrieve()

static MJsonNode * js_el_retrieve ( const MJsonNode *  params)
static

Definition at line 2993 of file mjsonrpc.cxx.

2994{
2995 if (!params) {
2996 MJSO* doc = MJSO::I();
2997 doc->D("Get an elog message");
2998 doc->P("tag", MJSON_STRING, "elog message tag");
2999 doc->R("status", MJSON_INT, "return status of el_retrieve");
3000 doc->R("msg.tag", MJSON_STRING, "message tag");
3001 return doc;
3002 }
3003
3004 MJsonNode* error = NULL;
3005
3006 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
3007
3008 int run = 0;
3009 char date[80], author[80], type[80], system[80], subject[256], text[10000];
3010 char orig_tag[80], reply_tag[80], attachment[3][256], encoding[80];
3011
3012 char xtag[80];
3013 mstrlcpy(xtag, tag.c_str(), sizeof(xtag));
3014
3015 int size = sizeof(text);
3016
3017 int status = el_retrieve(xtag,
3018 date, &run, author, type, system, subject,
3019 text, &size, orig_tag, reply_tag,
3021
3022 //printf("js_el_retrieve: size %d, status %d, tag [%s]\n", size, status, xtag);
3023
3024 MJsonNode* msg = MJsonNode::MakeObject();
3025
3026 if (status == EL_SUCCESS) {
3028 msg->AddToObject("tag", MJsonNode::MakeString(xtag));
3030 msg->AddToObject("date", MJsonNode::MakeString(date));
3031 msg->AddToObject("run", MJsonNode::MakeInt(run));
3032 ss_repair_utf8(author);
3033 msg->AddToObject("author", MJsonNode::MakeString(author));
3035 msg->AddToObject("type", MJsonNode::MakeString(type));
3037 msg->AddToObject("system", MJsonNode::MakeString(system));
3039 msg->AddToObject("subject", MJsonNode::MakeString(subject));
3040 ss_repair_utf8(text);
3041 msg->AddToObject("text", MJsonNode::MakeString(text));
3043 msg->AddToObject("orig_tag", MJsonNode::MakeString(orig_tag));
3045 msg->AddToObject("reply_tag", MJsonNode::MakeString(reply_tag));
3047 msg->AddToObject("attachment0", MJsonNode::MakeString(attachment[0]));
3049 msg->AddToObject("attachment1", MJsonNode::MakeString(attachment[1]));
3051 msg->AddToObject("attachment2", MJsonNode::MakeString(attachment[2]));
3053 msg->AddToObject("encoding", MJsonNode::MakeString(encoding));
3054 }
3055
3056 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "msg", msg);
3057}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_list_files()

static MJsonNode * js_ext_list_files ( const MJsonNode *  params)
static

Definition at line 4142 of file mjsonrpc.cxx.

4143{
4144 if (!params) {
4145 MJSO* doc = MJSO::I();
4146 doc->D("js_ext_list_files");
4147 doc->P("subdir", MJSON_STRING, "List files in experiment_directory/userfiles/subdir");
4148 doc->P("fileext", MJSON_STRING, "Filename extension");
4149 doc->R("status", MJSON_INT, "return status of midas library calls");
4150 doc->R("path", MJSON_STRING, "Search path");
4151 doc->R("subdirs[]", MJSON_STRING, "list of subdirectories");
4152 doc->R("files[].filename", MJSON_STRING, "script filename");
4153 doc->R("files[].description", MJSON_STRING, "script description");
4154 return doc;
4155 }
4156
4157 MJsonNode* error = NULL;
4158 std::string subdir = mjsonrpc_get_param(params, "subdir", &error)->GetString(); if (error) return error;
4159 std::string fileext = mjsonrpc_get_param(params, "fileext", &error)->GetString(); if (error) return error;
4160
4161 /*---- Not allowed to contain ../ - safety feature ----*/
4162 if (subdir.find("..") != std::string::npos) {
4163 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The subdir is not permitted"));
4164 }
4165
4166 /*---- ext must start with *. and some not allowed ext - safety feature */
4167 if (fileext.find("..") != std::string::npos) {
4168 /*
4169 fileext.find("/") != std::string::npos ||
4170 fileext.find("*.") != 0 ||
4171 fileext.find("*.html") != std::string::npos || fileext.find("*.HTML") != std::string::npos ||
4172 fileext.find("*.htm") != std::string::npos || fileext.find("*.HTM") != std::string::npos ||
4173 fileext.find("*.js") != std::string::npos || fileext.find("*.JS") != std::string::npos ||
4174 fileext.find("*.pl") != std::string::npos || fileext.find("*.PL") != std::string::npos ||
4175 fileext.find("*.cgi") != std::string::npos || fileext.find("*.CGI") != std::string::npos ||
4176 fileext.find("*.*") != std::string::npos
4177 ) {
4178 */
4179 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename extension is not permitted"));
4180 }
4181
4182 int status;
4183 HNDLE hDB;
4184
4186
4187 if (status != DB_SUCCESS) {
4188 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
4189 }
4190
4191 std::string path = cm_expand_env(cm_get_path().c_str());
4192 if (path[path.length()-1] != DIR_SEPARATOR) {
4193 path += DIR_SEPARATOR_STR;
4194 }
4195 path += "userfiles";
4196
4197 // Check if the userfiles folder exists
4198 if (access(path.c_str(), F_OK) != 0) {
4199 // Create the path if it doesn't exist
4200 if (mkdir(path.c_str(), 0777) != 0) {
4201 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4202 }
4203 }
4204
4205 if (subdir.length() > 0) {
4206 if (subdir[0] != DIR_SEPARATOR) {
4207 path += DIR_SEPARATOR_STR;
4208 }
4209 path += subdir;
4210 }
4211
4212 char* flist = NULL;
4213 MJsonNode* s = MJsonNode::MakeArray();
4214
4215 /*---- go over subdirectories ----*/
4216 int n = ss_dirlink_find(path.c_str(), "*", &flist);
4217
4218 for (int i=0 ; i<n ; i++) {
4219 if (flist[i*MAX_STRING_LENGTH] != '.') {
4220 //printf("subdir %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
4222 s->AddToArray(MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
4223 }
4224 }
4225
4226 MJsonNode* f = MJsonNode::MakeArray();
4227 time_t modtime = time(NULL);
4228 double fsize;
4229 /*---- go over files with extension fileext in path ----*/
4230 n = ss_file_find(path.c_str(), fileext.c_str(), &flist);
4231
4232 if (n == -1) {
4233 // path does not exist, return an error
4234 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Subdirectory does not exist, create it first."));
4235 }
4236
4237 for (int i=0 ; i<n ; i++) {
4238 //printf("file %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
4239 MJsonNode* o = MJsonNode::MakeObject();
4241 o->AddToObject("filename", MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
4242 /* description is msl specific, do we need it? */
4243 std::string full_name = path;
4244 if (full_name.back() != DIR_SEPARATOR)
4247 // o->AddToObject("description", MJsonNode::MakeString(full_name.c_str()));
4248 o->AddToObject("description", MJsonNode::MakeString("description"));
4249 modtime = ss_file_time(full_name.c_str());
4250 o->AddToObject("modtime", MJsonNode::MakeInt(modtime));
4251 fsize = ss_file_size(full_name.c_str());
4252 o->AddToObject("size", MJsonNode::MakeInt(fsize));
4253 f->AddToArray(o);
4254 }
4255
4256 free(flist);
4257 flist = NULL;
4258
4259 MJsonNode* r = MJsonNode::MakeObject();
4260 r->AddToObject("status", MJsonNode::MakeInt(SUCCESS));
4261 ss_repair_utf8(path);
4262 r->AddToObject("path", MJsonNode::MakeString(path.c_str()));
4263 r->AddToObject("subdirs", s);
4264 r->AddToObject("files", f);
4265
4266 return mjsonrpc_make_result(r);
4267
4268}
std::string cm_expand_env(const char *str)
Definition midas.cxx:7718
std::string cm_get_path()
Definition midas.cxx:1537
#define MAX_STRING_LENGTH
Definition msystem.h:113
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6878
time_t ss_file_time(const char *path)
Definition system.cxx:7016
double ss_file_size(const char *path)
Definition system.cxx:6978
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6719
DWORD n[4]
Definition mana.cxx:247
#define DIR_SEPARATOR
Definition midas.h:193
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_read_file()

static MJsonNode * js_ext_read_file ( const MJsonNode *  params)
static

Definition at line 4346 of file mjsonrpc.cxx.

4347{
4348 if (!params) {
4349 MJSO* doc = MJSO::I();
4350 doc->D("js_ext_read_script");
4351 doc->P("filename", MJSON_STRING, "File name, read from experiment_directory/userfiles/filename");
4352 doc->R("content", MJSON_STRING, "ASCII file content");
4353 doc->R("status", MJSON_INT, "return status of midas library calls");
4354 doc->R("error", MJSON_STRING, "error text");
4355 return doc;
4356 }
4357
4358 MJsonNode* error = NULL;
4359 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString(); if (error) return error;
4360
4361 /*---- filename should not contain the following - safety feature */
4362 if (filename.find("..") != std::string::npos ||
4363 filename.find("*") != std::string::npos) {
4364 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4365 }
4366
4367 int status;
4368 HNDLE hDB;
4369
4371
4372 if (status != DB_SUCCESS) {
4373 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4374 }
4375
4376 std::string path = cm_expand_env(cm_get_path().c_str());
4377 if (path[path.length()-1] != DIR_SEPARATOR) {
4378 path += DIR_SEPARATOR_STR;
4379 }
4380 path += "userfiles";
4381
4382 // Check if the userfiles folder exists
4383 if (access(path.c_str(), F_OK) != 0) {
4384 // Create the path if it doesn't exist
4385 if (mkdir(path.c_str(), 0777) != 0) {
4386 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4387 }
4388 }
4389
4390 path += DIR_SEPARATOR_STR;
4391 path += filename;
4392
4393 FILE* fp = fopen(path.c_str(), "r");
4394 if (!fp) {
4396 char errstr[256];
4397 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4398 ss_repair_utf8(errstr);
4399 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4400 }
4401
4402 fseek(fp, 0, SEEK_END);
4403 size_t file_size = ftell(fp);
4404 rewind(fp);
4405
4406 char* buffer = new char[file_size+1];
4407 fread(buffer, file_size, 1, fp);
4408 // Maybe not needed here
4409 buffer[file_size] = '\0';
4410 fclose(fp);
4411
4412 std::string content = buffer;
4413 delete[] buffer;
4414 buffer = NULL;
4415
4417 std::string errstr = "no error";
4418
4419 return mjsonrpc_make_result("content", MJsonNode::MakeString(content.c_str()), "status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr.c_str()));
4420}
#define CM_SUCCESS
Definition midas.h:582
#define SS_FILE_ERROR
Definition midas.h:669
char content[600000]
Definition melog.cxx:90
static FILE * fp
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_save_file()

static MJsonNode * js_ext_save_file ( const MJsonNode *  params)
static

Definition at line 4270 of file mjsonrpc.cxx.

4271{
4272 if (!params) {
4273 MJSO* doc = MJSO::I();
4274 doc->D("js_ext_save_file");
4275 doc->P("filename", MJSON_STRING, "File name, save in experiment_directory/userfiles/filename");
4276 doc->P("script", MJSON_STRING, "ASCII content");
4277 doc->R("status", MJSON_INT, "return status of midas library calls");
4278 doc->R("error", MJSON_STRING, "error text");
4279 return doc;
4280 }
4281
4282 /* Need to make sure that content cannot be abused (e.g. not Javascript code), how?? */
4283
4284 MJsonNode* error = NULL;
4285 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString(); if (error) return error;
4286 std::string script = mjsonrpc_get_param(params, "script", &error)->GetString(); if (error) return error;
4287
4288 /*---- filename should not contain the following - safety feature */
4289 if (filename.find("..") != std::string::npos ) {
4290 /*
4291 filename.find("*") != std::string::npos ||
4292 filename.find(".html") != std::string::npos || filename.find(".HTML") != std::string::npos ||
4293 filename.find(".htm") != std::string::npos || filename.find(".HTM") != std::string::npos ||
4294 filename.find(".js") != std::string::npos || filename.find(".JS") != std::string::npos ||
4295 filename.find(".pl") != std::string::npos || filename.find(".PL") != std::string::npos ||
4296 filename.find(".cgi") != std::string::npos || filename.find(".CGI") != std::string::npos
4297 ) {
4298 */
4299 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4300 }
4301
4302 int status;
4303 HNDLE hDB;
4304
4306
4307 if (status != DB_SUCCESS) {
4308 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4309 }
4310
4311 std::string path = cm_expand_env(cm_get_path().c_str());
4312 path += "userfiles";
4313
4314 // Check if the userfiles folder exists
4315 if (access(path.c_str(), F_OK) != 0) {
4316 // Create the path if it doesn't exist
4317 if (mkdir(path.c_str(), 0777) != 0) {
4318 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4319 }
4320 }
4321
4322 path += DIR_SEPARATOR_STR;
4323 path += filename;
4324
4325 FILE* fp = fopen(path.c_str(), "w");
4326 if (!fp) {
4328 char errstr[256];
4329 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4330 ss_repair_utf8(errstr);
4331 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4332 }
4333
4334 fwrite(script.c_str(), script.length(), 1, fp);
4335 //fprintf(fp, "\n");
4336 fclose(fp);
4337 fp = NULL;
4338
4340 std::string errstr = "no error";
4341
4342 //ss_repair_utf8(errstr); redundant!
4343 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr.c_str()));
4344}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_get_timezone()

static MJsonNode * js_get_timezone ( const MJsonNode *  params)
static

Definition at line 4602 of file mjsonrpc.cxx.

4603{
4604 if (!params) {
4605 MJSO *doc = MJSO::I();
4606 doc->D("get current server timezone offset in seconds");
4607 doc->P(NULL, 0, "there are no input parameters");
4608 doc->R(NULL, MJSON_INT, "offset in seconds");
4609 return doc;
4610 }
4611
4612 ss_tzset(); // required for localtime_r()
4613 time_t rawtime = time(NULL);
4614 struct tm gmt_tms;
4617 struct tm tms;
4619 time_t offset = rawtime - gmt + (tms.tm_isdst ? 3600 : 0);
4620
4621 return mjsonrpc_make_result(MJsonNode::MakeNumber(offset));
4622}
static int offset
Definition mgd.cxx:1500
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_exit()

static void js_hs_exit ( )
static

Definition at line 1748 of file mjsonrpc.cxx.

1749{
1750 for (auto& e : gHistoryChannels) {
1751 //printf("history channel \"%s\" mh %p\n", e.first.c_str(), e.second);
1752 delete e.second;
1753 }
1754 gHistoryChannels.clear();
1755}
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_active_events()

static MJsonNode * js_hs_get_active_events ( const MJsonNode *  params)
static

Definition at line 1670 of file mjsonrpc.cxx.

1671{
1672 if (!params) {
1673 MJSO* doc = MJSO::I();
1674 doc->D("get list of active history events using hs_read_event_list()");
1675 doc->R("status", MJSON_INT, "return status of hs_read_event_list()");
1676 doc->R("events[]", MJSON_STRING, "array of history event names");
1677 return doc;
1678 }
1679
1681
1683
1684 MJsonNode* events = MJsonNode::MakeArray();
1685
1686 for (unsigned i=0; i<list.size(); i++) {
1688 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1689 }
1690
1691 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1692}
int hs_read_event_list(std::vector< std::string > *pevents)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_channels()

static MJsonNode * js_hs_get_channels ( const MJsonNode *  params)
static

Definition at line 1757 of file mjsonrpc.cxx.

1758{
1759 if (!params) {
1760 MJSO* doc = MJSO::I();
1761 doc->D("get list of history channels in /Logger/History");
1762 doc->R("status", MJSON_INT, "return success or failure status");
1763 doc->R("default_channel", MJSON_STRING, "name of the default logger history channel");
1764 doc->R("channels[]", MJSON_STRING, "all logger history channel names");
1765 doc->R("active_channels[]", MJSON_STRING, "active logger history channel names");
1766 return doc;
1767 }
1768
1769 MJsonNode* channels = MJsonNode::MakeArray();
1770 MJsonNode* active_channels = MJsonNode::MakeArray();
1771
1772 HNDLE hDB;
1774
1775 // get history channel name selected by user in ODB
1776
1777 //std::string selected_channel;
1778 //db_get_value_string(hDB, 0, "/History/LoggerHistoryChannel", 0, &selected_channel, TRUE);
1779
1780 int status;
1782
1783 status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1784 if (status == DB_SUCCESS) {
1785 for (int ichan=0; ; ichan++) {
1786 HNDLE hKey;
1788 if (status == DB_NO_MORE_SUBKEYS) {
1790 break;
1791 }
1792 if (status != DB_SUCCESS)
1793 break;
1794
1795 KEY key;
1796
1798
1799 if (status == DB_SUCCESS) {
1801 channels->AddToArray(MJsonNode::MakeString(key.name));
1802
1803 INT active = 0;
1804 INT size = sizeof(active);
1805 status = db_get_value(hDB, hKey, "Active", &active, &size, TID_BOOL, FALSE);
1806 if (status == DB_SUCCESS) {
1807 if (active) {
1808 active_channels->AddToArray(MJsonNode::MakeString(key.name));
1809 }
1810 }
1811 }
1812 }
1813 }
1814
1815 std::string default_channel;
1816
1817 HNDLE hKey;
1819 if (status == DB_SUCCESS) {
1820 KEY key;
1822 if (status == DB_SUCCESS) {
1824 }
1825 }
1826
1827 return mjsonrpc_make_result("status", MJsonNode::MakeInt(1),
1828 //"selected_channel", MJsonNode::MakeString(selected_channel.c_str()),
1829 "default_channel", MJsonNode::MakeString(default_channel.c_str()),
1830 "active_channels", active_channels,
1831 "channels", channels);
1832}
#define FALSE
Definition cfortran.h:309
#define DB_NO_MORE_SUBKEYS
Definition midas.h:646
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
int INT
Definition midas.h:129
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_events()

static MJsonNode * js_hs_get_events ( const MJsonNode *  params)
static

Definition at line 1834 of file mjsonrpc.cxx.

1835{
1836 if (!params) {
1837 MJSO* doc = MJSO::I();
1838 doc->D("get list of history events that existed at give time using hs_get_events()");
1839 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1840 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1841 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1842 doc->R("channel", MJSON_STRING, "logger history channel name");
1843 doc->R("events[]", MJSON_STRING, "array of history event names");
1844 return doc;
1845 }
1846
1847 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1848 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1849
1851
1852 MJsonNode* events = MJsonNode::MakeArray();
1853
1854 if (!mh) {
1855 int status = HS_FILE_ERROR;
1856 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1857 }
1858
1859 if (time == 0) {
1860 time = ::time(NULL);
1861 }
1862
1864
1865 int status = mh->hs_get_events(time, &list);
1866
1867 for (unsigned i=0; i<list.size(); i++) {
1869 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1870 }
1871
1872 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "events", events);
1873}
virtual int hs_get_events(time_t time_from, std::vector< std::string > *pevents)=0
get list of events that exist(ed) at given time and later (value 0 means "return all events from begi...
char name[NAME_LENGTH]
Definition history.h:111
#define HS_FILE_ERROR
Definition midas.h:728
INT channel
static MidasHistoryInterface * GetHistory(const char *name)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_last_written()

static MJsonNode * js_hs_get_last_written ( const MJsonNode *  params)
static

Definition at line 1978 of file mjsonrpc.cxx.

1979{
1980 if (!params) {
1981 MJSO* doc = MJSO::I();
1982 doc->D("get list of history tags for given history events that existed at give time using hs_get_last_written()");
1983 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1984 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1985 doc->P("events[]", MJSON_STRING, "array of history event names");
1986 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
1987 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
1988 doc->R("status", MJSON_INT, "return status");
1989 doc->R("channel", MJSON_STRING, "logger history channel name");
1990 doc->R("last_written[]", MJSON_NUMBER, "array of last-written times for each history event");
1991 return doc;
1992 }
1993
1994 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1995 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1996
1997 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
1998 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
1999 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2000
2002
2003 MJsonNode* lw = MJsonNode::MakeArray();
2004
2005 if (!mh) {
2006 int status = HS_FILE_ERROR;
2007 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "last_written", lw);
2008 }
2009
2010 unsigned num_var = events_array->size();
2011
2012 if (tags_array->size() != num_var) {
2013 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2014 }
2015
2016 if (index_array->size() != num_var) {
2017 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2018 }
2019
2020 std::vector<std::string> event_names(num_var);
2021 std::vector<std::string> tag_names(num_var);
2022 // const char** event_name = new const char*[num_var];
2023 // const char** tag_name = new const char*[num_var];
2024 int* var_index = new int[num_var];
2025 time_t* last_written = new time_t[num_var];
2026
2027 for (unsigned i=0; i<num_var; i++) {
2028 //event_name[i] = (*events_array)[i]->GetString().c_str();
2029 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2030 event_names[i] = (*events_array)[i]->GetString();
2031 tag_names[i] = (*tags_array)[i]->GetString();
2032 var_index[i] = (*index_array)[i]->GetInt();
2033 }
2034
2035 if (/* DISABLES CODE */ (0)) {
2036 printf("time %f, num_vars %d:\n", time, num_var);
2037 for (unsigned i=0; i<num_var; i++) {
2038 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2039 }
2040 }
2041
2042 if (time == 0) {
2043 time = ::time(NULL);
2044 }
2045
2046
2047 const char** event_name = new const char*[num_var];
2048 const char** tag_name = new const char*[num_var];
2049 for (unsigned i=0; i<num_var; i++) {
2050 event_name[i] = event_names[i].c_str();
2051 tag_name[i] = tag_names[i].c_str();
2052 }
2053 int status = mh->hs_get_last_written(time, num_var, event_name, tag_name, var_index, last_written);
2054
2055 for (unsigned i=0; i<num_var; i++) {
2056 if (/* DISABLES CODE */ (0)) {
2057 printf("%d: last_written %d\n", i, (int)last_written[i]);
2058 }
2059 lw->AddToArray(MJsonNode::MakeNumber(last_written[i]));
2060 }
2061
2062 delete[] event_name;
2063 delete[] tag_name;
2064 delete[] var_index;
2065 delete[] last_written;
2066
2067 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "last_written", lw);
2068}
virtual int hs_get_last_written(time_t start_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], time_t last_written[])=0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_tags()

static MJsonNode * js_hs_get_tags ( const MJsonNode *  params)
static

Definition at line 1900 of file mjsonrpc.cxx.

1901{
1902 if (!params) {
1903 MJSO* doc = MJSO::I();
1904 doc->D("get list of history tags for given history events that existed at give time using hs_get_tags()");
1905 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1906 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1907 doc->P("events[]?", MJSON_STRING, "array of history event names, default is get all events using hs_get_events()");
1908 doc->R("status", MJSON_INT, "return status");
1909 doc->R("channel", MJSON_STRING, "logger history channel name");
1910 doc->R("events[].name", MJSON_STRING, "array of history event names for each history event");
1911 doc->R("events[].status", MJSON_INT, "array of status ohistory tags for each history event");
1912 doc->R("events[].tags[]", MJSON_STRING, "array of history tags for each history event");
1913 doc->R("events[].tags[].name", MJSON_STRING, "history tag name");
1914 doc->R("events[].tags[].type", MJSON_INT, "history tag midas data type");
1915 doc->R("events[].tags[].n_data?", MJSON_INT, "history tag number of array elements, omitted if 1");
1916 return doc;
1917 }
1918
1919 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1920 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1921 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
1922
1923 if (time == 0) {
1924 time = ::time(NULL);
1925 }
1926
1928
1929 MJsonNode* events = MJsonNode::MakeArray();
1930
1931 if (!mh) {
1932 int status = HS_FILE_ERROR;
1933 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1934 }
1935
1936 std::vector<std::string> event_names;
1937
1938 if (events_array && events_array->size() > 0) {
1939 for (unsigned i=0; i<events_array->size(); i++) {
1940 event_names.push_back((*events_array)[i]->GetString());
1941 }
1942 }
1943
1944 if (event_names.size() < 1) {
1945 int status = mh->hs_get_events(time, &event_names);
1946 if (status != HS_SUCCESS) {
1947 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1948 }
1949 }
1950
1951 for (unsigned i=0; i<event_names.size(); i++) {
1952 MJsonNode* o = MJsonNode::MakeObject();
1953 const char* event_name = event_names[i].c_str();
1954 std::vector<TAG> tags;
1955 int status = mh->hs_get_tags(event_name, time, &tags);
1956 //ss_repair_utf8(event_name); redundant!
1957 o->AddToObject("name", MJsonNode::MakeString(event_name));
1958 o->AddToObject("status", MJsonNode::MakeInt(status));
1959 MJsonNode *ta = MJsonNode::MakeArray();
1960 for (unsigned j=0; j<tags.size(); j++) {
1961 MJsonNode* to = MJsonNode::MakeObject();
1962 ss_repair_utf8(tags[j].name);
1963 to->AddToObject("name", MJsonNode::MakeString(tags[j].name));
1964 to->AddToObject("type", MJsonNode::MakeInt(tags[j].type));
1965 if (tags[j].n_data != 1) {
1966 to->AddToObject("n_data", MJsonNode::MakeInt(tags[j].n_data));
1967 }
1968 ta->AddToArray(to);
1969 }
1970 o->AddToObject("tags", ta);
1971 events->AddToArray(o);
1972 }
1973
1974 int status = HS_SUCCESS;
1975 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "events", events);
1976}
virtual int hs_get_tags(const char *event_name, time_t time_from, std::vector< TAG > *ptags)=0
get list of history variables for given event (use event names returned by hs_get_events()) that exis...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_image_retrieve()

static MJsonNode * js_hs_image_retrieve ( const MJsonNode *  params)
static

Definition at line 2948 of file mjsonrpc.cxx.

2948 {
2949 if (!params) {
2950 MJSO *doc = MJSO::I();
2951 doc->D("Get a list of history image files");
2952 doc->P("image?", MJSON_STRING, "image name as defined under /History/Images/<image>");
2953 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2954 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2955 doc->R("time[]", MJSON_ARRAYBUFFER, "array of time stamps in seconds");
2956 doc->R("filename[]", MJSON_ARRAYBUFFER, "array of file names");
2957 return doc;
2958 }
2959
2960 MJsonNode* error = NULL;
2961
2962 std::string image = mjsonrpc_get_param(params, "image", NULL)->GetString();
2963 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2964 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2965
2966 std::vector<time_t>vtime{};
2967 std::vector<std::string>vfilename{};
2968
2969 int status = hs_image_retrieve(image, start_time, end_time, vtime, vfilename);
2970 int count = 10;
2971 MJsonNode *tj = MJsonNode::MakeArray();
2972 MJsonNode *fj = MJsonNode::MakeArray();
2973
2974 for (int i=0 ; i<(int)vtime.size() ; i++) {
2975 tj->AddToArray(MJsonNode::MakeInt(vtime[i]));
2977 fj->AddToArray(MJsonNode::MakeString(vfilename[i].c_str()));
2978 }
2979 MJsonNode* data = MJsonNode::MakeObject();
2980 data->AddToObject("count", MJsonNode::MakeInt(count));
2981 data->AddToObject("time", tj);
2982 data->AddToObject("filename", fj);
2983
2984 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2985}
int hs_image_retrieve(std::string image_name, time_t start_time, time_t stop_time, std::vector< time_t > &vtime, std::vector< std::string > &vfilename)
void * data
Definition mana.cxx:268
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read()

static MJsonNode * js_hs_read ( const MJsonNode *  params)
static

Definition at line 2107 of file mjsonrpc.cxx.

2108{
2109 if (!params) {
2110 MJSO* doc = MJSO::I();
2111 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2112 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2113 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2114 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2115 doc->P("events[]", MJSON_STRING, "array of history event names");
2116 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2117 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2118 doc->R("status", MJSON_INT, "return status");
2119 doc->R("channel", MJSON_STRING, "logger history channel name");
2120 doc->R("data[]", MJSON_ARRAY, "array of history data");
2121 doc->R("data[].status", MJSON_INT, "status for each event");
2122 doc->R("data[].count", MJSON_INT, "number of data for each event");
2123 doc->R("data[].time[]", MJSON_NUMBER, "time data");
2124 doc->R("data[].value[]", MJSON_NUMBER, "value data");
2125 return doc;
2126 }
2127
2128 MJsonNode* error = NULL;
2129
2130 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2131 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2132 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2133
2134 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2135 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2136 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2137
2139
2140 MJsonNode* data = MJsonNode::MakeArray();
2141
2142 if (!mh) {
2143 int status = HS_FILE_ERROR;
2144 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2145 }
2146
2147 unsigned num_var = events_array->size();
2148
2149 if (tags_array->size() != num_var) {
2150 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2151 }
2152
2153 if (index_array->size() != num_var) {
2154 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2155 }
2156
2157 std::vector<std::string> event_names(num_var);
2158 std::vector<std::string> tag_names(num_var);
2159 int* var_index = new int[num_var];
2162 int* hs_status = new int[num_var];
2163
2164 for (unsigned i=0; i<num_var; i++) {
2165 //event_name[i] = (*events_array)[i]->GetString().c_str();
2166 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2167 event_names[i] = (*events_array)[i]->GetString();
2168 tag_names[i] = (*tags_array)[i]->GetString();
2169 var_index[i] = (*index_array)[i]->GetInt();
2170 jbuf[i] = new JsonHistoryBuffer();
2171 buf[i] = jbuf[i];
2172 hs_status[i] = 0;
2173 }
2174
2175 if (/* DISABLES CODE */ (0)) {
2176 printf("time %f %f, num_vars %d:\n", start_time, end_time, num_var);
2177 for (unsigned i=0; i<num_var; i++) {
2178 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2179 }
2180 }
2181
2182 const char** event_name = new const char*[num_var];
2183 const char** tag_name = new const char*[num_var];
2184 for (unsigned i=0; i<num_var; i++) {
2185 event_name[i] = event_names[i].c_str();
2186 tag_name[i] = tag_names[i].c_str();
2187 }
2188
2189 int status = mh->hs_read_buffer(start_time, end_time, num_var, event_name, tag_name, var_index, buf, hs_status);
2190
2191 for (unsigned i=0; i<num_var; i++) {
2192 jbuf[i]->Finish();
2193
2194 MJsonNode* obj = MJsonNode::MakeObject();
2195 obj->AddToObject("status", MJsonNode::MakeInt(hs_status[i]));
2196 obj->AddToObject("count", MJsonNode::MakeInt(jbuf[i]->fCount));
2197 obj->AddToObject("time", MJsonNode::MakeJSON(jbuf[i]->fTimeJson.c_str()));
2198 obj->AddToObject("value", MJsonNode::MakeJSON(jbuf[i]->fValueJson.c_str()));
2199 data->AddToArray(obj);
2200
2201 delete jbuf[i];
2202 jbuf[i] = NULL;
2203 buf[i] = NULL;
2204 }
2205
2206 delete[] event_name;
2207 delete[] tag_name;
2208 delete[] var_index;
2209 delete[] buf;
2210 delete[] jbuf;
2211 delete[] hs_status;
2212
2213 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "data", data);
2214}
virtual int hs_read_buffer(time_t start_time, time_t end_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], MidasHistoryBufferInterface *buffer[], int status[])=0
returns HS_SUCCESS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_arraybuffer()

static MJsonNode * js_hs_read_arraybuffer ( const MJsonNode *  params)
static

Definition at line 2450 of file mjsonrpc.cxx.

2451{
2452 if (!params) {
2453 MJSO* doc = MJSO::I();
2454 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2455 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2456 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2457 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2458 doc->P("events[]", MJSON_STRING, "array of history event names");
2459 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2460 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2461 doc->R("binary data", MJSON_ARRAYBUFFER, "binary data, see documentation");
2462 return doc;
2463 }
2464
2465 MJsonNode* error = NULL;
2466
2467 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2468 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2469 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2470
2471 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2472 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2473 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2474
2476
2477 if (!mh) {
2478 int status = HS_FILE_ERROR;
2479 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
2480 }
2481
2482 size_t num_var = events_array->size();
2483
2484 if (tags_array->size() != num_var) {
2485 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2486 }
2487
2488 if (index_array->size() != num_var) {
2489 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2490 }
2491
2492 std::vector<std::string> event_names(num_var);
2493 std::vector<std::string> tag_names(num_var);
2494 int* var_index = new int[num_var];
2497 int* hs_status = new int[num_var];
2498
2499 for (size_t i=0; i<num_var; i++) {
2500 //event_name[i] = (*events_array)[i]->GetString().c_str();
2501 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2502 event_names[i] = (*events_array)[i]->GetString();
2503 tag_names[i] = (*tags_array)[i]->GetString();
2504 var_index[i] = (*index_array)[i]->GetInt();
2505 jbuf[i] = new BinaryHistoryBuffer();
2506 buf[i] = jbuf[i];
2507 hs_status[i] = 0;
2508 }
2509
2510 if (/* DISABLES CODE */ (0)) {
2511 printf("time %f %f, num_vars %d:\n", start_time, end_time, int(num_var));
2512 for (size_t i=0; i<num_var; i++) {
2513 printf("%d: [%s] [%s] [%d]\n", int(i), event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2514 }
2515 }
2516
2517 const char** event_name = new const char*[num_var];
2518 const char** tag_name = new const char*[num_var];
2519 for (unsigned i=0; i<num_var; i++) {
2520 event_name[i] = event_names[i].c_str();
2521 tag_name[i] = tag_names[i].c_str();
2522 }
2523
2524 int status = mh->hs_read_buffer(start_time, end_time, num_var, event_name, tag_name, var_index, buf, hs_status);
2525
2526 size_t num_values = 0;
2527
2528 for (unsigned i=0; i<num_var; i++) {
2529 jbuf[i]->Finish();
2530 num_values += jbuf[i]->fValues.size();
2531 }
2532
2533 // NB: beware of 32-bit integer overflow. all values are now 64-bit size_t, overflow should not happen.
2534 size_t p0_size = sizeof(double)*(2+2*num_var+2*num_values);
2535
2536 size_t size_limit = 1000*1024*1024;
2537
2538 if (p0_size > size_limit) {
2539 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Refusing to return %zu bytes of history data, limit is %zu bytes\n", p0_size, size_limit);
2540
2541 for (size_t i=0; i<num_var; i++) {
2542 delete jbuf[i];
2543 jbuf[i] = NULL;
2544 buf[i] = NULL;
2545 }
2546
2547 delete[] event_name;
2548 delete[] tag_name;
2549 delete[] var_index;
2550 delete[] buf;
2551 delete[] jbuf;
2552 delete[] hs_status;
2553
2554 return mjsonrpc_make_error(-32603, "Internal error", "Too much history data");
2555 }
2556
2557 double* p0 = (double*)malloc(p0_size);
2558
2559 if (p0 == NULL) {
2560 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Cannot allocate return buffer %d bytes\n", int(p0_size));
2561
2562 for (size_t i=0; i<num_var; i++) {
2563 delete jbuf[i];
2564 jbuf[i] = NULL;
2565 buf[i] = NULL;
2566 }
2567
2568 delete[] event_name;
2569 delete[] tag_name;
2570 delete[] var_index;
2571 delete[] buf;
2572 delete[] jbuf;
2573 delete[] hs_status;
2574
2575 return mjsonrpc_make_error(-32603, "Internal error", "Cannot allocate buffer, too much data");
2576 }
2577
2578 double *pptr = p0;
2579
2580 //
2581 // Binary data format:
2582 //
2583 // - hs_read() status
2584 // - num_var
2585 // - hs_status[0..num_var-1]
2586 // - num_values[0..num_var-1]
2587 // - data for var0:
2588 // - t[0][0], v[0][0] ... t[0][num_values[0]-1], v[0][num_values[0]-1]
2589 // - data for var1:
2590 // - t[1][0], v[1][0] ... t[1][num_values[1]-1], v[1][num_values[1]-1]
2591 // ...
2592 // - data for last variable:
2593 // - t[num_var-1][0], v[num_var-1][0] ... t[num_var-1][num_values[num_var-1]-1], v[num_var-1][num_values[num_var-1]-1]
2594 //
2595
2596 *pptr++ = status;
2597 *pptr++ = num_var;
2598
2599 for (size_t i=0; i<num_var; i++) {
2600 *pptr++ = hs_status[i];
2601 }
2602
2603 for (size_t i=0; i<num_var; i++) {
2604 *pptr++ = jbuf[i]->fValues.size();
2605 }
2606
2607 for (size_t i=0; i<num_var; i++) {
2608 size_t nv = jbuf[i]->fValues.size();
2609 for (size_t j=0; j<nv; j++) {
2610 *pptr++ = jbuf[i]->fTimes[j];
2611 *pptr++ = jbuf[i]->fValues[j];
2612 }
2613
2614 delete jbuf[i];
2615 jbuf[i] = NULL;
2616 buf[i] = NULL;
2617 }
2618
2619 //printf("p0_size %d, %d/%d\n", (int)p0_size, (int)(pptr-p0), (int)((pptr-p0)*sizeof(double)));
2620
2621 assert(p0_size == ((pptr-p0)*sizeof(double)));
2622
2623 delete[] event_name;
2624 delete[] tag_name;
2625 delete[] var_index;
2626 delete[] buf;
2627 delete[] jbuf;
2628 delete[] hs_status;
2629
2630 MJsonNode* result = MJsonNode::MakeArrayBuffer((char*)p0, p0_size);
2631
2632 return result;
2633}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_binned()

static MJsonNode * js_hs_read_binned ( const MJsonNode *  params)
static

Definition at line 2216 of file mjsonrpc.cxx.

2217{
2218 if (!params) {
2219 MJSO* doc = MJSO::I();
2220 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2221 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2222 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2223 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2224 doc->P("num_bins", MJSON_INT, "number of time bins");
2225 doc->P("events[]", MJSON_STRING, "array of history event names");
2226 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2227 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2228 doc->R("status", MJSON_INT, "return status");
2229 doc->R("channel", MJSON_STRING, "logger history channel name");
2230 doc->R("data[]", MJSON_ARRAY, "array of history data");
2231 doc->R("data[].status", MJSON_INT, "status for each event");
2232 doc->R("data[].num_entries", MJSON_INT, "number of data points for each event");
2233 doc->R("data[].count[]", MJSON_INT, "number of data points for each bin");
2234 doc->R("data[].mean[]", MJSON_NUMBER, "mean for each bin");
2235 doc->R("data[].rms[]", MJSON_NUMBER, "rms for each bin");
2236 doc->R("data[].min[]", MJSON_NUMBER, "minimum value for each bin");
2237 doc->R("data[].max[]", MJSON_NUMBER, "maximum value for each bin");
2238 doc->R("data[].bins_first_time[]", MJSON_NUMBER, "first data point in each bin");
2239 doc->R("data[].bins_first_value[]", MJSON_NUMBER, "first data point in each bin");
2240 doc->R("data[].bins_last_time[]", MJSON_NUMBER, "last data point in each bin");
2241 doc->R("data[].bins_last_value[]", MJSON_NUMBER, "last data point in each bin");
2242 doc->R("data[].last_time", MJSON_NUMBER, "time of last data entry");
2243 doc->R("data[].last_value", MJSON_NUMBER, "value of last data entry");
2244 return doc;
2245 }
2246
2247 MJsonNode* error = NULL;
2248
2249 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2250 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2251 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2252 int num_bins = mjsonrpc_get_param(params, "num_bins", &error)->GetInt(); if (error) return error;
2253
2254 if (num_bins < 1) {
2255 return mjsonrpc_make_error(-32602, "Invalid params", "Value of num_bins should be 1 or more");
2256 }
2257
2258 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2259 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2260 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2261
2263
2264 MJsonNode* data = MJsonNode::MakeArray();
2265
2266 if (!mh) {
2267 int status = HS_FILE_ERROR;
2268 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2269 }
2270
2271 unsigned num_var = events_array->size();
2272
2273 if (num_var < 1) {
2274 return mjsonrpc_make_error(-32602, "Invalid params", "Array of events should have 1 or more elements");
2275 }
2276
2277 if (tags_array->size() != num_var) {
2278 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2279 }
2280
2281 if (index_array->size() != num_var) {
2282 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2283 }
2284
2285 std::vector<std::string> event_names(num_var);
2286 std::vector<std::string> tag_names(num_var);
2287 //const char** event_name = new const char*[num_var];
2288 //const char** tag_name = new const char*[num_var];
2289 int* var_index = new int[num_var];
2290
2291 int* num_entries = new int[num_var];
2293 double* last_value = new double[num_var];
2294 int* hs_status = new int[num_var];
2295
2296 int** count_bins = new int*[num_var];
2297 double** mean_bins = new double*[num_var];
2298 double** rms_bins = new double*[num_var];
2299 double** min_bins = new double*[num_var];
2300 double** max_bins = new double*[num_var];
2301
2304
2305 double** bins_first_value = new double*[num_var];
2306 double** bins_last_value = new double*[num_var];
2307
2308 for (unsigned i=0; i<num_var; i++) {
2309 //event_name[i] = (*events_array)[i]->GetString().c_str();
2310 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2311 event_names[i] = (*events_array)[i]->GetString();
2312 tag_names[i] = (*tags_array)[i]->GetString();
2313 var_index[i] = (*index_array)[i]->GetInt();
2314 num_entries[i] = 0;
2315 last_time[i] = 0;
2316 last_value[i] = 0;
2317 hs_status[i] = 0;
2318 count_bins[i] = new int[num_bins];
2319 mean_bins[i] = new double[num_bins];
2320 rms_bins[i] = new double[num_bins];
2321 min_bins[i] = new double[num_bins];
2322 max_bins[i] = new double[num_bins];
2323
2326
2327 bins_first_value[i] = new double[num_bins];
2328 bins_last_value[i] = new double[num_bins];
2329 }
2330
2331 if (/* DISABLES CODE */ (0)) {
2332 printf("time %f %f, num_vars %d:\n", start_time, end_time, num_var);
2333 for (unsigned i=0; i<num_var; i++) {
2334 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2335 }
2336 }
2337
2338 const char** event_name = new const char*[num_var];
2339 const char** tag_name = new const char*[num_var];
2340 for (unsigned i=0; i<num_var; i++) {
2341 event_name[i] = event_names[i].c_str();
2342 tag_name[i] = tag_names[i].c_str();
2343 }
2344
2345 int status = mh->hs_read_binned(start_time, end_time, num_bins, num_var, event_name, tag_name, var_index, num_entries, count_bins, mean_bins, rms_bins, min_bins, max_bins, bins_first_time, bins_first_value, bins_last_time, bins_last_value, last_time, last_value, hs_status);
2346
2347 for (unsigned i=0; i<num_var; i++) {
2348 MJsonNode* obj = MJsonNode::MakeObject();
2349 obj->AddToObject("status", MJsonNode::MakeInt(hs_status[i]));
2350 obj->AddToObject("num_entries", MJsonNode::MakeInt(num_entries[i]));
2351
2352 MJsonNode* a1 = MJsonNode::MakeArray();
2353 MJsonNode* a2 = MJsonNode::MakeArray();
2354 MJsonNode* a3 = MJsonNode::MakeArray();
2355 MJsonNode* a4 = MJsonNode::MakeArray();
2356 MJsonNode* a5 = MJsonNode::MakeArray();
2357
2358 MJsonNode* b1 = MJsonNode::MakeArray();
2359 MJsonNode* b2 = MJsonNode::MakeArray();
2360 MJsonNode* b3 = MJsonNode::MakeArray();
2361 MJsonNode* b4 = MJsonNode::MakeArray();
2362
2363 for (int j=0; j<num_bins; j++) {
2364 a1->AddToArray(MJsonNode::MakeInt(count_bins[i][j]));
2365 a2->AddToArray(MJsonNode::MakeNumber(mean_bins[i][j]));
2366 a3->AddToArray(MJsonNode::MakeNumber(rms_bins[i][j]));
2367 a4->AddToArray(MJsonNode::MakeNumber(min_bins[i][j]));
2368 a5->AddToArray(MJsonNode::MakeNumber(max_bins[i][j]));
2369
2370 b1->AddToArray(MJsonNode::MakeNumber(bins_first_time[i][j]));
2371 b2->AddToArray(MJsonNode::MakeNumber(bins_first_value[i][j]));
2372 b3->AddToArray(MJsonNode::MakeNumber(bins_last_time[i][j]));
2373 b4->AddToArray(MJsonNode::MakeNumber(bins_last_value[i][j]));
2374 }
2375
2376 obj->AddToObject("count", a1);
2377 obj->AddToObject("mean", a2);
2378 obj->AddToObject("rms", a3);
2379 obj->AddToObject("min", a4);
2380 obj->AddToObject("max", a5);
2381 obj->AddToObject("bins_first_time", b1);
2382 obj->AddToObject("bins_first_value", b2);
2383 obj->AddToObject("bins_last_time", b3);
2384 obj->AddToObject("bins_last_value", b4);
2385 obj->AddToObject("last_time", MJsonNode::MakeNumber(last_time[i]));
2386 obj->AddToObject("last_value", MJsonNode::MakeNumber(last_value[i]));
2387 data->AddToArray(obj);
2388
2389 delete count_bins[i];
2390 delete mean_bins[i];
2391 delete rms_bins[i];
2392 delete min_bins[i];
2393 delete max_bins[i];
2394
2395 delete bins_first_time[i];
2396 delete bins_first_value[i];
2397 delete bins_last_time[i];
2398 delete bins_last_value[i];
2399 }
2400
2401 delete[] count_bins;
2402 delete[] mean_bins;
2403 delete[] rms_bins;
2404 delete[] min_bins;
2405 delete[] max_bins;
2406
2407 delete[] bins_first_time;
2408 delete[] bins_first_value;
2409 delete[] bins_last_time;
2410 delete[] bins_last_value;
2411
2412 delete[] event_name;
2413 delete[] tag_name;
2414 delete[] var_index;
2415
2416 delete[] num_entries;
2417 delete[] last_time;
2418 delete[] last_value;
2419 delete[] hs_status;
2420
2421 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "data", data);
2422}
virtual int hs_read_binned(time_t start_time, time_t end_time, int num_bins, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], int num_entries[], int *count_bins[], double *mean_bins[], double *rms_bins[], double *min_bins[], double *max_bins[], time_t *bins_first_time[], double *bins_first_value[], time_t *bins_last_time[], double *bins_last_value[], time_t last_time[], double last_value[], int status[])=0
returns HS_SUCCESS
DWORD last_time
Definition mana.cxx:3070
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_binned_arraybuffer()

static MJsonNode * js_hs_read_binned_arraybuffer ( const MJsonNode *  params)
static

Definition at line 2635 of file mjsonrpc.cxx.

2636{
2637 if (!params) {
2638 MJSO* doc = MJSO::I();
2639 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2640 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2641 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2642 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2643 doc->P("num_bins", MJSON_INT, "number of time bins");
2644 doc->P("events[]", MJSON_STRING, "array of history event names");
2645 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2646 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2647 doc->R("binary data", MJSON_ARRAYBUFFER, "binary data, see documentation");
2648 return doc;
2649 }
2650
2651 MJsonNode* error = NULL;
2652
2653 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2654 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2655 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2656 int inum_bins = mjsonrpc_get_param(params, "num_bins", &error)->GetInt(); if (error) return error;
2657
2658 if (inum_bins < 1) {
2659 return mjsonrpc_make_error(-32602, "Invalid params", "Value of num_bins should be 1 or more");
2660 }
2661
2662 size_t num_bins = inum_bins;
2663
2664 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2665 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2666 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2667
2669
2670 if (!mh) {
2671 int status = HS_FILE_ERROR;
2672 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
2673 }
2674
2675 size_t num_var = events_array->size();
2676
2677 if (num_var < 1) {
2678 return mjsonrpc_make_error(-32602, "Invalid params", "Array of events should have 1 or more elements");
2679 }
2680
2681 if (tags_array->size() != num_var) {
2682 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2683 }
2684
2685 if (index_array->size() != num_var) {
2686 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2687 }
2688
2689 std::vector<std::string> event_names(num_var);
2690 std::vector<std::string> tag_names(num_var);
2691 //const char** event_name = new const char*[num_var];
2692 //const char** tag_name = new const char*[num_var];
2693 int* var_index = new int[num_var];
2694
2695 int* num_entries = new int[num_var];
2697 double* last_value = new double[num_var];
2698 int* hs_status = new int[num_var];
2699
2700 int** count_bins = new int*[num_var];
2701 double** mean_bins = new double*[num_var];
2702 double** rms_bins = new double*[num_var];
2703 double** min_bins = new double*[num_var];
2704 double** max_bins = new double*[num_var];
2705
2708
2709 double** bins_first_value = new double*[num_var];
2710 double** bins_last_value = new double*[num_var];
2711
2712 for (unsigned i=0; i<num_var; i++) {
2713 //event_name[i] = (*events_array)[i]->GetString().c_str();
2714 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2715 event_names[i] = (*events_array)[i]->GetString();
2716 tag_names[i] = (*tags_array)[i]->GetString();
2717 var_index[i] = (*index_array)[i]->GetInt();
2718 num_entries[i] = 0;
2719 last_time[i] = 0;
2720 last_value[i] = 0;
2721 hs_status[i] = 0;
2722 count_bins[i] = new int[num_bins];
2723 mean_bins[i] = new double[num_bins];
2724 rms_bins[i] = new double[num_bins];
2725 min_bins[i] = new double[num_bins];
2726 max_bins[i] = new double[num_bins];
2729 bins_first_value[i] = new double[num_bins];
2730 bins_last_value[i] = new double[num_bins];
2731 }
2732
2733 if (/* DISABLES CODE */ (0)) {
2734 printf("time %f %f, num_vars %d:\n", start_time, end_time, int(num_var));
2735 for (size_t i=0; i<num_var; i++) {
2736 printf("%d: [%s] [%s] [%d]\n", int(i), event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2737 }
2738 }
2739
2740 const char** event_name = new const char*[num_var];
2741 const char** tag_name = new const char*[num_var];
2742 for (size_t i=0; i<num_var; i++) {
2743 event_name[i] = event_names[i].c_str();
2744 tag_name[i] = tag_names[i].c_str();
2745 }
2746
2747 int status = mh->hs_read_binned(start_time, end_time, num_bins, num_var, event_name, tag_name, var_index, num_entries, count_bins, mean_bins, rms_bins, min_bins, max_bins, bins_first_time, bins_first_value, bins_last_time, bins_last_value, last_time, last_value, hs_status);
2748
2749 // NB: beware of 32-bit integer overflow: all variables are now 64-bit size_t, overflow should not happen
2750 size_t p0_size = sizeof(double)*(5+4*num_var+9*num_var*num_bins);
2751
2752 size_t size_limit = 100*1024*1024;
2753
2754 if (p0_size > size_limit) {
2755 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Refusing to return %d bytes. limit is %d bytes\n", int(p0_size), int(size_limit));
2756
2757 for (size_t i=0; i<num_var; i++) {
2758 delete count_bins[i];
2759 delete mean_bins[i];
2760 delete rms_bins[i];
2761 delete min_bins[i];
2762 delete max_bins[i];
2763 delete bins_first_time[i];
2764 delete bins_first_value[i];
2765 delete bins_last_time[i];
2766 delete bins_last_value[i];
2767 }
2768
2769 delete[] count_bins;
2770 delete[] mean_bins;
2771 delete[] rms_bins;
2772 delete[] min_bins;
2773 delete[] max_bins;
2774
2775 delete[] bins_first_time;
2776 delete[] bins_first_value;
2777 delete[] bins_last_time;
2778 delete[] bins_last_value;
2779
2780 delete[] event_name;
2781 delete[] tag_name;
2782 delete[] var_index;
2783
2784 delete[] num_entries;
2785 delete[] last_time;
2786 delete[] last_value;
2787 delete[] hs_status;
2788
2789 return mjsonrpc_make_error(-32603, "Internal error", "Refuse to return too much data");
2790 }
2791
2792 double* p0 = (double*)malloc(p0_size);
2793
2794 if (p0 == NULL) {
2795 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Cannot allocate return buffer %d bytes\n", int(p0_size));
2796
2797 for (size_t i=0; i<num_var; i++) {
2798 delete count_bins[i];
2799 delete mean_bins[i];
2800 delete rms_bins[i];
2801 delete min_bins[i];
2802 delete max_bins[i];
2803 delete bins_first_time[i];
2804 delete bins_first_value[i];
2805 delete bins_last_time[i];
2806 delete bins_last_value[i];
2807 }
2808
2809 delete[] count_bins;
2810 delete[] mean_bins;
2811 delete[] rms_bins;
2812 delete[] min_bins;
2813 delete[] max_bins;
2814
2815 delete[] bins_first_time;
2816 delete[] bins_first_value;
2817 delete[] bins_last_time;
2818 delete[] bins_last_value;
2819
2820 delete[] event_name;
2821 delete[] tag_name;
2822 delete[] var_index;
2823
2824 delete[] num_entries;
2825 delete[] last_time;
2826 delete[] last_value;
2827 delete[] hs_status;
2828
2829 return mjsonrpc_make_error(-32603, "Internal error", "Cannot allocate buffer, too much data");
2830 }
2831
2832 double *pptr = p0;
2833
2834 //
2835 // Binary data format:
2836 //
2837 // * header
2838 // -- hs_read() status
2839 // -- start_time
2840 // -- end_time
2841 // -- num_bins
2842 // -- num_var
2843 // * per variable info
2844 // -- hs_status[0..num_var-1]
2845 // -- num_entries[0..num_var-1]
2846 // -- last_time[0..num_var-1]
2847 // -- last_value[0..num_var-1]
2848 // * data for var0 bin0
2849 // -- count - number of entries in this bin
2850 // -- mean - mean value
2851 // -- rms - rms value
2852 // -- min - minimum value
2853 // -- max - maximum value
2854 // -- bins_first_time - first data point in each bin
2855 // -- bins_first_value
2856 // -- bins_last_time - last data point in each bin
2857 // -- bins_last_value
2858 // - data for var0 bin1
2859 // - ... bin[num_bins-1]
2860 // - data for var1 bin0
2861 // - ...
2862 // - data for var[num_vars-1] bin[0]
2863 // - ...
2864 // - data for var[num_vars-1] bin[num_bins-1]
2865 //
2866
2867 *pptr++ = status;
2868 *pptr++ = start_time;
2869 *pptr++ = end_time;
2870 *pptr++ = num_bins;
2871 *pptr++ = num_var;
2872
2873 for (unsigned i=0; i<num_var; i++) {
2874 *pptr++ = hs_status[i];
2875 }
2876
2877 for (unsigned i=0; i<num_var; i++) {
2878 *pptr++ = num_entries[i];
2879 }
2880
2881 for (unsigned i=0; i<num_var; i++) {
2882 *pptr++ = last_time[i];
2883 }
2884
2885 for (unsigned i=0; i<num_var; i++) {
2886 *pptr++ = last_value[i];
2887 }
2888
2889 for (size_t i=0; i<num_var; i++) {
2890 for (size_t j=0; j<num_bins; j++) {
2891 *pptr++ = count_bins[i][j];
2892 *pptr++ = mean_bins[i][j];
2893 *pptr++ = rms_bins[i][j];
2894 *pptr++ = min_bins[i][j];
2895 *pptr++ = max_bins[i][j];
2896 *pptr++ = bins_first_time[i][j];
2897 *pptr++ = bins_first_value[i][j];
2898 *pptr++ = bins_last_time[i][j];
2899 *pptr++ = bins_last_value[i][j];
2900 }
2901
2902 delete count_bins[i];
2903 delete mean_bins[i];
2904 delete rms_bins[i];
2905 delete min_bins[i];
2906 delete max_bins[i];
2907 delete bins_first_time[i];
2908 delete bins_first_value[i];
2909 delete bins_last_time[i];
2910 delete bins_last_value[i];
2911 }
2912
2913 //printf("p0_size %d, %d/%d\n", (int)p0_size, (int)(pptr-p0), (int)((pptr-p0)*sizeof(double)));
2914
2915 assert(p0_size == ((pptr-p0)*sizeof(double)));
2916
2917 delete[] count_bins;
2918 delete[] mean_bins;
2919 delete[] rms_bins;
2920 delete[] min_bins;
2921 delete[] max_bins;
2922
2923 delete[] bins_first_time;
2924 delete[] bins_first_value;
2925 delete[] bins_last_time;
2926 delete[] bins_last_value;
2927
2928 delete[] event_name;
2929 delete[] tag_name;
2930 delete[] var_index;
2931
2932 delete[] num_entries;
2933 delete[] last_time;
2934 delete[] last_value;
2935 delete[] hs_status;
2936
2937 MJsonNode* result = MJsonNode::MakeArrayBuffer((char*)p0, p0_size);
2938
2939 return result;
2940}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_reopen()

static MJsonNode * js_hs_reopen ( const MJsonNode *  params)
static

Definition at line 1875 of file mjsonrpc.cxx.

1876{
1877 if (!params) {
1878 MJSO* doc = MJSO::I();
1879 doc->D("reopen the history channel to make sure we see the latest list of events using hs_clear_cache()");
1880 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1881 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1882 doc->R("channel", MJSON_STRING, "logger history channel name");
1883 return doc;
1884 }
1885
1886 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1887
1889
1890 if (!mh) {
1891 int status = HS_FILE_ERROR;
1892 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1893 }
1894
1895 int status = mh->hs_clear_cache();
1896
1897 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name));
1898}
virtual int hs_clear_cache()=0
clear internal cache, returns HS_SUCCESS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_make_subdir()

static MJsonNode * js_make_subdir ( const MJsonNode *  params)
static

Definition at line 4076 of file mjsonrpc.cxx.

4077{
4078 if (!params) {
4079 MJSO* doc = MJSO::I();
4080 doc->D("js_make_subdir");
4081 doc->P("subdir", MJSON_STRING, "Create folder experiment_directory/userfiles/subdir");
4082 doc->R("status", MJSON_INT, "return status of midas library calls");
4083 doc->R("path", MJSON_STRING, "Search path");
4084 return doc;
4085 }
4086
4087 MJsonNode* error = NULL;
4088
4089 std::string subdir = mjsonrpc_get_param(params, "subdir", &error)->GetString(); if (error) return error;
4090
4091 /*---- Not allowed to contain ../ - safety feature ----*/
4092 if (subdir.find("..") != std::string::npos) {
4093 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The subdir is not permitted"));
4094 }
4095
4096 int status;
4097 HNDLE hDB;
4098
4100
4101 if (status != DB_SUCCESS) {
4102 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
4103 }
4104
4105 std::string path = cm_expand_env(cm_get_path().c_str());
4106 if (path[path.length()-1] != DIR_SEPARATOR) {
4107 path += DIR_SEPARATOR_STR;
4108 }
4109 path += "userfiles";
4110
4111 // Check if the userfiles folder exists
4112 if (access(path.c_str(), F_OK) != 0) {
4113 // Create the path if it doesn't exist
4114 if (mkdir(path.c_str(), 0777) != 0) {
4115 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4116 }
4117 }
4118
4119 // Add subdir to userfiles
4120 if (subdir.length() > 0) {
4121 if (subdir[0] != DIR_SEPARATOR) {
4122 path += DIR_SEPARATOR_STR;
4123 }
4124 path += subdir;
4125 }
4126 // Check if the subdir exisits in userfiles, otherwise create it
4127 if (access(path.c_str(), F_OK) != 0) {
4128 // Create the path if it doesn't exist
4129 if (mkdir(path.c_str(), 0777) != 0) {
4130 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create subdirectory"));
4131 }
4132 }
4133
4134
4135 MJsonNode* r = MJsonNode::MakeObject();
4136 r->AddToObject("status", MJsonNode::MakeInt(SUCCESS));
4137 ss_repair_utf8(path);
4138 r->AddToObject("path", MJsonNode::MakeString(path.c_str()));
4139 return mjsonrpc_make_result(r);
4140}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_read_binary_file()

static MJsonNode * js_read_binary_file ( const MJsonNode *  params)
static

Definition at line 4428 of file mjsonrpc.cxx.

4428 {
4429 if (!params) {
4430 MJSO* doc = MJSO::I();
4431 doc->D("js_read_binary_file");
4432 doc->P("filename", MJSON_STRING, "File name, read from experiment_directory/userfiles/filename");
4433 doc->R("binary data", MJSON_ARRAYBUFFER, "Binary file content");
4434 doc->R("status", MJSON_INT, "Return status of midas library calls");
4435 doc->R("error", MJSON_STRING, "Error text");
4436 return doc;
4437 }
4438
4439 MJsonNode* error = NULL;
4440 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString();
4441 if (error) return error;
4442
4443 /*---- filename should not contain the following - safety feature */
4444 if (filename.find("..") != std::string::npos ||
4445 filename.find("*") != std::string::npos) {
4446 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4447 }
4448
4449 int status;
4450 HNDLE hDB;
4451
4453
4454 if (status != DB_SUCCESS) {
4455 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4456 }
4457
4458 std::string path = cm_expand_env(cm_get_path().c_str());
4459 if (path[path.length()-1] != DIR_SEPARATOR) {
4460 path += DIR_SEPARATOR_STR;
4461 }
4462 path += "userfiles";
4463
4464 // Check if the userfiles folder exists
4465 if (access(path.c_str(), F_OK) != 0) {
4466 // Create the path if it doesn't exist
4467 if (mkdir(path.c_str(), 0777) != 0) {
4468 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4469 }
4470 }
4471
4472 path += DIR_SEPARATOR_STR;
4473 path += filename;
4474
4475 FILE* fp = fopen(path.c_str(), "rb");
4476 if (!fp) {
4478 char errstr[256];
4479 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4480 ss_repair_utf8(errstr);
4481 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4482 }
4483
4484 fseek(fp, 0, SEEK_END);
4485 size_t file_size = ftell(fp);
4486 rewind(fp);
4487
4488 char* buffer = new char[file_size];
4489 fread(buffer, file_size, 1, fp);
4490 // maybe not needed here
4491 //buffer[file_size] = '\0';
4492 fclose(fp);
4493
4495 std::string errstr = "no error";
4496
4497 MJsonNode* result = MJsonNode::MakeArrayBuffer(buffer, file_size);
4498 return result;
4499}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ss_millitime()

static MJsonNode * js_ss_millitime ( const MJsonNode *  params)
static

Definition at line 3833 of file mjsonrpc.cxx.

3834{
3835 if (!params) {
3836 MJSO *doc = MJSO::I();
3837 doc->D("get current MIDAS time using ss_millitime()");
3838 doc->P(NULL, 0, "there are no input parameters");
3839 doc->R(NULL, MJSON_INT, "current value of ss_millitime()");
3840 return doc;
3841 }
3842
3843 return mjsonrpc_make_result(MJsonNode::MakeNumber(ss_millitime()));
3844}
DWORD ss_millitime()
Definition system.cxx:3393
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MatchEvent()

static void MatchEvent ( const std::string  buffer_name,
const EVENT_HEADER pevent 
)
static

Definition at line 3620 of file mjsonrpc.cxx.

3621{
3622 std::lock_guard<std::mutex> guard(gEventStashMutex);
3623 for (EventStashEntry* s : gEventStash) {
3624 if (s->buffer_name != buffer_name)
3625 continue;
3626 if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3627 s->ReplaceEvent(pevent);
3628 //s->Print(); printf(", matched\n");
3629 }
3630 }
3631}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_get_param_array()

const MJsonNodeVector * mjsonrpc_get_param_array ( const MJsonNode *  params,
const char name,
MJsonNode **  error 
)

Definition at line 201 of file mjsonrpc.cxx.

202{
203 // NULL params is a request for documentation, return NULL
204 if (!params) {
205 if (error)
206 *error = MJsonNode::MakeObject();
207 return NULL;
208 }
209
210 const MJsonNode* node = mjsonrpc_get_param(params, name, error);
211
212 // handle error return from mjsonrpc_get_param()
213 if (error && *error) {
214 return NULL;
215 }
216
217 const MJsonNodeVector* v = node->GetArray();
218
219 if (!v) {
220 if (error)
221 *error = mjsonrpc_make_error(-32602, "Invalid params", (std::string("parameter must be an array: ") + name).c_str());
222 return NULL;
223 }
224
225 if (error)
226 *error = NULL;
227 return v;
228}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_handle_request()

static MJsonNode * mjsonrpc_handle_request ( const MJsonNode *  request)
static

Definition at line 5109 of file mjsonrpc.cxx.

5110{
5111 // find required request elements
5112 const MJsonNode* version = request->FindObjectNode("jsonrpc");
5113 const MJsonNode* method = request->FindObjectNode("method");
5114 const MJsonNode* params = request->FindObjectNode("params");
5115 const MJsonNode* id = request->FindObjectNode("id");
5116
5117 std::string bad = "";
5118
5119 if (!version)
5120 add(&bad, "jsonrpc version is missing");
5121 if (!method)
5122 add(&bad, "method is missing");
5123 if (!params)
5124 add(&bad, "params is missing");
5125 if (!id)
5126 add(&bad, "id is missing");
5127
5128 if (version&&version->GetType() != MJSON_STRING)
5129 add(&bad, "jsonrpc version is not a string");
5130 if (version&&version->GetString() != "2.0")
5131 add(&bad, "jsonrpc version is not 2.0");
5132
5133 if (method&&method->GetType() != MJSON_STRING)
5134 add(&bad, "method is not a string");
5135
5136 if (bad.length() > 0) {
5137 MJsonNode* response = mjsonrpc_make_error(-32600, "Invalid request", bad.c_str());
5138 response->AddToObject("jsonrpc", MJsonNode::MakeString("2.0"));
5139 if (id) {
5140 response->AddToObject("id", id->Copy());
5141 } else {
5142 response->AddToObject("id", MJsonNode::MakeNull());
5143 }
5144
5145 if (mjsonrpc_debug) {
5146 printf("mjsonrpc: invalid request: reply:\n");
5147 printf("%s\n", response->Stringify().c_str());
5148 printf("\n");
5149 }
5150
5151 return response;
5152 }
5153
5154 double start_time = 0;
5155
5156 if (mjsonrpc_time) {
5157 start_time = GetTimeSec();
5158 }
5159
5160 const std::string ms = method->GetString();
5161 const char* m = ms.c_str();
5162
5163 MJsonNode* result = NULL;
5164
5165 // special built-in methods
5166
5167 if (strcmp(m, "echo") == 0) {
5168 result = mjsonrpc_make_result(request->Copy());
5169 } else if (strcmp(m, "error") == 0) {
5170 result = mjsonrpc_make_error(1, "test error", "test error");
5171 } else if (strcmp(m, "invalid_json") == 0) {
5172 if (mjsonrpc_debug) {
5173 printf("mjsonrpc: reply with invalid json\n");
5174 }
5175 return MJsonNode::MakeJSON("this is invalid json data");
5176 } else if (strcmp(m, "test_nan_inf") == 0) {
5177 double one = 1;
5178 double zero = 0;
5179 double nan = zero/zero;
5180 double plusinf = one/zero;
5181 double minusinf = -one/zero;
5182 MJsonNode* n = MJsonNode::MakeArray();
5183 n->AddToArray(MJsonNode::MakeNumber(nan));
5184 n->AddToArray(MJsonNode::MakeNumber(plusinf));
5185 n->AddToArray(MJsonNode::MakeNumber(minusinf));
5186 result = mjsonrpc_make_result("test_nan_plusinf_minusinf", n);
5187 } else if (strcmp(m, "test_arraybuffer") == 0) {
5188 if (mjsonrpc_debug) {
5189 printf("mjsonrpc: reply with test arraybuffer data\n");
5190 }
5191 size_t size = 32;
5192 char* ptr = (char*)malloc(size);
5193 for (size_t i=0; i<size; i++) {
5194 ptr[i] = 'A' + i;
5195 }
5196 *((short*)(ptr+4*2*1)) = 111; // int16[4]
5197 *((int*)(ptr+4*2*2)) = 1234; // int32[4]
5198 *((double*)(ptr+4*2*3)) = 3.14; // float64[3]
5199 return MJsonNode::MakeArrayBuffer(ptr, size);
5200 } else {
5202 if (s != gMethodsTable.end()) {
5203 bool lock = s->second.fNeedsLocking;
5204 if (lock && gMutex)
5205 gMutex->lock();
5206 result = s->second.fHandler(params);
5207 if (lock && gMutex)
5208 gMutex->unlock();
5209 } else {
5210 result = mjsonrpc_make_error(-32601, "Method not found", (std::string("unknown method: ") + ms).c_str());
5211 }
5212 }
5213
5214 if (mjsonrpc_debug) {
5215 printf("mjsonrpc: handler reply:\n");
5216 result->Dump();
5217 printf("\n");
5218 }
5219
5220 double end_time = 0;
5221 double elapsed_time = 0;
5222 if (mjsonrpc_time) {
5223 end_time = GetTimeSec();
5224 elapsed_time = end_time - start_time;
5225 if (mjsonrpc_time > 1) {
5226 printf("request took %.3f seconds, method [%s]\n", elapsed_time, m);
5227 }
5228 }
5229
5230 if (result->GetType() == MJSON_ARRAYBUFFER) {
5231 return result;
5232 }
5233
5234 const MJsonNode *nerror = result->FindObjectNode("error");
5235 const MJsonNode *nresult = result->FindObjectNode("result");
5236
5237 if (nerror) {
5238 result->DeleteObjectNode("result");
5239 } else if (nresult) {
5240 result->DeleteObjectNode("error");
5241 } else {
5242 delete result;
5243 result = mjsonrpc_make_error(-32603, "Internal error", "bad dispatcher reply: no result and no error");
5244 }
5245
5246 result->AddToObject("jsonrpc", MJsonNode::MakeString("2.0"));
5247
5248 if (id) {
5249 result->AddToObject("id", id->Copy());
5250 } else {
5251 result->AddToObject("id", MJsonNode::MakeNull());
5252 }
5253
5254 if (mjsonrpc_time) {
5255 result->AddToObject("elapsed_time", MJsonNode::MakeNumber(elapsed_time));
5256 }
5257
5258 assert(result != NULL);
5259
5260 return result;
5261}
char response[10000]
Definition melog.cxx:90
char request[600000]
Definition melog.cxx:90
MethodsTable::iterator MethodsTableIterator
static double GetTimeSec()
Definition mjsonrpc.cxx:116
static MethodsTable gMethodsTable
INT add
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_make_result()

MJsonNode * mjsonrpc_make_result ( const char name,
MJsonNode *  value,
const char name2,
MJsonNode *  value2,
const char name3,
MJsonNode *  value3,
const char name4,
MJsonNode *  value4 
)

Definition at line 158 of file mjsonrpc.cxx.

159{
160 MJsonNode* node = MJsonNode::MakeObject();
161
162 if (name)
163 node->AddToObject(name, value);
164 if (name2)
165 node->AddToObject(name2, value2);
166 if (name3)
167 node->AddToObject(name3, value3);
168 if (name4)
169 node->AddToObject(name4, value4);
170
171 MJsonNode* result = MJsonNode::MakeObject();
172 result->AddToObject("result", node);
173 return result;
174}
Here is the call graph for this function:

◆ mjsonrpc_make_schema()

static MJsonNode * mjsonrpc_make_schema ( MethodsTable h)
static

Definition at line 4750 of file mjsonrpc.cxx.

4751{
4752 MJsonNode* s = MJsonNode::MakeObject();
4753
4754 s->AddToObject("$schema", MJsonNode::MakeString("http://json-schema.org/schema#"));
4755 s->AddToObject("id", MJsonNode::MakeString("MIDAS JSON-RPC autogenerated schema"));
4756 s->AddToObject("title", MJsonNode::MakeString("MIDAS JSON-RPC schema"));
4757 s->AddToObject("description", MJsonNode::MakeString("Autogenerated schema for all MIDAS JSON-RPC methods"));
4758 s->AddToObject("type", MJsonNode::MakeString("object"));
4759
4760 MJsonNode* m = MJsonNode::MakeObject();
4761
4762 for (MethodsTableIterator iterator = h->begin(); iterator != h->end(); iterator++) {
4763 // iterator->first = key
4764 // iterator->second = value
4765 //printf("build schema for method \"%s\"!\n", iterator->first.c_str());
4766 MJsonNode* doc = iterator->second.fHandler(NULL);
4767 if (doc == NULL)
4768 doc = MJsonNode::MakeObject();
4769 m->AddToObject(iterator->first.c_str(), doc);
4770 }
4771
4772 s->AddToObject("properties", m);
4773 s->AddToObject("required", MJsonNode::MakeArray());
4774
4775 return s;
4776}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_anything()

std::string mjsonrpc_schema_to_html_anything ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 5049 of file mjsonrpc.cxx.

5050{
5051 std::string type;
5052 std::string description;
5053 //bool optional = false;
5054
5055 const MJsonNode* t = schema->FindObjectNode("type");
5056 if (t)
5057 type = t->GetString();
5058 else
5059 type = "any";
5060
5061 const MJsonNode* d = schema->FindObjectNode("description");
5062 if (d)
5063 description = d->GetString();
5064
5065 //const MJsonNode* o = schema->FindObjectNode("optional");
5066 //if (o)
5067 // optional = o->GetBool();
5068
5069 if (type == "object") {
5071 } else if (type == "array") {
5073 } else {
5074 //if (optional)
5075 // output(nest_level, false, "?");
5076 //else
5077 // output(nest_level, false, "!");
5078 o->Output(nest_level, false, type);
5079 o->Output(nest_level+1, true, description);
5080 if (description.length() > 1) {
5081 return (type + "</td><td>" + description);
5082 } else {
5083 return (type);
5084 }
5085 }
5086}
char description[1000]
Definition mana.cxx:267
static std::string mjsonrpc_schema_to_html_array(const MJsonNode *schema, int nest_level, NestedOutput *o)
static std::string mjsonrpc_schema_to_html_object(const MJsonNode *schema, int nest_level, NestedOutput *o)
double d
Definition system.cxx:1311
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_array()

static std::string mjsonrpc_schema_to_html_array ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 4993 of file mjsonrpc.cxx.

4994{
4995 const MJsonNode* d = schema->FindObjectNode("description");
4996 std::string description;
4997 if (d)
4998 description = d->GetString();
4999
5000 std::string xshort = "array";
5001 if (description.length() > 1)
5002 xshort += "</td><td>" + description;
5003
5004 const MJsonNode* items = schema->FindObjectNode("items");
5005
5006 if (!items) {
5007 o->Output(nest_level, false, "array");
5008 o->Output(nest_level+1, true, description);
5009 return xshort;
5010 }
5011
5012 const MJsonNodeVector *nodes = items->GetArray();
5013
5014 if (!nodes) {
5015 o->Output(nest_level, false, "array");
5016 o->Output(nest_level+1, true, description);
5017 return xshort;
5018 }
5019
5020 std::string nest = indent(nest_level * 4);
5021
5022 std::string s;
5023
5024 //s += "array</td><td>";
5025
5026 s += nest + "<table border=1>\n";
5027
5028 if (description.length() > 1) {
5029 s += nest + "<tr>\n";
5030 s += nest + " <td>" + description + "</td>\n";
5031 s += nest + "</tr>\n";
5032 }
5033
5034 o->Output(nest_level, true, description);
5035
5036 for (unsigned i=0; i<nodes->size(); i++) {
5037 o->Output(nest_level, false, "array of");
5038
5039 s += nest + "<tr>\n";
5040 s += nest + " <td> array of " + mjsonrpc_schema_to_html_anything((*nodes)[i], nest_level + 1, o) + "</td>\n";
5041 s += nest + "</tr>\n";
5042 }
5043
5044 s += nest + "</table>\n";
5045
5046 return s;
5047}
static std::string mjsonrpc_schema_to_html_anything(const MJsonNode *schema, int nest_level, NestedOutput *o)
static std::string indent(int x, const char *p=" ")
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_object()

static std::string mjsonrpc_schema_to_html_object ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 4907 of file mjsonrpc.cxx.

4908{
4909 const MJsonNode* d = schema->FindObjectNode("description");
4910 std::string description;
4911 if (d)
4912 description = d->GetString();
4913
4914 std::string xshort = "object";
4915 if (description.length() > 1)
4916 xshort += "</td><td>" + description;
4917
4918 const MJsonNode* properties = schema->FindObjectNode("properties");
4919
4921 const MJsonNode* r = schema->FindObjectNode("required");
4922 if (r)
4923 required_list = r->GetArray();
4924
4925 if (!properties) {
4926 o->Output(nest_level, false, "object");
4927 o->Output(nest_level+1, true, description);
4928 return xshort;
4929 }
4930
4931 const MJsonStringVector *names = properties->GetObjectNames();
4932 const MJsonNodeVector *nodes = properties->GetObjectNodes();
4933
4934 if (!names || !nodes) {
4935 o->Output(nest_level, false, "object");
4936 o->Output(nest_level+1, true, description);
4937 return xshort;
4938 }
4939
4940 std::string nest = indent(nest_level * 4);
4941
4942 std::string s;
4943
4944 s += nest + "<table border=1>\n";
4945
4946 if (description.length() > 1) {
4947 s += nest + "<tr>\n";
4948 s += nest + " <td colspan=3>" + description + "</td>\n";
4949 s += nest + "</tr>\n";
4950 }
4951
4952 o->Output(nest_level, true, description);
4953
4954 for (unsigned i=0; i<names->size(); i++) {
4955 std::string name = (*names)[i];
4956 const MJsonNode* node = (*nodes)[i];
4957
4958 bool required = false;
4959 if (required_list)
4960 for (unsigned j=0; j<required_list->size(); j++)
4961 if ((*required_list)[j])
4962 if ((*required_list)[j]->GetString() == name) {
4963 required = true;
4964 break;
4965 }
4966
4967 bool is_array = false;
4968 const MJsonNode* type = node->FindObjectNode("type");
4969 if (type && type->GetString() == "array")
4970 is_array = true;
4971
4972 if (is_array)
4973 name += "[]";
4974
4975 if (!required)
4976 name += "?";
4977
4978 o->Output(nest_level, false, name);
4979
4980 s += nest + "<tr>\n";
4981 s += nest + " <td>" + name + "</td>\n";
4982 s += nest + " <td>";
4984 s += "</td>\n";
4985 s += nest + "</tr>\n";
4986 }
4987
4988 s += nest + "</table>\n";
4989
4990 return s;
4991}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_array_index_list()

static int parse_array_index_list ( const char method,
const char path,
std::vector< unsigned > *  list 
)
static

Definition at line 560 of file mjsonrpc.cxx.

561{
562 // parse array index in form of:
563 // odbpath[number]
564 // odbpath[number,number]
565 // odbpath[number-number]
566 // or any combination of them, i.e. odbpath[1,10-15,20,30-40]
567
568 const char*s = strchr(path, '[');
569
570 if (!s) {
571 cm_msg(MERROR, method, "expected an array index character \'[\' in \"%s\"", path);
572 return DB_OUT_OF_RANGE;
573 }
574
575 s++; // skip '[' itself
576
577 while (s && (*s != 0)) {
578
579 // check that we have a number
580 if (!isdigit(*s)) {
581 cm_msg(MERROR, method, "expected a number in array index in \"%s\" at \"%s\"", path, s);
582 return DB_OUT_OF_RANGE;
583 }
584
585 unsigned value1 = strtoul(s, (char**)&s, 10);
586
587 // array range,
588 if (*s == '-') {
589 s++; // skip the minus char
590
591 if (!isdigit(*s)) {
592 cm_msg(MERROR, method, "expected a number in array index in \"%s\" at \"%s\"", path, s);
593 return DB_OUT_OF_RANGE;
594 }
595
596 unsigned value2 = strtoul(s, (char**)&s, 10);
597
598 if (value2 >= value1)
599 for (unsigned i=value1; i<=value2; i++)
600 list->push_back(i);
601 else {
602 // this is stupid. simple loop like this
603 // for (unsigned i=value1; i>=value2; i--)
604 // does not work for range 4-0, because value2 is 0,
605 // and x>=0 is always true for unsigned numbers,
606 // so we would loop forever... K.O.
607 for (unsigned i=value1; i!=value2; i--)
608 list->push_back(i);
609 list->push_back(value2);
610 }
611 } else {
612 list->push_back(value1);
613 }
614
615 if (*s == ',') {
616 s++; // skip the comma char
617 continue; // back to the begin of loop
618 }
619
620 if (*s == ']') {
621 s++; // skip the closing bracket
622 s = NULL;
623 continue; // done
624 }
625
626 cm_msg(MERROR, method, "invalid char in array index in \"%s\" at \"%s\"", path, s);
627 return DB_OUT_OF_RANGE;
628 }
629
630#if 0
631 printf("parsed array indices for \"%s\" size is %d: ", path, (int)list->size());
632 for (unsigned i=0; i<list->size(); i++)
633 printf(" %d", (*list)[i]);
634 printf("\n");
635#endif
636
637 return SUCCESS;
638}
#define DB_OUT_OF_RANGE
Definition midas.h:651
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove()

static std::string remove ( const std::string  s,
char  c 
)
static

Definition at line 253 of file mjsonrpc.cxx.

254{
255 std::string::size_type pos = s.find(c);
256 if (pos == std::string::npos)
257 return s;
258 else
259 return s.substr(0, pos);
260}
char c
Definition system.cxx:1310
Here is the caller graph for this function:

◆ set_debug()

static MJsonNode * set_debug ( const MJsonNode *  params)
static

Definition at line 4521 of file mjsonrpc.cxx.

4522{
4523 if (!params) {
4524 MJSO* doc = MJSO::I();
4525 doc->D("set new value of mjsonrpc_debug");
4526 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4527 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4528 return doc;
4529 }
4530
4531 mjsonrpc_debug = params->GetInt();
4532 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4533}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_sleep()

static MJsonNode * set_sleep ( const MJsonNode *  params)
static

Definition at line 4548 of file mjsonrpc.cxx.

4549{
4550 if (!params) {
4551 MJSO* doc = MJSO::I();
4552 doc->D("set new value of mjsonrpc_sleep");
4553 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4554 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4555 return doc;
4556 }
4557
4558 mjsonrpc_sleep = params->GetInt();
4559 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4560}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_time()

static MJsonNode * set_time ( const MJsonNode *  params)
static

Definition at line 4575 of file mjsonrpc.cxx.

4576{
4577 if (!params) {
4578 MJSO* doc = MJSO::I();
4579 doc->D("set new value of mjsonrpc_time");
4580 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_time");
4581 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_time");
4582 return doc;
4583 }
4584
4585 mjsonrpc_time = params->GetInt();
4586 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4587}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_program()

static MJsonNode * start_program ( const MJsonNode *  params)
static

Definition at line 486 of file mjsonrpc.cxx.

487{
488 if (!params) {
489 MJSO* doc = MJSO::I();
490 doc->D("start MIDAS program defined in ODB /Programs/name");
491 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
492 doc->R("status", MJSON_INT, "return status of ss_system()");
493 return doc;
494 }
495
496 MJsonNode* error = NULL;
497
498 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString(); if (error) return error;
499
500 std::string path = "";
501 path += "/Programs/";
502 path += name;
503 path += "/Start command";
504
505 HNDLE hDB;
507
508 char command[256];
509 int size = sizeof(command);
510 int status = db_get_value(hDB, 0, path.c_str(), command, &size, TID_STRING, FALSE);
511
512 if (status == DB_SUCCESS && command[0]) {
513 status = ss_system(command);
514 }
515
516 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
517}
INT ss_system(const char *command)
Definition system.cxx:2116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ StashEvent()

static void StashEvent ( const std::string  buffer_name,
int  event_id,
int  trigger_mask,
const EVENT_HEADER pevent 
)
static

Definition at line 3593 of file mjsonrpc.cxx.

3594{
3595 std::lock_guard<std::mutex> guard(gEventStashMutex);
3596 bool found = false;
3597 for (EventStashEntry* s : gEventStash) {
3598 if (s->buffer_name != buffer_name)
3599 continue;
3600 if (s->event_id == event_id && s->trigger_mask == trigger_mask) {
3601 found = true;
3602 s->ReplaceEvent(pevent);
3603 //s->Print(); printf(", replaced\n");
3604 } else if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3605 s->ReplaceEvent(pevent);
3606 //s->Print(); printf(", matched\n");
3607 }
3608 }
3609 if (!found) {
3612 s->event_id = event_id;
3614 s->pevent = CopyEvent(pevent);
3615 //s->Print(); printf(", added\n");
3616 gEventStash.push_back(s);
3617 }
3618}
std::string buffer_name
int event_id
const EVENT_HEADER * pevent
int trigger_mask
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xnull()

static MJsonNode * xnull ( const MJsonNode *  params)
static

Definition at line 413 of file mjsonrpc.cxx.

414{
415 if (!params) {
416 MJSO* doc = MJSO::I();
417 doc->D("RPC method always returns null");
418 doc->P(NULL, 0, "method parameters are ignored");
419 doc->R(NULL, MJSON_NULL, "always returns null");
420 return doc;
421 }
422
423 return mjsonrpc_make_result(MJsonNode::MakeNull());
424}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gEventStash

std::vector<EventStashEntry*> gEventStash
static

Definition at line 3591 of file mjsonrpc.cxx.

◆ gEventStashMutex

std::mutex gEventStashMutex
static

Definition at line 3590 of file mjsonrpc.cxx.

◆ gHistoryChannels

MhiMap gHistoryChannels
static

Definition at line 1696 of file mjsonrpc.cxx.

◆ gMethodsTable

MethodsTable gMethodsTable
static

Definition at line 4640 of file mjsonrpc.cxx.

◆ gMutex

std::mutex* gMutex = NULL
static

Definition at line 4641 of file mjsonrpc.cxx.

◆ gNullNode

MJsonNode* gNullNode = NULL
static

Definition at line 176 of file mjsonrpc.cxx.

◆ mjsonrpc_sleep

int mjsonrpc_sleep = 0
static

Definition at line 113 of file mjsonrpc.cxx.

◆ mjsonrpc_time

int mjsonrpc_time = 0
static

Definition at line 114 of file mjsonrpc.cxx.