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 4634 of file mjsonrpc.cxx.

◆ MethodsTableIterator

typedef MethodsTable::iterator MethodsTableIterator

Definition at line 4635 of file mjsonrpc.cxx.

◆ MhiMap

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

Definition at line 1693 of file mjsonrpc.cxx.

Function Documentation

◆ add()

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

Definition at line 5098 of file mjsonrpc.cxx.

5099{
5100 assert(s != NULL);
5101 if (s->length() > 0)
5102 *s += ", ";
5103 *s += text;
5104}
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 3421 of file mjsonrpc.cxx.

3422{
3423 if (!params) {
3424 MJSO* doc = MJSO::I();
3425 doc->D("make RPC call into frontend program via RPC_BRPC");
3426 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3427 doc->P("cmd", MJSON_STRING, "Command passed to client");
3428 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3429 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.");
3430 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3431 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3432 return doc;
3433 }
3434
3435 MJsonNode* error = NULL;
3436
3437 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3438 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3439 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3440 int max_reply_length = mjsonrpc_get_param(params, "max_reply_length", NULL)->GetInt();
3441
3442 int status;
3443
3444 int buf_length = 1024;
3445
3448
3449 char* buf = (char*)malloc(buf_length);
3450 buf[0] = 0;
3451
3452 HNDLE hconn;
3453
3454 status = cm_connect_client(name.c_str(), &hconn);
3455
3456 if (status != RPC_SUCCESS) {
3457 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3458 }
3459
3460 status = rpc_client_call(hconn, RPC_BRPC, cmd.c_str(), args.c_str(), buf, &buf_length);
3461
3462 // disconnect return status ignored on purpose.
3463 // disconnect not needed, there is no limit on number
3464 // of connections. dead and closed connections are reaped
3465 // automatically. K.O. Feb 2021.
3466 // cm_disconnect_client(hconn, FALSE);
3467
3468 if (status != RPC_SUCCESS) {
3469 free(buf);
3470 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3471 }
3472
3473 return MJsonNode::MakeArrayBuffer(buf, buf_length);
3474}
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:13472
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 3542 of file mjsonrpc.cxx.

3543{
3544 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3545 //size_t total_size = ALIGN8(event_size);
3547 assert(ptr);
3548 memcpy(ptr, pevent, event_size);
3549 return ptr;
3550}
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 3630 of file mjsonrpc.cxx.

3631{
3632 std::lock_guard<std::mutex> guard(gEventStashMutex);
3633 for (size_t i=0; i<gEventStash.size(); i++) {
3634 if (gEventStash[i]) {
3635 delete gEventStash[i];
3636 gEventStash[i] = NULL;
3637 }
3638 }
3639}
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:5461
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 3641 of file mjsonrpc.cxx.

3642{
3643 std::lock_guard<std::mutex> guard(gEventStashMutex);
3644 for (EventStashEntry* s : gEventStash) {
3645 if (s->buffer_name != buffer_name)
3646 continue;
3647 if (bm_match_event(event_id, trigger_mask, s->pevent)) {
3648 if (s->pevent->event_id == last_event_id
3649 && s->pevent->trigger_mask == last_trigger_mask
3650 && s->pevent->serial_number == last_serial_number
3651 && s->pevent->time_stamp == last_time_stamp) {
3652 //s->Print(); printf(", already sent for %d,0x%x\n", event_id, trigger_mask);
3653 return NULL;
3654 } else {
3655 //s->Print(); printf(", serving for %d,0x%x\n", event_id, trigger_mask);
3656 return CopyEvent(s->pevent);
3657 }
3658 }
3659 }
3660 return NULL;
3661}
INT bm_match_event(short int event_id, short int trigger_mask, const EVENT_HEADER *pevent)
Definition midas.cxx:6015
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 3849 of file mjsonrpc.cxx.

3850{
3851 if (!params) {
3852 MJSO* doc = MJSO::I();
3853 doc->D("get alarm data");
3854 doc->P("get_all?", MJSON_BOOL, "get all alarms, even in alarm system not active and alarms not triggered");
3855 doc->R("status", MJSON_INT, "return status of midas library calls");
3856 doc->R("alarm_system_active", MJSON_BOOL, "value of ODB \"/Alarms/alarm system active\"");
3857 doc->R("alarms", MJSON_OBJECT, "alarm data, keyed by alarm name");
3858 doc->R("alarms[].triggered", MJSON_BOOL, "alarm is triggered");
3859 doc->R("alarms[].active", MJSON_BOOL, "alarm is enabled");
3860 doc->R("alarms[].class", MJSON_STRING, "alarm class");
3861 doc->R("alarms[].type", MJSON_INT, "alarm type AT_xxx");
3862 doc->R("alarms[].bgcolor", MJSON_STRING, "display background color");
3863 doc->R("alarms[].fgcolor", MJSON_STRING, "display foreground color");
3864 doc->R("alarms[].message", MJSON_STRING, "alarm ODB message field");
3865 doc->R("alarms[].condition", MJSON_STRING, "alarm ODB condition field");
3866 doc->R("alarms[].evaluated_value?", MJSON_STRING, "evaluated alarm condition (AT_EVALUATED alarms only)");
3867 doc->R("alarms[].periodic_next_time?", MJSON_STRING, "next time the periodic alarm will fire (AT_PERIODIC alarms only)");
3868 doc->R("alarms[].time_triggered_first", MJSON_STRING, "time when alarm was triggered");
3869 doc->R("alarms[].show_to_user", MJSON_STRING, "final alarm text shown to user by mhttpd");
3870 return doc;
3871 }
3872
3873 //MJsonNode* error = NULL;
3874
3875 bool get_all = mjsonrpc_get_param(params, "get_all", NULL)->GetBool();
3876
3877 int status;
3878 HNDLE hDB;
3879
3881
3882 if (status != DB_SUCCESS) {
3883 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3884 }
3885
3886 int flag;
3887 int size;
3888 int alarm_system_active = 0;
3889
3890 /* check global alarm flag */
3891 flag = TRUE;
3892 size = sizeof(flag);
3893 status = db_get_value(hDB, 0, "/Alarms/Alarm System active", &flag, &size, TID_BOOL, TRUE);
3894
3895 if (status != DB_SUCCESS) {
3896 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3897 }
3898
3900
3902 if (!get_all) {
3903 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
3904 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
3905 "alarms", MJsonNode::MakeObject());
3906 }
3907
3908 /* go through all alarms */
3909 HNDLE hkey;
3910 status = db_find_key(hDB, 0, "/Alarms/Alarms", &hkey);
3911
3912 if (status != DB_SUCCESS) {
3913 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3914 }
3915
3916 MJsonNode* alarms = MJsonNode::MakeObject();
3917
3918 for (int i = 0;; i++) {
3919 HNDLE hsubkey;
3920 KEY key;
3921
3923
3924 if (!hsubkey)
3925 break;
3926
3928
3929 const char* name = key.name;
3930
3931 flag = 0;
3932 size = sizeof(flag);
3933 status = db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, TRUE);
3934
3935 // skip un-triggered alarms
3936 if (!flag)
3937 if (!get_all)
3938 continue;
3939
3940 MJsonNode* a = MJsonNode::MakeObject();
3941
3942 a->AddToObject("triggered", MJsonNode::MakeBool(flag!=0));
3943
3944 flag = 1;
3945 size = sizeof(BOOL);
3946 status = db_get_value(hDB, hsubkey, "Active", &flag, &size, TID_BOOL, TRUE);
3947
3948 a->AddToObject("active", MJsonNode::MakeBool(flag!=0));
3949
3950 char alarm_class[NAME_LENGTH];
3951 strcpy(alarm_class, "Alarm");
3952 size = sizeof(alarm_class);
3953 status = db_get_value(hDB, hsubkey, "Alarm Class", alarm_class, &size, TID_STRING, TRUE);
3954
3955 ss_repair_utf8(alarm_class);
3956 a->AddToObject("class", MJsonNode::MakeString(alarm_class));
3957
3958 int atype = 0;
3959 size = sizeof(atype);
3960 status = db_get_value(hDB, hsubkey, "Type", &atype, &size, TID_INT, TRUE);
3961
3962 a->AddToObject("type", MJsonNode::MakeInt(atype));
3963
3964 char str[256];
3965
3966 char bgcol[256];
3967 strcpy(bgcol, "red");
3968
3969 if (strlen(alarm_class) > 0) {
3970 sprintf(str, "/Alarms/Classes/%s/Display BGColor", alarm_class);
3971 size = sizeof(bgcol);
3972 status = db_get_value(hDB, 0, str, bgcol, &size, TID_STRING, TRUE);
3973 }
3974
3976 a->AddToObject("bgcolor", MJsonNode::MakeString(bgcol));
3977
3978 char fgcol[256];
3979 strcpy(fgcol, "black");
3980
3981 if (strlen(alarm_class) > 0) {
3982 sprintf(str, "/Alarms/Classes/%s/Display FGColor", alarm_class);
3983 size = sizeof(fgcol);
3984 status = db_get_value(hDB, 0, str, fgcol, &size, TID_STRING, TRUE);
3985 }
3986
3988 a->AddToObject("fgcolor", MJsonNode::MakeString(fgcol));
3989
3990 flag = 1;
3991 if (strlen(alarm_class) > 0) {
3992 size = sizeof(BOOL);
3993 sprintf(str, "/Alarms/Classes/%s/Alarm sound", alarm_class);
3994 status = db_get_value(hDB, 0, str, &flag, &size, TID_BOOL, TRUE);
3995 }
3996 a->AddToObject("alarm_sound", MJsonNode::MakeBool(flag!=0));
3997
3998 char msg[256];
3999 msg[0] = 0;
4000 size = sizeof(msg);
4001 status = db_get_value(hDB, hsubkey, "Alarm Message", msg, &size, TID_STRING, TRUE);
4002
4003 ss_repair_utf8(msg);
4004 a->AddToObject("message", MJsonNode::MakeString(msg));
4005
4006 char cond[256];
4007 cond[0] = 0;
4008 size = sizeof(cond);
4009 status = db_get_value(hDB, hsubkey, "Condition", cond, &size, TID_STRING, TRUE);
4010
4011 ss_repair_utf8(cond);
4012 a->AddToObject("condition", MJsonNode::MakeString(cond));
4013
4014 std::string show_to_user;
4015
4016 if (atype == AT_EVALUATED) {
4017 /* retrieve value */
4018 std::string value;
4020 show_to_user = msprintf(msg, value.c_str());
4022 a->AddToObject("evaluated_value", MJsonNode::MakeString(value.c_str()));
4023 } else
4024 show_to_user = msg;
4025
4027 a->AddToObject("show_to_user", MJsonNode::MakeString(show_to_user.c_str()));
4028
4029 str[0] = 0;
4030 size = sizeof(str);
4031 status = db_get_value(hDB, hsubkey, "Time triggered first", str, &size, TID_STRING, TRUE);
4032
4034 a->AddToObject("time_triggered_first", MJsonNode::MakeString(str));
4035
4036 if (atype == AT_PERIODIC) {
4037 DWORD last = 0;
4038 size = sizeof(last);
4039 db_get_value(hDB, hsubkey, "Checked last", &last, &size, TID_DWORD, TRUE);
4040
4041 if (last == 0) {
4042 last = ss_time();
4043 db_set_value(hDB, hsubkey, "Checked last", &last, size, 1, TID_DWORD);
4044 }
4045
4046 int interval = 0;
4047 size = sizeof(interval);
4048 db_get_value(hDB, hsubkey, "Check interval", &interval, &size, TID_INT, TRUE);
4049
4051
4052 char ctimebuf[32];
4054
4055 //ss_repair_utf8(ctimebuf); redundant!
4056 a->AddToObject("periodic_next_time", MJsonNode::MakeString(ctimebuf));
4057 }
4058
4059 alarms->AddToObject(name, a);
4060 }
4061
4062 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
4063 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
4064 "alarms", alarms);
4065}
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:8151
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:1445
#define TRUE
Definition midas.h:182
#define AT_EVALUATED
Definition midas.h:1444
#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 4505 of file mjsonrpc.cxx.

