📄 cms.cc
字号:
/* Set flags to make sure ops section of config file is correct. */ if (NULL != strchr(PermissionString, 'R')) { read_permission_flag = 1; } else { read_permission_flag = 0; } if (NULL != strchr(PermissionString, 'W')) { write_permission_flag = 1; } else { write_permission_flag = 0; } if (isserver) { read_permission_flag = 1; write_permission_flag = 1; } mode = CMS_NOT_A_MODE; /* Make sure user sets the mode before using. */ // Search the end of the bufferline for key words. if (NULL != strstr(ProcessLine, "serialPortDevName=")) { remote_port_type = CMS_TTY_REMOTE_PORT_TYPE; } if (min_compatible_version < 3.44 && min_compatible_version > 0) { total_subdivisions = 1; } if (queuing_enabled && split_buffer) { rcs_print_error("CMS: Can not split buffer with queuing enabled.\n"); status = CMS_CONFIG_ERROR; return; } if (min_compatible_version > 3.39 || min_compatible_version <= 0.0) { if (neutral_encoding_method == CMS_ASCII_ENCODING) { neutral_encoding_method = CMS_DISPLAY_ASCII_ENCODING; } } if (min_compatible_version <= 3.71 && min_compatible_version >= 1e-6) { rcs_print("NO DIAGNOSTICS\n"); enable_diagnostics = 0; } open(); /* Allocate memory and intialize XDR streams */ if (enable_diagnostics) { setup_diag_proc_info(); }}/* Function for allocating memory and initializing XDR streams, which *//* is called from both CMS constructors. */void CMS::open(void){ int encode_header_ret; int encode_queuing_header_ret; /* Clear some status checking variables. */ status = CMS_STATUS_NOT_SET; /* Set all the pointers to null before requesting memory so that we only */ /* free successfully allocated memory. */ data = NULL; subdiv_data = NULL; encoded_data = NULL; encoded_header = NULL; encoded_queuing_header = NULL; encoded_header_size = 0; updater = (CMS_UPDATER *) NULL; normal_updater = (CMS_UPDATER *) NULL; temp_updater = (CMS_UPDATER *) NULL; last_im = CMS_NOT_A_MODE; pointer_check_disabled = 0; dummy_handle = (PHYSMEM_HANDLE *) NULL; /* Initialize some debug variables. */ first_read_done = 0; first_write_done = 0; total_messages_missed = 0; messages_missed_on_last_read = 0; format_low_ptr = (char *) NULL; format_high_ptr = (char *) NULL; header.was_read = 0; header.write_id = 0; header.in_buffer_size = 0; number_of_cms_objects++; /* Increment the static variable. */ /* Save some memory and time if this is a PHANTOMMEM object. */ if (!is_phantom) { /* Allocate memory for the local copy of global buffer. */ data = malloc(size); memset(data, 0, size); subdiv_data = data; if (force_raw) { encoded_data = data; } rcs_print_debug(PRINT_CMS_CONSTRUCTORS, "%X = data = calloc(%d,1);\n", data, size); /* Check to see if allocating memory was successful. */ if (data == NULL) { rcs_print_error("CMS: Can't allocate memory for local buffer.\n"); status = CMS_CREATE_ERROR; return; } } if (isserver || neutral || ProcessType == CMS_REMOTE_TYPE && !force_raw) { switch (neutral_encoding_method) { case CMS_XDR_ENCODING: updater = new CMS_XDR_UPDATER(this); break; case CMS_ASCII_ENCODING: updater = new CMS_ASCII_UPDATER(this); break; case CMS_DISPLAY_ASCII_ENCODING: updater = new CMS_DISPLAY_ASCII_UPDATER(this); break; default: updater = (CMS_UPDATER *) NULL; status = CMS_UPDATE_ERROR; rcs_print_error("CMS: Invalid encoding method(%d)\n", neutral_encoding_method); break; } normal_updater = updater; if (((int) status) < 0) { return; } /* Find out what size the header is after it has been encoded. */ if ((encode_header_ret = encode_header()) == -1) { rcs_print_error("CMS:Error encoding CMS header.\n"); status = CMS_MISC_ERROR; return; } encoded_header_size = (long) encode_header_ret; if (min_compatible_version <= 0.0 || min_compatible_version > 3.29) { if (neutral_encoding_method == CMS_DISPLAY_ASCII_ENCODING) { encoded_header_size = 16; } } if (queuing_enabled) { /* Initialize queuing header to avoid test center error message. */ memset(&queuing_header, 0, sizeof(queuing_header)); /* Find out what size the queuing_header is after being encoded. */ if ((encode_queuing_header_ret = encode_queuing_header()) == -1) { rcs_print_error("CMS:Error encoding CMS queuing_header.\n"); status = CMS_MISC_ERROR; return; } encoded_queuing_header_size = (long) encode_queuing_header_ret; } } if (split_buffer && total_subdivisions > 1) { rcs_print_error ("Can't split buffer and use subdivisions. (total_subsivisions=%d)", total_subdivisions); status = CMS_MISC_ERROR; return; } int nfactor = 4; if (NULL != updater) { nfactor = updater->neutral_size_factor; } /* Set some varaibles to let the user know how much space is left. */ size_without_diagnostics = size; diag_offset = 0; if (enable_diagnostics) { diag_offset = (sizeof(CMS_DIAG_HEADER) + (total_connections * sizeof(CMS_DIAG_PROC_INFO))); size_without_diagnostics -= diag_offset; } skip_area = 0; half_offset = (size_without_diagnostics / 2); half_size = (size_without_diagnostics / 2); fast_mode = 0; if (split_buffer) { if (neutral) { subdiv_size = (size_without_diagnostics / 2) - total_connections; subdiv_size -= (subdiv_size % 4); max_message_size = (size_without_diagnostics / 2) - total_connections - encoded_header_size - 2; max_encoded_message_size = size_without_diagnostics - total_connections - encoded_header_size; guaranteed_message_space = max_message_size / cms_encoded_data_explosion_factor; } else { if (ProcessType == CMS_REMOTE_TYPE) { subdiv_size = (size_without_diagnostics / 2) - total_connections; subdiv_size -= (subdiv_size % 4); max_message_size = (size_without_diagnostics / 2) - total_connections - sizeof(CMS_HEADER) - 2; max_encoded_message_size = nfactor * max_message_size; guaranteed_message_space = max_message_size / nfactor; } else { subdiv_size = (size_without_diagnostics / 2) - total_connections; subdiv_size -= (subdiv_size % 4); max_message_size = (size_without_diagnostics / 2) - total_connections - sizeof(CMS_HEADER) - 2; max_encoded_message_size = nfactor * max_message_size; guaranteed_message_space = max_message_size; } } } else { if (neutral) { subdiv_size = (size_without_diagnostics - total_connections) / total_subdivisions; subdiv_size -= (subdiv_size % 4); max_message_size = subdiv_size - encoded_header_size; max_encoded_message_size = subdiv_size - encoded_header_size; guaranteed_message_space = max_message_size / nfactor; } else { if (ProcessType == CMS_REMOTE_TYPE) { subdiv_size = (size_without_diagnostics - total_connections) / total_subdivisions; subdiv_size -= (subdiv_size % 4); max_message_size = subdiv_size - sizeof(CMS_HEADER); max_encoded_message_size = nfactor * max_message_size; guaranteed_message_space = max_message_size / nfactor; } else { subdiv_size = (size_without_diagnostics - total_connections) / total_subdivisions; subdiv_size -= (subdiv_size % 4); max_message_size = subdiv_size - sizeof(CMS_HEADER); max_encoded_message_size = nfactor * max_message_size; guaranteed_message_space = max_message_size; } } } if (enc_max_size > 0 && enc_max_size < max_encoded_message_size) { max_encoded_message_size = enc_max_size; } if ((neutral || ProcessType == CMS_REMOTE_TYPE) && !isserver) { /* Local processes that are use a neutral buffer and */ /* All remote processes. */ read_mode = CMS_DECODE; read_updater_mode = CMS_DECODE_DATA; write_mode = CMS_ENCODE; write_updater_mode = CMS_ENCODE_DATA; } else if (!neutral && isserver && !force_raw) { /* Servers. */ read_mode = CMS_ENCODE; read_updater_mode = CMS_ENCODE_DATA; write_mode = CMS_DECODE; write_updater_mode = CMS_DECODE_DATA; } else { /* Everybody else. */ read_mode = CMS_RAW_OUT; read_updater_mode = CMS_NO_UPDATE; write_mode = CMS_RAW_IN; write_updater_mode = CMS_NO_UPDATE; }}/* Set the area used for the encoded data buffer, and initialize the */ /* XDR streams to use this area. *//* This function is called from open, which is called by the constructor */ /* and by one of the CMS_SERVER functions. *//* _encoded_data should point to an area of memory at least cms_encoded_data_explosion_factor*size .*/void CMS::set_encoded_data(void *_encoded_data, long _encoded_data_size){ if (force_raw) { if (NULL != data && data != _encoded_data) { free(data); } data = encoded_data = _encoded_data; encoded_data_size = size; subdiv_data = data; using_external_encoded_data = 1; } else { if (max_encoded_message_size > _encoded_data_size) { max_encoded_message_size = _encoded_data_size; } if (NULL != updater) { updater->set_encoded_data(_encoded_data, _encoded_data_size); } if (NULL != _encoded_data) { memset(_encoded_data, 0, max_encoded_message_size); } using_external_encoded_data = 1; }}/* Destructor */CMS::~CMS(){ rcs_print_debug(PRINT_CMS_DESTRUCTORS, "deleting CMS (%s)\n", BufferName); if (NULL != updater) { delete updater; updater = (CMS_UPDATER *) NULL; } /* Free the memory used for the local copy of the global buffer. */ if (NULL != data && (!force_raw || !using_external_encoded_data)) { rcs_print_debug(PRINT_CMS_DESTRUCTORS, "free( data = %X);\n", data); free(data); data = NULL; if (force_raw) { encoded_data = NULL; } } number_of_cms_objects--; if (NULL != dummy_handle) { delete dummy_handle; dummy_handle = (PHYSMEM_HANDLE *) NULL; } rcs_print_debug(PRINT_CMS_DESTRUCTORS, "Leaving ~CMS()\n");}/* This function should never be called. It exists so that classes which */ /* overload read, write etc don't have to bother creating it. */CMS_STATUS CMS::main_access(void *_local){ rcs_print_error("CMS::main_access called by %s for %s.\n", ProcessName, BufferName); rcs_print_error("This should never happen.\n"); rcs_print_error ("Derived classes should either override main_access() or\n"); rcs_print_error("the functions that call it.(read(), write(), etc.)\n"); rcs_print_error("_local = %p\n", _local); return (CMS_MISC_ERROR);}/* General Utility Functions. *//* Check the buffer id against in_buffer_id to see if it is new. */CMS_STATUS CMS::check_id(CMSID id){ if (status < 0) { return (status); } if (0 == id) { messages_missed_on_last_read = 0; in_buffer_id = 0; return (status = CMS_READ_OLD); } if (id == in_buffer_id) { status = CMS_READ_OLD; messages_missed_on_last_read = 0; } else { if (split_buffer) { if (id == last_id_side0 || id == last_id_side1) { status = CMS_READ_OLD; messages_missed_on_last_read = 0; return (status); } if (toggle_bit) { last_id_side0 = id; } else { last_id_side1 = id; } } status = CMS_READ_OK; messages_missed_on_last_read = id - in_buffer_id - 1; if (messages_missed_on_last_read < 0) { messages_missed_on_last_read = 0; } total_messages_missed += messages_missed_on_last_read; in_buffer_id = id; } return (status);}void CMS::clean_buffers(){ in_buffer_id = 0; last_id_side0 = 0; last_id_side1 = 0; if (NULL != data) { memset(data, 0, size); } if (NULL != encoded_data) { memset(encoded_data, 0, max_encoded_message_size); }}/* Read and Write interface functions call appropriate virtual function. */CMS_STATUS CMS::clear(){ in_buffer_id = 0; last_id_side0 = 0; last_id_side1 = 0; status = CMS_STATUS_NOT_SET; internal_access_type = CMS_CLEAR_ACCESS; main_access(data); return (status);}int CMS::check_if_read(){ internal_access_type = CMS_CHECK_IF_READ_ACCESS; status = CMS_STATUS_NOT_SET; main_access(data); return ((int) header.was_read);}int CMS::get_queue_length(){ internal_access_type = CMS_GET_QUEUE_LENGTH_ACCESS; status = CMS_STATUS_NOT_SET; if (!queuing_enabled) { return 0; } main_access(data); return ((int) queuing_header.queue_length);}int CMS::get_space_available(){ internal_access_type = CMS_GET_SPACE_AVAILABLE_ACCESS; status = CMS_STATUS_NOT_SET; if (!queuing_enabled) { return size; } main_access(data); return ((int) free_space);}CMS_STATUS CMS::read(){ internal_access_type = CMS_READ_ACCESS; status = CMS_STATUS_NOT_SET; blocking_timeout = 0; main_access(data); return (status);}CMS_STATUS CMS::blocking_read(double _blocking_timeout){ status = CMS_STATUS_NOT_SET; internal_access_type = CMS_READ_ACCESS; blocking_timeout = _blocking_timeout; main_access(data); return (status);}void CMS::disconnect(){}void CMS::reconnect(){}CMS_STATUS CMS::peek(){ internal_access_type = CMS_PEEK_ACCESS; status = CMS_STATUS_NOT_SET; blocking_timeout = 0; main_access(data); return (status);}CMS_STATUS CMS::write(void *user_data){ internal_access_type = CMS_WRITE_ACCESS; status = CMS_STATUS_NOT_SET; main_access(user_data); return (status);}CMS_STATUS CMS::write_if_read(void *user_data){ internal_access_type = CMS_WRITE_IF_READ_ACCESS; status = CMS_STATUS_NOT_SET; main_access(user_data); return (status);}// For protocols that provide No security, tell the// application the login was successful.// This method needs to be overloaded to have any security.int CMS::login(const char *name, const char *passwd){ return 1;}/* Function to set the mode to appropriate read or write mode. */void CMS::set_mode(CMSMODE im){ status = CMS_STATUS_NOT_SET; if (last_im == im) { return; } if (!force_raw) { if (CMS_WRITE == im) { mode = write_mode; if (NULL != updater) { updater->set_mode((CMS_UPDATER_MODE) write_updater_mode); } last_im = im; return; } if (CMS_READ == im) { mode = read_mode; if (NULL != updater) { updater->set_mode((CMS_UPDATER_MODE) read_updater_mode); } last_im = im; return; } if (CMS_DECODE == im) { mode = CMS_DECODE; if (NULL != updater) { updater->set_mode(CMS_DECODE_DATA); } } if (CMS_ENCODE == im) { mode = CMS_ENCODE; if (NULL != updater) { updater->set_mode(CMS_ENCODE_DATA); } } } last_im = im; mode = im;}/* Functions for changing/restoring the updator type. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -