/** @details -# While there is data in memory that has not been written to disk -# Write out each of the other parameter values to the temporary #writer_buff -# Write #writer_buff to the output file */ int Trick::DRBinary::format_specific_write_data(unsigned int writer_offset) { unsigned long bf; int sbf; unsigned int ii ; unsigned int len = 0 ; char *address = 0 ; /* Write out all parameters */ for (ii = 0; ii < rec_buffer.size() ; ii++) { address = rec_buffer[ii]->buffer + ( writer_offset * rec_buffer[ii]->ref->attr->size ) ; switch (rec_buffer[ii]->ref->attr->type) { case TRICK_CHARACTER: case TRICK_UNSIGNED_CHARACTER: case TRICK_SHORT: case TRICK_UNSIGNED_SHORT: case TRICK_BOOLEAN: case TRICK_ENUMERATED: case TRICK_INTEGER: case TRICK_UNSIGNED_INTEGER: case TRICK_FLOAT: case TRICK_LONG: case TRICK_UNSIGNED_LONG: case TRICK_LONG_LONG: case TRICK_UNSIGNED_LONG_LONG: case TRICK_STRUCTURED: case TRICK_DOUBLE: memcpy(writer_buff + len, address, (size_t)rec_buffer[ii]->ref->attr->size); break; case TRICK_BITFIELD: sbf = GET_BITFIELD(address, rec_buffer[ii]->ref->attr->size, rec_buffer[ii]->ref->attr->index[0].start, rec_buffer[ii]->ref->attr->index[0].size); memcpy(writer_buff + len, &sbf, (size_t)rec_buffer[ii]->ref->attr->size); break; case TRICK_UNSIGNED_BITFIELD: bf = GET_UNSIGNED_BITFIELD(address, rec_buffer[ii]->ref->attr->size, rec_buffer[ii]->ref->attr->index[0].start, rec_buffer[ii]->ref->attr->index[0].size); memcpy(writer_buff + len, &bf, (size_t)rec_buffer[ii]->ref->attr->size); break; default: break; } len += rec_buffer[ii]->ref->attr->size ; } write( fp , writer_buff , len) ; return(0) ; }
int Trick::VariableServerThread::write_binary_data( int Start, char *buf1, int PacketNum ) { int i; int ret ; int HeaderSize, MessageSize; int NumVariablesProcessed; unsigned int msg_type , offset, len ; unsigned int size ; unsigned int swap_int ; char * address = 0 ; char* param_name; //remove warning for unused PacketNum... to be deleted. (void)PacketNum ; /* start the offset 4 bytes into the message, we'll subtract the sizeof offset at the end */ offset = sizeof(msg_type) + sizeof(offset) ; /* if we are here the msg_type is good, so send a 0, swapped or not 0 is still 0 */ msg_type = VS_VAR_LIST ; memcpy(buf1, &msg_type , sizeof(msg_type)) ; HeaderSize = sizeof(msg_type); offset += sizeof(unsigned int) ; HeaderSize += sizeof(unsigned int); for (i = Start; i < (int)vars.size() ; i++) { // data to send was copied to buffer in copy_sim_data address = (char *)vars[i]->buffer_out; size = vars[i]->size ; param_name = vars[i]->ref->reference; len = strlen(param_name) ; // when var_binary_nonames, do not put the variable names into the message to be sent if (binary_data_nonames) { MessageSize = sizeof(int) + sizeof(size) + size ; } else { MessageSize = sizeof(len) + len + sizeof(int) + sizeof(size) + size ; } /* make sure this message will fit in a packet by itself */ if ( (HeaderSize + MessageSize) > MAX_MSG_LEN ) { message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small (need %d) for symbol %s, SKIPPING IT.\n", &connection, MAX_MSG_LEN, (int)(HeaderSize + MessageSize), vars[i]->ref->reference ); continue; } if ( (offset + MessageSize) < MAX_MSG_LEN ) { if (byteswap) { if (!binary_data_nonames) { swap_int = trick_byteswap_int((int)len) ; memcpy(&buf1[offset] , &swap_int , sizeof(len)) ; offset += sizeof(len) ; memcpy(&buf1[offset] , param_name , (size_t)len) ; offset += len ; } swap_int = trick_byteswap_int(vars[i]->ref->attr->type) ; memcpy(&buf1[offset] , &swap_int , sizeof(int)) ; offset += sizeof(int) ; swap_int = trick_byteswap_int((int)size) ; memcpy(&buf1[offset] , &swap_int , sizeof(size)) ; offset += sizeof(size) ; /* TODO: There is a bug here, this call will want to swap the entire buffer, we may not have the whole buffer */ trick_bswap_buffer(&buf1[offset], address, vars[i]->ref->attr, 1); offset += size ; } else { int temp_i ; unsigned int temp_ui ; if (!binary_data_nonames) { memcpy(&buf1[offset] , &len , sizeof(len)) ; offset += sizeof(len) ; memcpy(&buf1[offset] , param_name , (size_t)len) ; offset += len ; } memcpy(&buf1[offset] , &vars[i]->ref->attr->type , sizeof(int)) ; offset += sizeof(int) ; memcpy(&buf1[offset] , &size , sizeof(size)) ; offset += sizeof(size) ; switch ( vars[i]->ref->attr->type ) { case TRICK_BITFIELD: temp_i = GET_BITFIELD(address , vars[i]->ref->attr->size , vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ; memcpy(&buf1[offset] , &temp_i , (size_t)size) ; break ; case TRICK_UNSIGNED_BITFIELD: temp_ui = GET_UNSIGNED_BITFIELD(address , vars[i]->ref->attr->size , vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ; memcpy(&buf1[offset] , &temp_ui , (size_t)size) ; break ; case TRICK_NUMBER_OF_TYPES: // TRICK_NUMBER_OF_TYPES is an error case temp_i = 0 ; memcpy(&buf1[offset] , &temp_i , (size_t)size) ; break ; default: memcpy(&buf1[offset] , address , (size_t)size) ; break ; } offset += size ; } } else { /* indicate that we're over the maximum size */ if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server buffer[%d] too small (need %d), sending multiple binary packets.\n", &connection, connection.client_tag, MAX_MSG_LEN, (int)(offset + MessageSize) ); } break ; } } /* adjust the header with the correct information reflecting what has been accomplished */ NumVariablesProcessed = i - Start; offset -= sizeof(offset) ; if (byteswap) { swap_int = trick_byteswap_int((int)offset) ; memcpy(buf1 + sizeof(msg_type) , &swap_int , sizeof(offset)) ; swap_int = trick_byteswap_int( NumVariablesProcessed ) ; memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &swap_int , sizeof(swap_int)) ; } else { memcpy(buf1 + sizeof(msg_type) , &offset , sizeof(offset)) ; memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &NumVariablesProcessed , sizeof( NumVariablesProcessed )) ; } if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %u binary bytes containing %d variables.\n", &connection, connection.client_tag, (unsigned int)(offset + sizeof(offset)), NumVariablesProcessed); } len = offset + sizeof(msg_type) ; ret = tc_write(&connection, (char *) buf1, len); if ( ret != (int)len ) { return(-1) ; } /* return the index to the next symbol to send or V->num_vars if all done */ return i; }
int ref_to_value(REF2 * R, V_DATA * V) { char *cp; unsigned char *ucp; char **cpp; #ifndef __Lynx__ wchar_t **wcpp; #endif short *shp; int *ip; long *lp; float *fp; double *dp; long long *llp; int bf; unsigned int ubf; int type; char *address = 0; /* * This function is called from within the YACC parser. * This function relies on the REF data structure to be filled -- * YACC fills part of the REF struct and ref_attributes() fills * the rest. * * This function will get the value of the parameter pointed by REF and * returns the value in param_right_ret. */ /* I'm trying to keep from casting integer values to doubles and back again, esp. for long longs, for they could get changed in all of the conversions */ // if (R->deprecated) { // /* Removed input_processor as a parameter to ref_to_value for simplification but that means we no longer know // what I->print_deprecated is. Heck with it -- always print out this warning here. */ // //send_hs(stderr, "\n[33mWARNING: Deprecated variable referenced:[00m\n" // // "%s\nReturning value = 0.\n", R->reference); // V->type = R->attr->type; // V->value.ll = 0; // return (MM_NO_ERROR); // } type = R->attr->type; /* treat C++ bool reference as an unsigned char */ if (type == TRICK_BOOLEAN) { type = TRICK_UNSIGNED_CHARACTER; } address = R->address; // if ((R->num_index < R->attr->num_index - 1) || ((R->address_req == 0) && (R->num_index < R->attr->num_index))) { // type = VOID_PTR; // } V->type = type; switch (type) { case TRICK_VOID_PTR: //if ((R->num_index < R->attr->num_index - 1) || ((R->address_req == 0) && (R->num_index < R->attr->num_index))) { // V->value.vp = address; //} else { V->value.vp = *(void **) address; // } break; case TRICK_CHARACTER: cp = address; V->value.c = *cp; break; case TRICK_UNSIGNED_CHARACTER: #if ( __linux | __sgi ) case TRICK_BOOLEAN: #endif ucp = (unsigned char *) address; V->value.c = (char) *ucp; break; case TRICK_STRING: cpp = (char **) address; V->value.cp = *cpp; break; case TRICK_WSTRING: #ifndef __Lynx__ wcpp = (wchar_t **) address; V->value.wcp = *wcpp; #endif break; case TRICK_SHORT: case TRICK_UNSIGNED_SHORT: shp = (short *) address; V->value.s = *shp; V->type = TRICK_SHORT; break; case TRICK_INTEGER: case TRICK_ENUMERATED: case TRICK_UNSIGNED_INTEGER: #if ( __sun | __APPLE__ ) case TRICK_BOOLEAN: #endif ip = (int *) address; V->value.i = *ip; break; case TRICK_LONG: case TRICK_UNSIGNED_LONG: lp = (long *) address; V->value.ll = (long long) *lp; break; case TRICK_FLOAT: fp = (float *) address; V->value.f = *fp; break; case TRICK_DOUBLE: dp = (double *) address; V->value.d = *dp; V->type = TRICK_DOUBLE; break; case TRICK_LONG_LONG: case TRICK_UNSIGNED_LONG_LONG: llp = (long long *) address; V->value.ll = *llp; V->type = TRICK_LONG_LONG; break; case TRICK_BITFIELD: bf = GET_BITFIELD(address, R->attr->size, R->attr->index[0].start, R->attr->index[0].size); if (R->attr->size == sizeof(int)) { } else if (R->attr->size == sizeof(short)) { } else if (R->attr->size == sizeof(char)) { } else { // ERROR } // TODO: always integer? or should we return short or char for those types? V->value.i = bf; V->type = TRICK_INTEGER; break; case TRICK_UNSIGNED_BITFIELD: ubf = GET_UNSIGNED_BITFIELD(address, R->attr->size, R->attr->index[0].start, R->attr->index[0].size); // TODO: always integer? or should we return short or char for those types? V->value.i = (int) ubf; V->type = TRICK_UNSIGNED_INTEGER; break; } return (MM_OK); }
int Trick::DRAscii::copy_data_ascii_item( Trick::DataRecordBuffer * DI, int item_num, char *buf ) { char *address = 0; unsigned long bf; int sbf; address = DI->buffer + (item_num * DI->ref->attr->size) ; switch (DI->ref->attr->type) { case TRICK_CHARACTER: sprintf(buf, "%c", *((char *) address)); break; case TRICK_UNSIGNED_CHARACTER: #if ( __linux | __sgi ) case TRICK_BOOLEAN: #endif sprintf(buf, "%u", *((unsigned char *) address)); break; case TRICK_STRING: sprintf(buf, "%s", *((char **) address)); break; case TRICK_SHORT: sprintf(buf, "%d", *((short *) address)); break; case TRICK_UNSIGNED_SHORT: sprintf(buf, "%u", *((unsigned short *) address)); break; case TRICK_ENUMERATED: case TRICK_INTEGER: #if ( __sun | __APPLE__ ) case TRICK_BOOLEAN: #endif sprintf(buf, "%d", *((int *) address)); break; case TRICK_UNSIGNED_INTEGER: sprintf(buf, "%u", *((unsigned int *) address)); break; case TRICK_LONG: sprintf(buf, "%ld", *((long *) address)); break; case TRICK_UNSIGNED_LONG: sprintf(buf, "%lu", *((unsigned long *) address)); break; case TRICK_FLOAT: sprintf(buf, ascii_float_format.c_str() , *((float *) address)); break; case TRICK_DOUBLE: sprintf(buf, ascii_double_format.c_str() , *((double *) address)); break; case TRICK_BITFIELD: sbf = GET_BITFIELD(address, DI->ref->attr->size, DI->ref->attr->index[0].start, DI->ref->attr->index[0].size); sprintf(buf, "%d", sbf); break; case TRICK_UNSIGNED_BITFIELD: bf = GET_UNSIGNED_BITFIELD(address, DI->ref->attr->size, DI->ref->attr->index[0].start, DI->ref->attr->index[0].size); sprintf(buf, "%lu", bf); break; case TRICK_LONG_LONG: sprintf(buf, "%lld", *((long long *) address)); break; case TRICK_UNSIGNED_LONG_LONG: sprintf(buf, "%llu", *((unsigned long long *) address)); break; default: break; } return(0) ; }