4506{
4507 if (!params) {
4508 MJSO *doc = MJSO::I();
4509 doc->D("get current value of mjsonrpc_debug");
4510 doc->P(NULL, 0, "there are no input parameters");
4511 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_debug");
4512 return doc;
4513 }
4514
4515 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4516}
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 4586 of file mjsonrpc.cxx.

4587{
4588 if (!params) {
4589 MJSO* doc = MJSO::I();
4590 doc->D("Get the MIDAS JSON-RPC schema JSON object");
4591 doc->P(NULL, 0, "there are no input parameters");
4592 doc->R(NULL, MJSON_OBJECT, "returns the MIDAS JSON-RPC schema JSON object");
4593 return doc;
4594 }
4595
4597}
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 4532 of file mjsonrpc.cxx.

4533{
4534 if (!params) {
4535 MJSO *doc = MJSO::I();
4536 doc->D("get current value of mjsonrpc_sleep");
4537 doc->P(NULL, 0, "there are no input parameters");
4538 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_sleep");
4539 return doc;
4540 }
4541
4542 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4543}
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 4559 of file mjsonrpc.cxx.

4560{
4561 if (!params) {
4562 MJSO *doc = MJSO::I();
4563 doc->D("get current value of mjsonrpc_time");
4564 doc->P(NULL, 0, "there are no input parameters");
4565 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_time");
4566 return doc;
4567 }
4568
4569 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4570}
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 1697 of file mjsonrpc.cxx.

1698{
1699 // empty name means use the default reader channel
1700
1701 MhiMap::iterator ci = gHistoryChannels.find(name);
1702 if (ci != gHistoryChannels.end()) {
1703 return ci->second;
1704 };
1705
1706 int verbose = 0;
1707
1708 HNDLE hDB;
1710
1711 HNDLE hKey = 0;
1712
1713 if (strlen(name) < 1) {
1715 if (status != HS_SUCCESS) {
1716 return NULL;
1717 }
1718 } else {
1720 int status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1721 if (status != DB_SUCCESS) {
1722 return NULL;
1723 }
1725 if (status != DB_SUCCESS) {
1726 return NULL;
1727 }
1728 }
1729
1731
1733 if (status != HS_SUCCESS || mh==NULL) {
1734 cm_msg(MERROR, "GetHistory", "Cannot configure history, hs_get_history() status %d", status);
1735 return NULL;
1736 }
1737
1738 //printf("hs_get_history: \"%s\" -> mh %p\n", name, mh);
1739
1741
1742 // cm_msg(MINFO, "GetHistory", "Reading history channel \"%s\" from channel \'%s\' type \'%s\'", name, mh->name, mh->type);
1743
1744 return mh;
1745}
#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 4792 of file mjsonrpc.cxx.

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

◆ jrpc()

static MJsonNode * jrpc ( const MJsonNode *  params)
static

Definition at line 3356 of file mjsonrpc.cxx.

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

1588{
1589 if (!params) {
1590 MJSO* doc = MJSO::I();
1591 doc->D("reset alarms");
1592 doc->P("alarms[]", MJSON_STRING, "array of alarm names");
1593 doc->R("status[]", MJSON_INT, "return status of al_reset_alarm() for each alarm");
1594 return doc;
1595 }
1596
1597 MJsonNode* error = NULL;
1598
1599 const MJsonNodeVector* alarms = mjsonrpc_get_param_array(params, "alarms", &error); if (error) return error;
1600
1601 MJsonNode* sresult = MJsonNode::MakeArray();
1602
1603 for (unsigned i=0; i<alarms->size(); i++) {
1604 int status = al_reset_alarm((*alarms)[i]->GetString().c_str());
1605 sresult->AddToArray(MJsonNode::MakeInt(status));
1606 }
1607
1608 return mjsonrpc_make_result("status", sresult);
1609}
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 1611 of file mjsonrpc.cxx.

