📄 nml.cc
字号:
/********************************************************************* Description: nml.cc* C++ file for the Neutral Manufacturing Language (NML).** Derived from a work by Fred Proctor & Will Shackleford** Author:* License: LGPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.12 $* $Author: paul_c $* $Date: 2005/06/13 14:38:50 $********************************************************************/#include "rcsversion.h"#ifdef __cplusplusextern "C" {#endif#include <string.h> /* memcpy() */#include <stdlib.h> /* atexit() */#include <sys/param.h> // MAXHOSTNAMELEN#include <netdb.h>#include <arpa/inet.h> /* inet_ntoa */#ifdef __cplusplus}#endif#include "nml.hh" /* class NML */#include "nmlmsg.hh" /* class NMLmsg */#include "cms.hh" /* class CMS */#include "timer.hh" // esleep()#include "nml_srv.hh" /* NML_Default_Super_Server */#include "cms_cfg.hh" /* cms_config(), cms_copy() */#include "linklist.hh" /* class LinkedList */#include "rcs_print.hh" /* rcs_print_error() */#ifndef MAXHOSTNAMELEN#define MAXHOSTNAMELEN 64#endif#include "nmldiag.hh" // NML_DIAGNOSTICS_INFO/* Pointer to a global list of NML channels. */LinkedList *NML_Main_Channel_List = (LinkedList *) NULL;LinkedList *Dynamically_Allocated_NML_Objects = (LinkedList *) NULL;int nml_print_hostname_on_error = 0;int verbose_nml_error_messages = 1;char NML_ERROR_TYPE_STRINGS[8][80] = { "NML_NO_ERROR", "NML_BUFFER_NOT_READ", "NML_TIMED_OUT", "NML_INVALID_CONFIGURATION", "NML_FORMAT_ERROR", "NML_INTERNAL_CMS_ERROR", "NML_NO_MASTER_ERROR", "NML_INVALID_MESSAGE_ERROR",};static char *default_nml_config_file = NULL;int nml_reset_errors_printed = 1;void set_default_nml_config_file(const char *cfg_file){ if (cfg_file == NULL) { default_nml_config_file = NULL; } default_nml_config_file = (char *) malloc(strlen(cfg_file) + 1); strcpy(default_nml_config_file, cfg_file);}const char *get_default_nml_config_file(){ return default_nml_config_file;}/** NML Member Functions*//* Special new operator to allow the nml_cleanup function todistinguish between dynamically and statically allocated NMLobjects. */void *NML::operator new(size_t size){ if (size < sizeof(NML)) { rcs_print_error ("void *NML::operator new() called with size (%d) < sizeof(NML) (%d) the code calling NML was probably not compiled with the correct header file version.\n", size, sizeof(NML)); size = sizeof(NML); } void *nml_space = NULL; char *cptr = (char *) NULL; int dynamic_list_id = 0; nml_space = malloc(size + sizeof(int) * 2); if (NULL != nml_space) { memset(nml_space, 0, size); } if (NULL == Dynamically_Allocated_NML_Objects) { Dynamically_Allocated_NML_Objects = new LinkedList(); } if (NULL != Dynamically_Allocated_NML_Objects) { dynamic_list_id = Dynamically_Allocated_NML_Objects->store_at_tail(nml_space, sizeof(NML), 0); cptr = ((char *) nml_space) + sizeof(NML); // guarantee alignment cptr += sizeof(int) - (((int) cptr) % sizeof(int)); *((int *) cptr) = dynamic_list_id; } rcs_print_debug(PRINT_NML_CONSTRUCTORS, "%X = NML::operater new(%d)\n", nml_space, size); return nml_space;}void NML::operator delete(void *nml_space){ int dynamic_list_id = 0; char *cptr = (char *) NULL; rcs_print_debug(PRINT_NML_DESTRUCTORS, "NML::operater delete(%X)\n", nml_space); if (NULL == nml_space) { return; } if (NULL != Dynamically_Allocated_NML_Objects) { cptr = ((char *) nml_space) + sizeof(NML); cptr += sizeof(int) - (((int) cptr) % sizeof(int)); dynamic_list_id = *((int *) cptr); Dynamically_Allocated_NML_Objects->delete_node(dynamic_list_id); if (Dynamically_Allocated_NML_Objects->list_size == 0) { delete Dynamically_Allocated_NML_Objects; Dynamically_Allocated_NML_Objects = (LinkedList *) NULL; } } free(nml_space);}/******************************************************************* Constructor for NML:* Parameters:* NML_FORMAT_PTR f_ptr - address of the function to be used to format messages.* char *buf - Name of the buffer to connect to as written in the config file.* char *proc - Name of the calling process as expected in the config file.* char *file - Name of the configuration file.* int set_to_server - If 1 this NML will consider its calling process to* be an NML_SERVER, which effects how and when messages are encoded and* decoded.* int set_to_master - Passed to the CMS constructor - how this is used* depends on the type of CMS buffer. In general the master is responsible* for creating/initializing the buffer. If set_to_master == 1 then this* process will be considered the master, if set_to_master == 0 then* the the configuration file determines if this is the master, and it* set_to_master == -1 then this will not be the master.* NOTES:* 1. Borland C++(for DOS and Windows) does not allow default* parameters to be specified both here and in the header file.* 2. All pointers are first initialized to NULL so that it can be determined* later if the constructor returned before creating the objects* the pointers are intended to point at.******************************************************************/NML::NML(NML_FORMAT_PTR f_ptr, char *buf, char *proc, char *file, int set_to_server, int set_to_master){ registered_with_server = 0; cms_for_msg_string_conversions = 0; info_printed = 0; blocking_read_poll_interval = -1.0; forced_type = 0; strncpy(bufname, buf, 40); strncpy(procname, proc, 40); if (NULL == file) { file = default_nml_config_file; } strncpy(cfgfilename, file, 160); if (rcs_errors_printed >= max_rcs_errors_to_print && max_rcs_errors_to_print > 0 && nml_reset_errors_printed) { rcs_errors_printed = 0; rcs_print ("\nResetting rcs_errors_printed because a new NML channel is being created.\n"); } already_deleted = 0; channel_type = NML_GENERIC_CHANNEL_TYPE; reconstruct(f_ptr, buf, proc, file, set_to_server, set_to_master); if (NULL != cms) { char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = 0; temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } }}int NML::login(const char *name, const char *passwd){ if (NULL == cms) { return 1; } return cms->login(name, passwd);}void NML::reconstruct(NML_FORMAT_PTR f_ptr, char *buf, char *proc, char *file, int set_to_server, int set_to_master){ cms = (CMS *) NULL; format_chain = (LinkedList *) NULL; phantom_read = (NMLTYPE(*)())NULL; phantom_peek = (NMLTYPE(*)())NULL; phantom_write = (int (*)(NMLmsg *)) NULL; phantom_write_if_read = (int (*)(NMLmsg *)) NULL; phantom_check_if_read = (int (*)()) NULL; phantom_clear = (int (*)()) NULL; channel_list_id = 0; error_type = NML_NO_ERROR; fast_mode = 0; ignore_format_chain = 0; info_printed = 0; format_chain = new LinkedList; if (NULL != format_chain) { prefix_format_chain(f_ptr); } if (NULL == f_ptr) { rcs_print_error("NML:(Format Function Pointer) f_ptr == NULL.\n"); } if (-1 == cms_config(&cms, buf, proc, file, set_to_server, set_to_master)) { set_error(); if (!info_printed) { print_info(buf, proc, file); } if (NULL != cms) { rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; } return; } if (NULL == cms) { if (!info_printed) { print_info(buf, proc, file); } error_type = NML_INVALID_CONFIGURATION; return; } if (cms->status < 0) { error_type = NML_INVALID_CONFIGURATION; if (!info_printed) { print_info(buf, proc, file); } rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; return; } if (!set_to_server) { register_with_server(); } add_to_channel_list(); // FAST MODE is a combination of options which allow certian checks // during // a read or write operation to be avoided and therefore reduce the // NML/CMS // overhead. if (!cms->is_phantom && cms->ProcessType == CMS_LOCAL_TYPE && !cms->neutral && !cms->isserver && !cms->enable_diagnostics) { fast_mode = 1; } cms_status = (int *) &(cms->status); cms_inbuffer_header_size = &(cms->header.in_buffer_size); char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = 0; temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } char *brpi_eq = strstr(cms->buflineupper, "BRPI="); if (brpi_eq != NULL) { blocking_read_poll_interval = strtod(brpi_eq + 5, NULL); }}/******************************************************************* Constructor for NML:* Parameters:* char *buf - Name of the buffer to connect to as written in the config file.* char *proc - Name of the calling process as expected in the config file.* char *file - Name of the configuration file.* int set_to_server - If 1 this NML will consider its calling process to* be an NML_SERVER, which effects how and when messages are encoded and* decoded.* int set_to_master - Passed to the CMS constructor - how this is used* depends on the type of CMS buffer. In general the master is responsible* for creating/initializing the buffer. If set_to_master == 1 then this* process will be considered the master, if set_to_master == 0 then* the the configuration file determines if this is the master, and it* set_to_master == -1 then this will not be the master.* NOTES:* 1. Borland C++(for DOS and Windows) does not allow default* parameters to be specified both here and in the header file.* 2. All pointers are first initialized to NULL so that it can be determined* later if the constructor returned before creating the objects* the pointers are intended to point at.* 3. This constructor does not register itself with the default server.* 4. The NML object created by this constructor can not be used until* the format_chain is constructed. (This may be done by* derived classes. )******************************************************************/NML::NML(char *buf, char *proc, char *file, int set_to_server, int set_to_master){ if (NULL == file) { file = default_nml_config_file; } registered_with_server = 0; cms_for_msg_string_conversions = 0; strncpy(bufname, buf, 40); strncpy(procname, proc, 40); strncpy(cfgfilename, file, 160); blocking_read_poll_interval = -1.0; info_printed = 0; forced_type = 0; already_deleted = 0; cms = (CMS *) NULL; format_chain = (LinkedList *) NULL; phantom_read = (NMLTYPE(*)())NULL; phantom_peek = (NMLTYPE(*)())NULL; phantom_write = (int (*)(NMLmsg *)) NULL; phantom_write_if_read = (int (*)(NMLmsg *)) NULL; phantom_check_if_read = (int (*)()) NULL; phantom_clear = (int (*)()) NULL; channel_list_id = 0; error_type = NML_NO_ERROR; ignore_format_chain = 0; fast_mode = 0; channel_type = NML_GENERIC_CHANNEL_TYPE; if (-1 == cms_config(&cms, buf, proc, file, set_to_server, set_to_master)) { if (verbose_nml_error_messages) { rcs_print_error("NML: cms_config returned -1.\n"); } if (!info_printed) { print_info(buf, proc, file); } if (NULL != cms) { rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; } error_type = NML_INVALID_CONFIGURATION; return; } if (NULL == cms) { error_type = NML_INVALID_CONFIGURATION; if (!info_printed) { print_info(buf, proc, file); } return; } if (cms->status < 0) { error_type = NML_INVALID_CONFIGURATION; if (!info_printed) { print_info(buf, proc, file); } rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; return; } add_to_channel_list(); if (!cms->is_phantom && cms->ProcessType == CMS_LOCAL_TYPE && !cms->neutral && !cms->isserver) { fast_mode = 1; } cms_status = (int *) &(cms->status); cms_inbuffer_header_size = &(cms->header.in_buffer_size); if (NULL != cms) { char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = 0; temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } char *brpi_eq = strstr(cms->buflineupper, "BRPI="); if (brpi_eq != NULL) { blocking_read_poll_interval = strtod(brpi_eq + 5, NULL); } }}/******************************************************************* Constructor for NML:* Parameters:* char *buffer_line - Buffer line as written in the config file.* char *proc_line - Process Line as expected in the config file.* char *file - Name of the configuration file.* int set_to_server - If 1 this NML will consider its calling process to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -