/* * console device write */ static void viocons_write(struct console *co, const char *s, unsigned count) { int index; int begin; struct port_info *pi; static const char cr = '\r'; /* * Check port data first because the target LP might be valid but * simply not active, in which case we want to hvlog the output. */ pi = get_port_data(NULL); if (pi == NULL) { hvlog("\n\rviocons_write: unable to get port data."); return; } hvlogOutput(s, count); if (!viopath_isactive(pi->lp)) { /* * This is a VERY noisy trace message in the case where the * path manager is not active or in the case where this * function is called prior to viocons initialization. It is * being commented out for the sake of a clear trace buffer. */ #if 0 hvlog("\n\rviocons_write: path not active to lp %d", pi->lp); #endif return; } /* * Any newline character found will cause a * carriage return character to be emitted as well. */ begin = 0; for (index = 0; index < count; index++) { if (s[index] == '\n') { /* * Newline found. Print everything up to and * including the newline */ internal_write(pi, &s[begin], index - begin + 1, NULL); begin = index + 1; /* Emit a carriage return as well */ internal_write(pi, &cr, 1, NULL); } } /* If any characters left to write, write them now */ if ((index - begin) > 0) internal_write(pi, &s[begin], index - begin, NULL); }
void Connection::on_ready() { if (state_ == CONNECTION_STATE_CONNECTED && listener_->event_types() != 0) { set_state(CONNECTION_STATE_REGISTERING_EVENTS); internal_write(new StartupHandler(this, new RegisterRequest(listener_->event_types()))); return; } if (keyspace_.empty()) { notify_ready(); } else { internal_write(new StartupHandler(this, new QueryRequest("USE \"" + keyspace_ + "\""))); } }
void eeprom_base_device::erase(offs_t address) { if (!ready()) logerror("EEPROM: Erase performed before previous operation completed!"); internal_write(address, ~0); m_completion_time = machine().time() + m_operation_time[ERASE_TIME]; }
// ask the general-loader to use this when naming its output void GeneralWriter :: setRemotePath ( const std :: string & remote_db ) { stream_state new_state = uninitialized; switch ( state ) { case header_written: new_state = remote_name_sent; break; case schema_sent: new_state = remote_name_and_schema_sent; break; case software_name_sent: new_state = remote_name_and_software_name_sent; break; case schema_and_software_name_sent: new_state = remote_name_schema_and_software_name_sent; break; default: throw "state violation setting remote path"; } size_t str_size = remote_db . size (); if ( str_size > 0x10000 ) throw "remote path too long"; gwp_1string_evt_U16 hdr; init ( hdr, 0, evt_remote_path2 ); set_size ( hdr, str_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( remote_db . data (), str_size ); state = new_state; }
bool Connection::write(Handler* handler, bool flush_immediately) { bool result = internal_write(handler, flush_immediately); if (result) { restart_heartbeat_timer(); } return result; }
void Connection::close() { if(!m_connected && !m_connecting) return; // flush send data before disconnecting on clean connections if(m_connected && !m_error && m_outputStream) internal_write(); m_connecting = false; m_connected = false; m_connectCallback = nullptr; m_errorCallback = nullptr; m_recvCallback = nullptr; m_resolver.cancel(); m_readTimer.cancel(); m_writeTimer.cancel(); m_delayedWriteTimer.cancel(); if(m_socket.is_open()) { boost::system::error_code ec; m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); m_socket.close(); } }
void eeprom_base_device::write(offs_t address, UINT32 data) { if (!ready()) logerror("EEPROM: Write performed before previous operation completed!"); internal_write(address, data); m_completion_time = machine().time() + m_operation_time[WRITE_TIME]; }
void GeneralWriter :: logMsg ( const std :: string &msg ) { switch ( state ) { case header_written: case remote_name_sent: case schema_sent: case software_name_sent: case remote_name_and_schema_sent: case remote_name_and_software_name_sent: case schema_and_software_name_sent: case remote_name_schema_and_software_name_sent: case have_table: case have_column: case opened: break; default: return; } size_t str_size = msg . size (); if ( str_size == 0 ) return; if ( str_size > 0x10000 ) str_size = 0x10000; gwp_1string_evt_U16 hdr; init ( hdr, 0, evt_logmsg ); set_size ( hdr, str_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( msg . data (), str_size ); }
void eeprom_base_device::write_all(UINT32 data) { if (!ready()) logerror("EEPROM: Write all performed before previous operation completed!"); for (offs_t address = 0; address < (1 << m_address_bits); address++) internal_write(address, internal_read(address) & data); m_completion_time = machine().time() + m_operation_time[WRITE_ALL_TIME]; }
void eeprom_base_device::erase_all() { if (!ready()) logerror("EEPROM: Erase all performed before previous operation completed!"); for (offs_t address = 0; address < (1 << m_address_bits); address++) internal_write(address, ~0); m_completion_time = machine().time() + m_operation_time[ERASE_ALL_TIME]; }
void GeneralWriter :: writeHeader () { :: gw_header_v1 hdr; init ( hdr ); internal_write ( & hdr, sizeof hdr ); state = header_written; }
void Connection::on_supported(ResponseMessage* response) { SupportedResponse* supported = static_cast<SupportedResponse*>(response->response_body().get()); // TODO(mstump) do something with the supported info (void)supported; internal_write(new StartupHandler(this, new StartupRequest())); }
void Connection::send_credentials(const std::string& class_name) { ScopedPtr<V1Authenticator> v1_auth(config_.auth_provider()->new_authenticator_v1(host_, class_name)); if (v1_auth) { V1Authenticator::Credentials credentials; v1_auth->get_credentials(&credentials); internal_write(new StartupHandler(this, new CredentialsRequest(credentials))); } else { send_initial_auth_response(class_name); } }
void Connection::onCanWrite(const boost::system::error_code& error) { m_delayedWriteTimer.cancel(); if(error == asio::error::operation_aborted) return; if(m_connected) internal_write(); }
int GeneralWriter :: addTable ( const std :: string &table_name ) { stream_state new_state = uninitialized; switch ( state ) { case schema_sent: case remote_name_and_schema_sent: case remote_name_schema_and_software_name_sent: new_state = have_table; break; case have_table: case have_column: new_state = state; break; default: throw "state violation adding table"; } // create a pair between the outer db id ( 0 ) and this table name // this pair will act as an unique key of tables, whereas table_name // itself can be repeated if multiple databases are in use int_dbtbl tbl ( 0, table_name ); // prediction this is the index int id = ( int ) tables.size() + 1; if ( id > 256 ) throw "maximum number of tables exceeded"; // make sure we never record a table name twice under the same db std :: pair < std :: map < int_dbtbl, int > :: iterator, bool > result = table_name_idx.insert ( std :: pair < int_dbtbl, int > ( tbl, id ) ); // if first time if ( result.second ) { tables.push_back ( tbl ); size_t str_size = table_name . size (); if ( str_size > 0x10000 ) throw "maximum table name length exceeded"; gwp_1string_evt_U16 hdr; init ( hdr, id, evt_new_table2 ); set_size ( hdr, str_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( table_name.data (), str_size ); state = new_state; } // 1 based table id return result.first->second; }
void Connection::on_auth_challenge(const AuthResponseRequest* request, const std::string& token) { std::string response; if (!request->auth()->evaluate_challenge(token, &response)) { notify_error("Failed evaluating challenge token: " + request->auth()->error(), CONNECTION_ERROR_AUTH); return; } AuthResponseRequest* auth_response = new AuthResponseRequest(response, request->auth()); internal_write(new StartupHandler(this, auth_response)); }
void GeneralWriter :: columnDefault ( int stream_id, uint32_t elem_bits, const void *data, uint32_t elem_count ) { switch ( state ) { case opened: break; default: throw "state violation setting column default"; } if ( stream_id < 0 ) throw "Stream_id is not valid"; if ( stream_id > ( int ) streams.size () ) throw "Stream_id is out of bounds"; if ( elem_bits == 0 ) return; if ( data == 0 && elem_count != 0 ) throw "Invalid data ptr"; if ( elem_bits != streams [ stream_id - 1 ] . elem_bits ) throw "Invalid elem_bits"; size_t num_bytes = ( ( size_t ) elem_bits * elem_count + 7 ) / 8; if ( num_bytes == 0 ) { gwp_evt_hdr_v1 eh; init ( eh, stream_id, evt_empty_default ); write_event ( & eh, sizeof eh ); } else { if ( num_bytes <= 256 ) { gwp_data_evt chunk; init ( chunk, stream_id, evt_cell_default ); set_size ( chunk, num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } else if ( num_bytes <= 0x10000 ) { gwp_data_evt_U16 chunk; init ( chunk, stream_id, evt_cell_default2 ); set_size ( chunk, num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } else { throw "default cell-data exceeds maximum"; } internal_write ( data, num_bytes ); } }
void GeneralWriter :: setSoftwareName ( const std :: string & name, const std :: string & version ) { stream_state new_state = uninitialized; switch ( state ) { case header_written: new_state = software_name_sent; break; case remote_name_sent: new_state = remote_name_and_software_name_sent; break; case schema_sent: new_state = schema_and_software_name_sent; break; case remote_name_and_schema_sent: new_state = remote_name_schema_and_software_name_sent; break; default: throw "state violation using schema"; } size_t str1_size = name . size (); if ( str1_size > 0x100 ) throw "name too long"; size_t str2_size = version . size (); if ( str2_size > 0x100 ) throw "version too long"; gwp_2string_evt_v1 hdr; init ( hdr, 0, evt_software_name ); set_size1 ( hdr, str1_size ); set_size2 ( hdr, str2_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( name . data (), str1_size ); internal_write ( version . data (), str2_size ); state = new_state; }
// tell the general-loader to use this pre-defined schema void GeneralWriter :: useSchema ( const std :: string & schema_file_name, const std :: string & schema_db_spec ) { stream_state new_state = uninitialized; switch ( state ) { case header_written: new_state = schema_sent; break; case remote_name_sent: new_state = remote_name_and_schema_sent; break; case software_name_sent: new_state = schema_and_software_name_sent; break; case remote_name_and_software_name_sent: new_state = remote_name_schema_and_software_name_sent; break; default: throw "state violation using schema"; } size_t str1_size = schema_file_name . size (); if ( str1_size > 0x10000 ) throw "schema path too long"; size_t str2_size = schema_db_spec . size (); if ( str2_size > 0x10000 ) throw "schema spec too long"; gwp_2string_evt_U16 hdr; init ( hdr, 0, evt_use_schema2 ); set_size1 ( hdr, str1_size ); set_size2 ( hdr, str2_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( schema_file_name . data (), str1_size ); internal_write ( schema_db_spec . data (), str2_size ); state = new_state; }
void GeneralWriter :: setTblMetadataNode ( int obj_id, const std :: string & node_path, const std :: string & value ) { if ( obj_id <= 0 || ( size_t ) obj_id > tables.size () ) throw "Invalid table id"; size_t str1_size = node_path . size (); if ( str1_size > STRING_LIMIT_16 ) throw "tbl_path too long"; size_t str2_size = value . size (); if ( str2_size > STRING_LIMIT_16 ) throw "value too long"; if ( str1_size <= STRING_LIMIT_8 && str2_size <= STRING_LIMIT_8 ) { // use 8-bit sizes gwp_2string_evt_v1 hdr; init ( hdr, obj_id, evt_tbl_metadata_node ); set_size1 ( hdr, str1_size ); set_size2 ( hdr, str2_size ); write_event ( & hdr . dad, sizeof hdr ); } else { // use 16-bit sizes gwp_2string_evt_U16_v1 hdr; init ( hdr, obj_id, evt_tbl_metadata_node2 ); set_size1 ( hdr, str1_size ); set_size2 ( hdr, str2_size ); write_event ( & hdr . dad, sizeof hdr ); } internal_write ( node_path . data (), str1_size ); internal_write ( value . data (), str2_size ); }
void Connection::send_initial_auth_response(const std::string& class_name) { SharedRefPtr<Authenticator> auth(config_.auth_provider()->new_authenticator(host_, class_name)); if (!auth) { notify_error("Authentication required but no auth provider set", CONNECTION_ERROR_AUTH); } else { std::string response; if (!auth->initial_response(&response)) { notify_error("Failed creating initial response token: " + auth->error(), CONNECTION_ERROR_AUTH); return; } AuthResponseRequest* auth_response = new AuthResponseRequest(response, auth); internal_write(new StartupHandler(this, auth_response)); } }
void eeprom_base_device::nvram_default() { uint32_t eeprom_length = 1 << m_address_bits; uint32_t eeprom_bytes = eeprom_length * m_data_bits / 8; // initialize to the default value uint32_t default_value = m_default_value_set ? m_default_value : ~0; for (offs_t offs = 0; offs < eeprom_length; offs++) internal_write(offs, default_value); // handle hard-coded data from the driver if (m_default_data.u8 != nullptr) { osd_printf_verbose("Warning: Driver-specific EEPROM defaults are going away soon.\n"); for (offs_t offs = 0; offs < m_default_data_size; offs++) { if (m_data_bits == 8) internal_write(offs, m_default_data.u8[offs]); else internal_write(offs, m_default_data.u16[offs]); } } // populate from a memory region if present if (m_region.found()) { if (m_region->bytes() != eeprom_bytes) fatalerror("eeprom region '%s' wrong size (expected size = 0x%X)\n", tag(), eeprom_bytes); if (m_data_bits == 8 && m_region->bytewidth() != 1) fatalerror("eeprom region '%s' needs to be an 8-bit region\n", tag()); if (m_data_bits == 16 && (m_region->bytewidth() != 2 || m_region->endianness() != ENDIANNESS_BIG)) fatalerror("eeprom region '%s' needs to be a 16-bit big-endian region\n", tag()); osd_printf_verbose("Loading data from EEPROM region '%s'\n", tag()); memcpy(&m_data[0], m_region->base(), eeprom_bytes); } }
/* * TTY put_char method */ static void viotty_put_char(struct tty_struct *tty, unsigned char ch) { struct port_info *pi; pi = get_port_data(tty); if (pi == NULL) return; /* This will append '\r' as well if the char is '\n' */ if (viochar_is_console(pi)) hvlogOutput(&ch, 1); if (viopath_isactive(pi->lp)) internal_write(pi, &ch, 1, NULL); }
void GeneralWriter :: write_event ( const gwp_evt_hdr * e, size_t evt_size ) { #if PROGRESS_EVENT uint64_t ec = evt_count; if ( ( ec % 10000 ) == 0 ) { if ( ( ec % 500000 ) == 0 ) std :: cerr << "\n% [" << std :: setw ( 12 ) << byte_count << "] " << std :: setw ( 9 ) << ec + 1 << ' '; std :: cerr << '.'; } #endif ++ evt_count; assert ( evt ( * e ) != evt_bad_event ); assert ( evt ( * e ) < evt_max_id ); internal_write ( e, evt_size ); }
void GeneralWriter :: progMsg ( const std :: string & name, uint32_t version, uint64_t done, uint64_t total ) { switch ( state ) { case opened: break; default: return; } size_t str_size = name . size (); if ( str_size == 0 ) throw "zero-length app-name"; if ( str_size > 0x100 ) str_size = 0x100; // timestamp time_t timestamp = time ( NULL ); if ( total == 0 ) throw "illegal total value: would divide by zero"; if ( done > total ) throw "illegal done value: greater than total"; // calculate percentage done double fpercent = ( double ) done / total; assert ( fpercent >= 0.0 && fpercent <= 100.0 ); uint8_t percent = ( uint8_t ) ( fpercent * 100 ); gwp_status_evt_v1 hdr; init ( hdr, 0, evt_progmsg ); set_pid ( hdr, pid ); set_version ( hdr, version ); set_timestamp ( hdr, ( uint32_t ) timestamp ); set_size ( hdr, str_size ); set_percent ( hdr, percent ); write_event ( &hdr . dad, sizeof hdr ); internal_write ( name.data (), str_size ); }
void GeneralWriter :: logError ( const std :: string & msg ) { switch ( state ) { case header_written: case remote_name_sent: case schema_sent: case software_name_sent: case remote_name_and_schema_sent: case remote_name_and_software_name_sent: case schema_and_software_name_sent: case remote_name_schema_and_software_name_sent: case have_table: case have_column: case opened: case error: break; default: return; } gwp_1string_evt_U16 hdr; init ( hdr, 0, evt_errmsg2 ); const char * msg_data = msg . data (); size_t str_size = msg . size (); if ( str_size == 0 ) { msg_data = "ERROR: (NO MSG)"; str_size = strlen ( msg_data ); } else if ( str_size > 0x10000 ) str_size = 0x10000; set_size ( hdr, str_size ); write_event ( & hdr . dad, sizeof hdr ); internal_write ( msg_data, str_size ); }
void GeneralWriter :: write ( int stream_id, uint32_t elem_bits, const void *data, uint32_t elem_count ) { switch ( state ) { case opened: break; default: throw "state violation writing column data"; } if ( stream_id < 0 ) throw "Stream_id is not valid"; if ( stream_id > ( int ) streams.size () ) throw "Stream_id is out of bounds"; if ( elem_bits == 0 || elem_count == 0 ) return; if ( data == 0 ) throw "Invalid data ptr"; const int_stream & s = streams [ stream_id - 1 ]; if ( elem_bits != s . elem_bits ) throw "Invalid elem_bits"; bool compact_int = ( s . flag_bits & 1 ) != 0; const uint8_t * dp = ( const uint8_t * ) data; if ( compact_int ) { uint32_t elem; encode_result rslt; encode_result ( * encode ) ( uint8_t * buffer, const void * data, uint32_t first, uint32_t elem_count ); switch ( elem_bits ) { case 16: encode = encode_buffer < uint16_t >; break; case 32: encode = encode_buffer < uint32_t >; break; case 64: encode = encode_buffer < uint64_t >; break; default: throw "INTERNAL ERROR: corrupt element bits"; } for ( elem = 0; elem < elem_count; elem = rslt . num_elems ) { rslt = ( * encode ) ( packing_buffer, data, elem, elem_count ); if ( rslt . num_bytes <= 256 ) { assert ( rslt . num_bytes != 0 ); gwp_data_evt chunk; init ( chunk, stream_id, evt_cell_data ); set_size ( chunk, rslt . num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } else { gwp_data_evt_U16 chunk; init ( chunk, stream_id, evt_cell_data2 ); set_size ( chunk, rslt . num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } internal_write ( packing_buffer, rslt . num_bytes ); } } else { size_t num_bytes = ( ( size_t ) elem_bits * elem_count + 7 ) / 8; while ( num_bytes >= 0x10000 ) { gwp_data_evt_U16 chunk; init ( chunk, stream_id, evt_cell_data2 ); set_size ( chunk, 0x10000 ); write_event ( & chunk . dad, sizeof chunk ); internal_write ( dp, 0x10000 ); num_bytes -= 0x10000; dp += 0x10000; } if ( num_bytes <= 256 ) { gwp_data_evt chunk; init ( chunk, stream_id, evt_cell_data ); set_size ( chunk, num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } else { gwp_data_evt_U16 chunk; init ( chunk, stream_id, evt_cell_data2 ); set_size ( chunk, num_bytes ); write_event ( & chunk . dad, sizeof chunk ); } internal_write ( data, num_bytes ); } }
void Connection::on_connected() { internal_write(new StartupHandler(this, new OptionsRequest())); }
/* * TTY Write method */ static int viotty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) { int ret; int total = 0; struct port_info *pi; pi = get_port_data(tty); if (pi == NULL) { hvlog("\n\rviotty_write: no port data."); return -ENODEV; } if (viochar_is_console(pi)) hvlogOutput(buf, count); /* * If the path to this LP is closed, don't bother doing anything more. * just dump the data on the floor and return count. For some reason * some user level programs will attempt to probe available tty's and * they'll attempt a viotty_write on an invalid port which maps to an * invalid target lp. If this is the case then ignore the * viotty_write call and, since the viopath isn't active to this * partition, return count. */ if (!viopath_isactive(pi->lp)) { /* Noisy trace. Commented unless needed. */ #if 0 hvlog("\n\rviotty_write: viopath NOT active for lp %d.",pi->lp); #endif return count; } /* * If the viotty_write is invoked from user space we want to do the * copy_from_user() into an event buffer from the cfu buffer before * internal_write() is called because internal_write may need to buffer * data which will need to grab a spin_lock and we shouldn't * copy_from_user() while holding a spin_lock. Should internal_write() * not need to buffer data then it'll just use the event we created here * rather than checking one out from vio_get_event_buffer(). */ if (from_user) { struct viocharlpevent *viochar; int curlen; const char *curbuf = buf; viochar = viocons_get_cfu_buffer(); if (viochar == NULL) return -EAGAIN; initDataEvent(viochar, pi->lp); while (count > 0) { if (count > VIOCHAR_MAX_DATA) curlen = VIOCHAR_MAX_DATA; else curlen = count; viochar->len = curlen; ret = copy_from_user(viochar->data, curbuf, curlen); if (ret) break; ret = internal_write(pi, viochar->data, viochar->len, viochar); total += ret; if (ret != curlen) break; count -= curlen; curbuf += curlen; } viocons_free_cfu_buffer(viochar); } else total = internal_write(pi, buf, count, NULL); return total; }
void write_outchan(out_chan *chan, void *buffer, int size) { push_next_size(&chan->core, size); internal_write(&chan->core, buffer, size); }