1612{
1613 if (!params) {
1614 MJSO* doc = MJSO::I();
1615 doc->D("trigger an alarm");
1616 doc->P("name", MJSON_STRING, "alarm name");
1617 doc->P("message", MJSON_STRING, "alarm message");
1618 doc->P("class", MJSON_STRING, "alarm class");
1619 doc->P("condition", MJSON_STRING, "alarm condition");
1620 doc->P("type", MJSON_INT, "alarm type (AT_xxx)");
1621 doc->R("status", MJSON_INT, "return status of al_trigger_alarm()");
1622 return doc;
1623 }
1624
1625 MJsonNode* error = NULL;
1626
1627 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString(); if (error) return error;
1628 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1629 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1630 std::string condition = mjsonrpc_get_param(params, "condition", &error)->GetString(); if (error) return error;
1631 int type = mjsonrpc_get_param(params, "type", &error)->GetInt(); if (error) return error;
1632
1633 int status = al_trigger_alarm(name.c_str(), message.c_str(), xclass.c_str(), condition.c_str(), type);
1634
1635 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1636}
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 1638 of file mjsonrpc.cxx.

1639{
1640 if (!params) {
1641 MJSO* doc = MJSO::I();
1642 doc->D("trigger an alarm");
1643 doc->P("class", MJSON_STRING, "alarm class");
1644 doc->P("message", MJSON_STRING, "alarm message");
1645 doc->P("first?", MJSON_BOOL, "see al_trigger_class() in midas.c");
1646 doc->R("status", MJSON_INT, "return status of al_trigger_class()");
1647 return doc;
1648 }
1649
1650 MJsonNode* error = NULL;
1651
1652 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1653 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1654 bool first = mjsonrpc_get_param(params, "first", NULL)->GetBool();
1655
1656 int status = al_trigger_class(xclass.c_str(), message.c_str(), first);
1657
1658 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1659}
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 3663 of file mjsonrpc.cxx.

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

1509{
1510 if (!params) {
1511 MJSO *doc = MJSO::I();
1512 doc->D("Generate a midas message using cm_msg1()");
1513 doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
1514 doc->P("user?", MJSON_STRING, "message user, default is \"javascript_commands\"");
1515 doc->P("type?", MJSON_INT, "message type, MT_xxx from midas.h, default is MT_INFO");
1516 doc->P("message", MJSON_STRING, "message text");
1517 doc->R("status", MJSON_INT, "return status of cm_msg1()");
1518 return doc;
1519 }
1520
1521 MJsonNode* error = NULL;
1522
1523 std::string facility = mjsonrpc_get_param(params, "facility", &error)->GetString();
1524 std::string user = mjsonrpc_get_param(params, "user", &error)->GetString();
1525 int type = mjsonrpc_get_param(params, "type", &error)->GetInt();
1526 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1527
1528 if (facility.size() <1)
1529 facility = "midas";
1530 if (user.size()<1)
1531 user = "javascript_commands";
1532 if (type == 0)
1533 type = MT_INFO;
1534
1535 int status = cm_msg1(type, __FILE__, __LINE__, facility.c_str(), user.c_str(), "%s", message.c_str());
1536
1537 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1538}
#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 1483 of file mjsonrpc.cxx.

1484{
1485 if (!params) {
1486 MJSO* doc = MJSO::I();
1487 doc->D("get message facilities using cm_msg_facilities()");
1488 doc->R("status", MJSON_INT, "return status of cm_msg_facilities()");
1489 doc->R("facilities[]", MJSON_STRING, "array of facility names");
1490 return doc;
1491 }
1492
1494
1496
1497 MJsonNode* facilities = MJsonNode::MakeArray();
1498
1499 for (unsigned i=0; i<list.size(); i++) {
1501 facilities->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1502 }
1503
1504 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status),
1505 "facilities", facilities);
1506}
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 1540 of file mjsonrpc.cxx.

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

3483{
3484 if (!params) {
3485 MJSO* doc = MJSO::I();
3486 doc->D("start and stop runs");
3487 doc->P("transition", MJSON_STRING, "requested transition: TR_START, TR_STOP, TR_PAUSE, TR_RESUME");
3488 doc->P("run_number?", MJSON_INT, "New run number, value 0 means /runinfo/run_number + 1, default is 0");
3489 doc->P("async_flag?", MJSON_INT, "Transition type. Default is multithreaded transition TR_MTHREAD");
3490 doc->P("debug_flag?", MJSON_INT, "See cm_transition(), value 1: trace to stdout, value 2: trace to midas.log");
3491 doc->R("status", MJSON_INT, "return status of cm_transition()");
3492 doc->R("error_string?", MJSON_STRING, "return error string from cm_transition()");
3493 return doc;
3494 }
3495
3496 MJsonNode* error = NULL;
3497
3498 std::string xtransition = mjsonrpc_get_param(params, "transition", &error)->GetString(); if (error) return error;
3499 int run_number = mjsonrpc_get_param(params, "run_number", NULL)->GetInt();
3500 int async_flag = mjsonrpc_get_param(params, "async_flag", NULL)->GetInt();
3501 int debug_flag = mjsonrpc_get_param(params, "debug_flag", NULL)->GetInt();
3502
3503 int status;
3504
3505 int transition = 0;
3506
3507 if (xtransition == "TR_START")
3509 else if (xtransition == "TR_STOP")
3511 else if (xtransition == "TR_PAUSE")
3513 else if (xtransition == "TR_RESUME")
3515 else {
3516 return mjsonrpc_make_error(15, "invalid value of \"transition\"", xtransition.c_str());
3517 }
3518
3519 if (async_flag == 0)
3520 async_flag = TR_MTHREAD;
3521
3522 char error_str[1024];
3523
3524 status = cm_transition(transition, run_number, error_str, sizeof(error_str), async_flag, debug_flag);
3525
3526 MJsonNode* result = MJsonNode::MakeObject();
3527
3528 result->AddToObject("status", MJsonNode::MakeInt(status));
3529 if (strlen(error_str) > 0) {
3531 result->AddToObject("error_string", MJsonNode::MakeString(error_str));
3532 }
3533 return mjsonrpc_make_result(result);
3534}
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:5286
#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 return mjsonrpc_make_error(-32602, "Invalid params", "parameters must be an array of objects");
1050 }
1051
1052 HNDLE hDB;
1054
1055 for (unsigned i=0; i<pp->size(); i++) {
1056 const MJsonNode* p = (*pp)[i];
1057 std::string path = mjsonrpc_get_param(p, "path", NULL)->GetString();
1058 int type = mjsonrpc_get_param(p, "type", NULL)->GetInt();
1059 int array_length = mjsonrpc_get_param(p, "array_length", NULL)->GetInt();
1060 int string_length = mjsonrpc_get_param(p, "string_length", NULL)->GetInt();
1061
1062 //printf("create odb [%s], type %d, array %d, string %d\n", path.c_str(), type, array_length, string_length);
1063
1064 if (string_length == 0)
1066
1067 int status = db_create_key(hDB, 0, path.c_str(), type);
1068
1069 if (status == DB_SUCCESS && string_length > 0 && type == TID_STRING) {
1070 HNDLE hKey;
1071 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1072 if (status == DB_SUCCESS) {
1073 char* buf = (char*)calloc(1, string_length);
1074 assert(buf != NULL);
1075 int size = string_length;
1076 status = db_set_data(hDB, hKey, buf, size, 1, TID_STRING);
1077 free(buf);
1078 }
1079 }
1080
1081 if (status == DB_SUCCESS && array_length > 1) {
1082 HNDLE hKey;
1083 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1084 if (status == DB_SUCCESS)
1086 }
1087
1088 sresult->AddToArray(MJsonNode::MakeInt(status));
1089 }
1090
1091 return mjsonrpc_make_result("status", sresult);
1092}
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 1094 of file mjsonrpc.cxx.

1095{
1096 if (!params) {
1097 MJSO* doc = MJSO::I();
1098 doc->D("delete ODB keys");
1099 doc->P("paths[]", MJSON_STRING, "array of ODB paths to delete");
1100 doc->R("status[]", MJSON_INT, "return status of db_delete_key() for each path");
1101 return doc;
1102 }
1103
1104 MJsonNode* error = NULL;
1105
1106 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1107
1108 MJsonNode* sresult = MJsonNode::MakeArray();
1109
1110 HNDLE hDB;
1112
1113 for (unsigned i=0; i<paths->size(); i++) {
1114 int status = 0;
1115 HNDLE hkey;
1116 std::string path = (*paths)[i]->GetString();
1117
1118 status = db_find_link(hDB, 0, path.c_str(), &hkey);
1119 if (status != DB_SUCCESS) {
1120 sresult->AddToArray(MJsonNode::MakeInt(status));
1121 continue;
1122 }
1123
1124 status = db_delete_key(hDB, hkey, false);
1125 sresult->AddToArray(MJsonNode::MakeInt(status));
1126 }
1127
1128 return mjsonrpc_make_result("status", sresult);
1129}
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 1233 of file mjsonrpc.cxx.

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

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

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

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

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

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

1461{
1462 if (!params) {
1463 MJSO* doc = MJSO::I();
1464 doc->D("Show ODB clients");
1465 doc->R("scl", MJSON_JSON, "return value of db_scl()");
1466 return doc;
1467 }
1468
1469 HNDLE hDB;
1471
1472 MJsonNode* scl = db_scl(hDB);
1473
1474 return mjsonrpc_make_result("scl", scl);
1475}
MJsonNode * db_scl(HNDLE hDB)
Definition odb.cxx:14111
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 1438 of file mjsonrpc.cxx.

1439{
1440 if (!params) {
1441 MJSO* doc = MJSO::I();
1442 doc->D("Show ODB open records starting from given ODB path");
1443 doc->P("path?", MJSON_STRING, "ODB path");
1444 doc->R("sor", MJSON_JSON, "return value of db_sor()");
1445 return doc;
1446 }
1447
1448 MJsonNode* error = NULL;
1449
1450 std::string path = mjsonrpc_get_param(params, "path", NULL)->GetString(); if (error) return error;
1451
1452 HNDLE hDB;
1454
1455 MJsonNode* sor = db_sor(hDB, path.c_str());
1456
1457 return mjsonrpc_make_result("sor", sor);
1458}
MJsonNode * db_sor(HNDLE hDB, const char *root_path)
Definition odb.cxx:14161
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 3333 of file mjsonrpc.cxx.

3334{
3335 if (!params) {
3336 MJSO* doc = MJSO::I();
3337 doc->D("Delete elog message");
3338 doc->P("tag", MJSON_STRING, "tag of message to delete");
3339 doc->R("status", MJSON_INT, "return status of el_delete");
3340 return doc;
3341 }
3342
3343 MJsonNode* error = NULL;
3344 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
3345 int status = el_delete_message(tag.c_str());
3346 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3347}
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 3058 of file mjsonrpc.cxx.

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

2993{
2994 if (!params) {
2995 MJSO* doc = MJSO::I();
2996 doc->D("Get an elog message");
2997 doc->P("tag", MJSON_STRING, "elog message tag");
2998 doc->R("status", MJSON_INT, "return status of el_retrieve");
2999 doc->R("msg.tag", MJSON_STRING, "message tag");
3000 return doc;
3001 }
3002
3003 MJsonNode* error = NULL;
3004
3005 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
3006
3007 int run = 0;
3008 char date[80], author[80], type[80], system[80], subject[256], text[10000];
3009 char orig_tag[80], reply_tag[80], attachment[3][256], encoding[80];
3010
3011 char xtag[80];
3012 mstrlcpy(xtag, tag.c_str(), sizeof(xtag));
3013
3014 int size = sizeof(text);
3015
3016 int status = el_retrieve(xtag,
3017 date, &run, author, type, system, subject,
3018 text, &size, orig_tag, reply_tag,
3020
3021 //printf("js_el_retrieve: size %d, status %d, tag [%s]\n", size, status, xtag);
3022
3023 MJsonNode* msg = MJsonNode::MakeObject();
3024
3025 if (status == EL_SUCCESS) {
3027 msg->AddToObject("tag", MJsonNode::MakeString(xtag));
3029 msg->AddToObject("date", MJsonNode::MakeString(date));
3030 msg->AddToObject("run", MJsonNode::MakeInt(run));
3031 ss_repair_utf8(author);
3032 msg->AddToObject("author", MJsonNode::MakeString(author));
3034 msg->AddToObject("type", MJsonNode::MakeString(type));
3036 msg->AddToObject("system", MJsonNode::MakeString(system));
3038 msg->AddToObject("subject", MJsonNode::MakeString(subject));
3039 ss_repair_utf8(text);
3040 msg->AddToObject("text", MJsonNode::MakeString(text));
3042 msg->AddToObject("orig_tag", MJsonNode::MakeString(orig_tag));
3044 msg->AddToObject("reply_tag", MJsonNode::MakeString(reply_tag));
3046 msg->AddToObject("attachment0", MJsonNode::MakeString(attachment[0]));
3048 msg->AddToObject("attachment1", MJsonNode::MakeString(attachment[1]));
3050 msg->AddToObject("attachment2", MJsonNode::MakeString(attachment[2]));
3052 msg->AddToObject("encoding", MJsonNode::MakeString(encoding));
3053 }
3054
3055 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "msg", msg);
3056}
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 4139 of file mjsonrpc.cxx.

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

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

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

4600{
4601 if (!params) {
4602 MJSO *doc = MJSO::I();
4603 doc->D("get current server timezone offset in seconds");
4604 doc->P(NULL, 0, "there are no input parameters");
4605 doc->R(NULL, MJSON_INT, "offset in seconds");
4606 return doc;
4607 }
4608
4609 ss_tzset(); // required for localtime_r()
4610 time_t rawtime = time(NULL);
4611 struct tm gmt_tms;
4614 struct tm tms;
4616 time_t offset = rawtime - gmt + (tms.tm_isdst ? 3600 : 0);
4617
4618 return mjsonrpc_make_result(MJsonNode::MakeNumber(offset));
4619}
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 1747 of file mjsonrpc.cxx.

1748{
1749 for (auto& e : gHistoryChannels) {
1750 //printf("history channel \"%s\" mh %p\n", e.first.c_str(), e.second);
1751 delete e.second;
1752 }
1753 gHistoryChannels.clear();
1754}
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 1669 of file mjsonrpc.cxx.

1670{
1671 if (!params) {
1672 MJSO* doc = MJSO::I();
1673 doc->D("get list of active history events using hs_read_event_list()");
1674 doc->R("status", MJSON_INT, "return status of hs_read_event_list()");
1675 doc->R("events[]", MJSON_STRING, "array of history event names");
1676 return doc;
1677 }
1678
1680
1682
1683 MJsonNode* events = MJsonNode::MakeArray();
1684
1685 for (unsigned i=0; i<list.size(); i++) {
1687 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1688 }
1689
1690 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1691}
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 1756 of file mjsonrpc.cxx.

1757{
1758 if (!params) {
1759 MJSO* doc = MJSO::I();
1760 doc->D("get list of history channels in /Logger/History");
1761 doc->R("status", MJSON_INT, "return success or failure status");
1762 doc->R("default_channel", MJSON_STRING, "name of the default logger history channel");
1763 doc->R("channels[]", MJSON_STRING, "all logger history channel names");
1764 doc->R("active_channels[]", MJSON_STRING, "active logger history channel names");
1765 return doc;
1766 }
1767
1768 MJsonNode* channels = MJsonNode::MakeArray();
1769 MJsonNode* active_channels = MJsonNode::MakeArray();
1770
1771 HNDLE hDB;
1773
1774 // get history channel name selected by user in ODB
1775
1776 //std::string selected_channel;
1777 //db_get_value_string(hDB, 0, "/History/LoggerHistoryChannel", 0, &selected_channel, TRUE);
1778
1779 int status;
1781
1782 status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1783 if (status == DB_SUCCESS) {
1784 for (int ichan=0; ; ichan++) {
1785 HNDLE hKey;
1787 if (status == DB_NO_MORE_SUBKEYS) {
1789 break;
1790 }
1791 if (status != DB_SUCCESS)
1792 break;
1793
1794 KEY key;
1795
1797
1798 if (status == DB_SUCCESS) {
1800 channels->AddToArray(MJsonNode::MakeString(key.name));
1801
1802 INT active = 0;
1803 INT size = sizeof(active);
1804 status = db_get_value(hDB, hKey, "Active", &active, &size, TID_BOOL, FALSE);
1805 if (status == DB_SUCCESS) {
1806 if (active) {
1807 active_channels->AddToArray(MJsonNode::MakeString(key.name));
1808 }
1809 }
1810 }
1811 }
1812 }
1813
1814 std::string default_channel;
1815
1816 HNDLE hKey;
1818 if (status == DB_SUCCESS) {
1819 KEY key;
1821 if (status == DB_SUCCESS) {
1823 }
1824 }
1825
1826 return mjsonrpc_make_result("status", MJsonNode::MakeInt(1),
1827 //"selected_channel", MJsonNode::MakeString(selected_channel.c_str()),
1828 "default_channel", MJsonNode::MakeString(default_channel.c_str()),
1829 "active_channels", active_channels,
1830 "channels", channels);
1831}
#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 1833 of file mjsonrpc.cxx.

1834{
1835 if (!params) {
1836 MJSO* doc = MJSO::I();
1837 doc->D("get list of history events that existed at give time using hs_get_events()");
1838 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1839 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1840 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1841 doc->R("channel", MJSON_STRING, "logger history channel name");
1842 doc->R("events[]", MJSON_STRING, "array of history event names");
1843 return doc;
1844 }
1845
1846 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1847 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1848
1850
1851 MJsonNode* events = MJsonNode::MakeArray();
1852
1853 if (!mh) {
1854 int status = HS_FILE_ERROR;
1855 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1856 }
1857
1858 if (time == 0) {
1859 time = ::time(NULL);
1860 }
1861
1863
1864 int status = mh->hs_get_events(time, &list);
1865
1866 for (unsigned i=0; i<list.size(); i++) {
1868 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1869 }
1870
1871 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "events", events);
1872}
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 1977 of file mjsonrpc.cxx.

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

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

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

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

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

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

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

1875{
1876 if (!params) {
1877 MJSO* doc = MJSO::I();
1878 doc->D("reopen the history channel to make sure we see the latest list of events using hs_clear_cache()");
1879 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1880 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1881 doc->R("channel", MJSON_STRING, "logger history channel name");
1882 return doc;
1883 }
1884
1885 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1886
1888
1889 if (!mh) {
1890 int status = HS_FILE_ERROR;
1891 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1892 }
1893
1894 int status = mh->hs_clear_cache();
1895
1896 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name));
1897}
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 4073 of file mjsonrpc.cxx.

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

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

3831{
3832 if (!params) {
3833 MJSO *doc = MJSO::I();
3834 doc->D("get current MIDAS time using ss_millitime()");
3835 doc->P(NULL, 0, "there are no input parameters");
3836 doc->R(NULL, MJSON_INT, "current value of ss_millitime()");
3837 return doc;
3838 }
3839
3840 return mjsonrpc_make_result(MJsonNode::MakeNumber(ss_millitime()));
3841}
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 3617 of file mjsonrpc.cxx.

3618{
3619 std::lock_guard<std::mutex> guard(gEventStashMutex);
3620 for (EventStashEntry* s : gEventStash) {
3621 if (s->buffer_name != buffer_name)
3622 continue;
3623 if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3624 s->ReplaceEvent(pevent);
3625 //s->Print(); printf(", matched\n");
3626 }
3627 }
3628}
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 5106 of file mjsonrpc.cxx.

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

4748{
4749 MJsonNode* s = MJsonNode::MakeObject();
4750
4751 s->AddToObject("$schema", MJsonNode::MakeString("http://json-schema.org/schema#"));
4752 s->AddToObject("id", MJsonNode::MakeString("MIDAS JSON-RPC autogenerated schema"));
4753 s->AddToObject("title", MJsonNode::MakeString("MIDAS JSON-RPC schema"));
4754 s->AddToObject("description", MJsonNode::MakeString("Autogenerated schema for all MIDAS JSON-RPC methods"));
4755 s->AddToObject("type", MJsonNode::MakeString("object"));
4756
4757 MJsonNode* m = MJsonNode::MakeObject();
4758
4759 for (MethodsTableIterator iterator = h->begin(); iterator != h->end(); iterator++) {
4760 // iterator->first = key
4761 // iterator->second = value
4762 //printf("build schema for method \"%s\"!\n", iterator->first.c_str());
4763 MJsonNode* doc = iterator->second.fHandler(NULL);
4764 if (doc == NULL)
4765 doc = MJsonNode::MakeObject();
4766 m->AddToObject(iterator->first.c_str(), doc);
4767 }
4768
4769 s->AddToObject("properties", m);
4770 s->AddToObject("required", MJsonNode::MakeArray());
4771
4772 return s;
4773}
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 5046 of file mjsonrpc.cxx.

5047{
5048 std::string type;
5049 std::string description;
5050 //bool optional = false;
5051
5052 const MJsonNode* t = schema->FindObjectNode("type");
5053 if (t)
5054 type = t->GetString();
5055 else
5056 type = "any";
5057
5058 const MJsonNode* d = schema->FindObjectNode("description");
5059 if (d)
5060 description = d->GetString();
5061
5062 //const MJsonNode* o = schema->FindObjectNode("optional");
5063 //if (o)
5064 // optional = o->GetBool();
5065
5066 if (type == "object") {
5068 } else if (type == "array") {
5070 } else {
5071 //if (optional)
5072 // output(nest_level, false, "?");
5073 //else
5074 // output(nest_level, false, "!");
5075 o->Output(nest_level, false, type);
5076 o->Output(nest_level+1, true, description);
5077 if (description.length() > 1) {
5078 return (type + "</td><td>" + description);
5079 } else {
5080 return (type);
5081 }
5082 }
5083}
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 4990 of file mjsonrpc.cxx.

4991{
4992 const MJsonNode* d = schema->FindObjectNode("description");
4993 std::string description;
4994 if (d)
4995 description = d->GetString();
4996
4997 std::string xshort = "array";
4998 if (description.length() > 1)
4999 xshort += "</td><td>" + description;
5000
5001 const MJsonNode* items = schema->FindObjectNode("items");
5002
5003 if (!items) {
5004 o->Output(nest_level, false, "array");
5005 o->Output(nest_level+1, true, description);
5006 return xshort;
5007 }
5008
5009 const MJsonNodeVector *nodes = items->GetArray();
5010
5011 if (!nodes) {
5012 o->Output(nest_level, false, "array");
5013 o->Output(nest_level+1, true, description);
5014 return xshort;
5015 }
5016
5017 std::string nest = indent(nest_level * 4);
5018
5019 std::string s;
5020
5021 //s += "array</td><td>";
5022
5023 s += nest + "<table border=1>\n";
5024
5025 if (description.length() > 1) {
5026 s += nest + "<tr>\n";
5027 s += nest + " <td>" + description + "</td>\n";
5028 s += nest + "</tr>\n";
5029 }
5030
5031 o->Output(nest_level, true, description);
5032
5033 for (unsigned i=0; i<nodes->size(); i++) {
5034 o->Output(nest_level, false, "array of");
5035
5036 s += nest + "<tr>\n";
5037 s += nest + " <td> array of " + mjsonrpc_schema_to_html_anything((*nodes)[i], nest_level + 1, o) + "</td>\n";
5038 s += nest + "</tr>\n";
5039 }
5040
5041 s += nest + "</table>\n";
5042
5043 return s;
5044}
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 4904 of file mjsonrpc.cxx.

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

4519{
4520 if (!params) {
4521 MJSO* doc = MJSO::I();
4522 doc->D("set new value of mjsonrpc_debug");
4523 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4524 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4525 return doc;
4526 }
4527
4528 mjsonrpc_debug = params->GetInt();
4529 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4530}
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 4545 of file mjsonrpc.cxx.

4546{
4547 if (!params) {
4548 MJSO* doc = MJSO::I();
4549 doc->D("set new value of mjsonrpc_sleep");
4550 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4551 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4552 return doc;
4553 }
4554
4555 mjsonrpc_sleep = params->GetInt();
4556 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4557}
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 4572 of file mjsonrpc.cxx.

4573{
4574 if (!params) {
4575 MJSO* doc = MJSO::I();
4576 doc->D("set new value of mjsonrpc_time");
4577 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_time");
4578 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_time");
4579 return doc;
4580 }
4581
4582 mjsonrpc_time = params->GetInt();
4583 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4584}
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 3590 of file mjsonrpc.cxx.

3591{
3592 std::lock_guard<std::mutex> guard(gEventStashMutex);
3593 bool found = false;
3594 for (EventStashEntry* s : gEventStash) {
3595 if (s->buffer_name != buffer_name)
3596 continue;
3597 if (s->event_id == event_id && s->trigger_mask == trigger_mask) {
3598 found = true;
3599 s->ReplaceEvent(pevent);
3600 //s->Print(); printf(", replaced\n");
3601 } else if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3602 s->ReplaceEvent(pevent);
3603 //s->Print(); printf(", matched\n");
3604 }
3605 }
3606 if (!found) {
3609 s->event_id = event_id;
3611 s->pevent = CopyEvent(pevent);
3612 //s->Print(); printf(", added\n");
3613 gEventStash.push_back(s);
3614 }
3615}
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 3588 of file mjsonrpc.cxx.

◆ gEventStashMutex

std::mutex gEventStashMutex
static

Definition at line 3587 of file mjsonrpc.cxx.

◆ gHistoryChannels

MhiMap gHistoryChannels
static

Definition at line 1695 of file mjsonrpc.cxx.

◆ gMethodsTable

MethodsTable gMethodsTable
static

Definition at line 4637 of file mjsonrpc.cxx.

◆ gMutex

std::mutex* gMutex = NULL
static

Definition at line 4638 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.