• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nasa / trick / 4357077355

pending completion
4357077355

push

github

GitHub
Fix SIM_job_class_order (#1470)

12387 of 21399 relevant lines covered (57.89%)

916206.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.97
/trick_source/sim_services/VariableServer/VariableServerThread_write_data.cpp
1
/*
2
PURPOSE:      (Allows clients to get and set Trick parameters)
3
PROGRAMMERS: (((Alex Lin) (NASA) (8/06) (--)))
4
*/
5

6
#include <iostream>
7
#include <pthread.h>
8
#include "trick/VariableServer.hh"
9
#include "trick/parameter_types.h"
10
#include "trick/bitfield_proto.h"
11
#include "trick/trick_byteswap.h"
12
#include "trick/tc_proto.h"
13
#include "trick/message_proto.h"
14
#include "trick/message_type.h"
15

16

17
extern "C" {
18
    void *trick_bswap_buffer(void *out, void *in, ATTRIBUTES * attr, int tofrom) ;
19
}
20

21
#define MAX_MSG_LEN    8192
22

23

24
int Trick::VariableServerThread::write_binary_data( int Start, char *buf1, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type) {
3✔
25
    int i;
26
    int ret ;
27
    int HeaderSize, MessageSize;
28
    int NumVariablesProcessed;
29
    unsigned int msg_type , offset, len ;
30
    unsigned int size ;
31
    unsigned int swap_int ;
32
    char * address = 0 ;
3✔
33
    char* param_name;
34

35
    /* start the offset 4 bytes into the message, we'll subtract the sizeof offset at the end */
36
    offset = sizeof(msg_type) + sizeof(offset) ;
3✔
37

38
    if (byteswap) {
3✔
39
        /* Swap message type bytes */
40
        msg_type = trick_byteswap_int((int)message_type) ;
×
41
    } else {
42
        msg_type = message_type;
3✔
43
    }
44
    memcpy(buf1, &msg_type , sizeof(msg_type)) ;
3✔
45
    HeaderSize = sizeof(msg_type);
3✔
46

47
    offset += sizeof(unsigned int) ;
3✔
48
    HeaderSize += sizeof(unsigned int);
3✔
49

50
    for (i = Start; i < (int)given_vars.size() ; i++) {
12✔
51

52
        // data to send was copied to buffer in copy_sim_data
53
        address = (char *)given_vars[i]->buffer_out;
9✔
54
        size = given_vars[i]->size ;
9✔
55

56
        param_name = given_vars[i]->ref->reference;
9✔
57
        len = strlen(param_name)  ;
9✔
58
        // when var_binary_nonames, do not put the variable names into the message to be sent
59
        if (binary_data_nonames) {
9✔
60
            MessageSize = sizeof(int) + sizeof(size) + size ;
9✔
61
        } else {
62
            MessageSize = sizeof(len) + len + sizeof(int) + sizeof(size) + size ;
×
63
        }
64

65
        /* make sure this message will fit in a packet by itself */
66
        if ( (HeaderSize + MessageSize) > MAX_MSG_LEN ) {
9✔
67
            message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small (need %d) for symbol %s, SKIPPING IT.\n",
×
68
                            &connection, MAX_MSG_LEN,
69
                            (int)(HeaderSize + MessageSize),
70
                            given_vars[i]->ref->reference );
×
71
            continue;
×
72
        }
73

74
        if ( (offset + MessageSize) < MAX_MSG_LEN ) {
9✔
75
            if (byteswap) {
9✔
76
                if (!binary_data_nonames) {
×
77
                    swap_int = trick_byteswap_int((int)len) ;
×
78
                    memcpy(&buf1[offset] , &swap_int , sizeof(len)) ;
×
79
                    offset += sizeof(len) ;
×
80

81
                    memcpy(&buf1[offset] , param_name , (size_t)len) ;
×
82
                    offset += len ;
×
83
                }
84

85
                swap_int = trick_byteswap_int(given_vars[i]->ref->attr->type) ;
×
86
                memcpy(&buf1[offset] , &swap_int , sizeof(int)) ;
×
87
                offset += sizeof(int) ;
×
88

89
                swap_int = trick_byteswap_int((int)size) ;
×
90
                memcpy(&buf1[offset] , &swap_int , sizeof(size)) ;
×
91
                offset += sizeof(size) ;
×
92

93
                /* TODO: There is a bug here, this call will want to swap the entire buffer, we may not have the whole buffer */
94
                trick_bswap_buffer(&buf1[offset], address, given_vars[i]->ref->attr, 1);
×
95
                offset += size ;
×
96
            }
97
            else {
98
                int temp_i ;
99
                unsigned int temp_ui ;
100

101
                if (!binary_data_nonames) {
9✔
102
                    memcpy(&buf1[offset] , &len , sizeof(len)) ;
5✔
103
                    offset += sizeof(len) ;
5✔
104

105
                    memcpy(&buf1[offset] , param_name , (size_t)len) ;
5✔
106
                    offset += len ;
5✔
107
                }
108

109
                memcpy(&buf1[offset] , &given_vars[i]->ref->attr->type , sizeof(int)) ;
9✔
110
                offset += sizeof(int) ;
9✔
111

112
                memcpy(&buf1[offset] , &size , sizeof(size)) ;
9✔
113
                offset += sizeof(size) ;
9✔
114

115
                switch ( given_vars[i]->ref->attr->type ) {
9✔
116
                    case TRICK_BITFIELD:
×
117
                        temp_i = GET_BITFIELD(address , given_vars[i]->ref->attr->size ,
×
118
                          given_vars[i]->ref->attr->index[0].start, given_vars[i]->ref->attr->index[0].size) ;
119
                        memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
×
120
                    break ;
×
121
                    case TRICK_UNSIGNED_BITFIELD:
×
122
                        temp_ui = GET_UNSIGNED_BITFIELD(address , given_vars[i]->ref->attr->size ,
×
123
                                given_vars[i]->ref->attr->index[0].start, given_vars[i]->ref->attr->index[0].size) ;
124
                        memcpy(&buf1[offset] , &temp_ui , (size_t)size) ;
×
125
                    break ;
×
126
                    case TRICK_NUMBER_OF_TYPES:
×
127
                        // TRICK_NUMBER_OF_TYPES is an error case
128
                        temp_i = 0 ;
×
129
                        memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
×
130
                    break ;
×
131
                    default:
9✔
132
                        memcpy(&buf1[offset] , address , (size_t)size) ;
9✔
133
                    break ;
9✔
134
                }
135
                offset += size ;
9✔
136
            }
137
        }
138
        else {
139
            /* indicate that we're over the maximum size */
140
            if (debug >= 2) {
×
141
                message_publish(MSG_DEBUG, "%p tag=<%s> var_server buffer[%d] too small (need %d), sending multiple binary packets.\n",
×
142
                        &connection, connection.client_tag, MAX_MSG_LEN,
×
143
                        (int)(offset + MessageSize) );
×
144
            }
145
            break ;
×
146
        }
147
    }
148

149
    /* adjust the header with the correct information reflecting what has been accomplished */
150
    NumVariablesProcessed = i - Start;
3✔
151

152
    offset -= sizeof(offset) ;
3✔
153
    if (byteswap) {
3✔
154
        swap_int = trick_byteswap_int((int)offset) ;
×
155
        memcpy(buf1 + sizeof(msg_type) , &swap_int , sizeof(offset)) ;
×
156

157
        swap_int = trick_byteswap_int( NumVariablesProcessed ) ;
×
158
        memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &swap_int , sizeof(swap_int)) ;
×
159
    }
160
    else {
161
        memcpy(buf1 + sizeof(msg_type) , &offset , sizeof(offset)) ;
3✔
162
        memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &NumVariablesProcessed , sizeof( NumVariablesProcessed )) ;
3✔
163
    }
164

165
    if (debug >= 2) {
3✔
166
        message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %u binary bytes containing %d variables.\n", &connection,
×
167
                connection.client_tag, (unsigned int)(offset + sizeof(offset)), NumVariablesProcessed);
×
168
    }
169

170
    len = offset + sizeof(msg_type) ;
3✔
171
    ret = tc_write(&connection, (char *) buf1, len);
3✔
172
    if ( ret != (int)len ) {
3✔
173
        return(-1) ;
×
174
    }
175

176
    /* return the index to the next symbol to send or V->num_vars if all done */
177
    return i;
3✔
178
}
179

180
int Trick::VariableServerThread::write_ascii_data(char * dest_buf, size_t dest_buf_size, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type ) {
149✔
181

182
    snprintf(dest_buf, dest_buf_size, "%d\t", message_type) ;
149✔
183

184
    for (unsigned long i = 0; i < given_vars.size(); i++) {
443✔
185
        char curr_buf[MAX_MSG_LEN];
186
        int ret = vs_format_ascii( given_vars[i] , curr_buf, sizeof(curr_buf));
294✔
187

188
        if (ret < 0) {
294✔
189
            message_publish(MSG_WARNING, "%p Variable Server string buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
×
190
                            &connection, MAX_MSG_LEN, given_vars[i]->ref->reference );
×
191
        }
192

193
        /* make sure this message will fit in a packet by itself */
194
        if( strlen( curr_buf ) + 2 > MAX_MSG_LEN ) {
294✔
195
            message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
×
196
                            &connection, MAX_MSG_LEN, given_vars[i]->ref->reference );
×
197
            curr_buf[MAX_MSG_LEN - 1] = '\0';
×
198
        }
199

200
        int len = strlen(dest_buf) ;
294✔
201

202
        /* make sure there is space for the next tab or next newline and null */
203
        if( len + strlen( curr_buf ) + 2 > MAX_MSG_LEN ) {
294✔
204
            // If there isn't, send incomplete message
205
            if (debug >= 2) {
×
206
                message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:\n%s\n",
×
207
                                &connection, connection.client_tag, (int)strlen(dest_buf), dest_buf) ;
×
208
            }
209

210
            ret = tc_write(&connection, (char *) dest_buf, len);
×
211
            if ( ret != len ) {
×
212
                return(-1) ;
×
213
            }
214
            dest_buf[0] = '\0';
×
215
        }
216

217
        strcat(dest_buf, curr_buf);
294✔
218
        strcat(dest_buf, "\t");
294✔
219
    }
220

221
    int len = strlen(dest_buf) ;
149✔
222

223
    if ( len > 0 ) {
149✔
224
        dest_buf[ strlen(dest_buf) - 1 ] = '\n';
149✔
225

226
        if (debug >= 2) {
149✔
227
            message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:\n%s\n",
×
228
                            &connection, connection.client_tag, (int)strlen(dest_buf), dest_buf) ;
×
229
        }
230
        int ret = tc_write(&connection, (char *) dest_buf, (int)strlen(dest_buf));
149✔
231
        if ( ret != (int)strlen(dest_buf) ) {
149✔
232
            return(-1) ;
×
233
        }
234
    }
235

236
    return 0;
149✔
237
}
238

239
int Trick::VariableServerThread::write_data() {
457✔
240

241
    int ret;
242
    unsigned int i ;
243
    char buf1[ MAX_MSG_LEN ];
244
    int len ;
245

246
    // do not send anything when there are no variables!
247
    if ( vars.size() == 0 or packets_copied == 0 ) {
457✔
248
        return 0;
226✔
249
    }
250

251
    /* Acquire sole access to vars[ii]->buffer_in. */
252
    if ( var_data_staged and pthread_mutex_trylock(&copy_mutex) == 0 ) {
336✔
253
        unsigned int ii;
254
        void * temp_p;
255
        // Swap buffer_in and buffer_out for each vars[ii].
256
        for ( ii = 0 ; ii < vars.size() ; ii++ ) {
359✔
257
                          temp_p = vars[ii]->buffer_in;
254✔
258
            vars[ii]->buffer_in  = vars[ii]->buffer_out;
254✔
259
            vars[ii]->buffer_out = temp_p;
254✔
260
        }
261
        var_data_staged = false;
105✔
262

263
        /* Relinquish sole access to vars[ii]->buffer_in. */
264
        pthread_mutex_unlock(&copy_mutex) ;
105✔
265

266
        if (binary_data) {
105✔
267
            int index = 0;            
3✔
268

269
            do {
×
270
                ret = write_binary_data( index, buf1, vars, VS_VAR_LIST );
3✔
271
                if ( ret >= 0 ) {
3✔
272
                    index = ret ;
3✔
273
                } else {
274
                    return(-1) ;
×
275
                }
276
            } while( index < (int)vars.size() );
3✔
277

278
            return 0;
3✔
279

280
        } else { /* ascii mode */
281
            return write_ascii_data(buf1, sizeof(buf1), vars, VS_VAR_LIST );
102✔
282
        }
283
    }
284
}
231✔
285

286
int Trick::VariableServerThread::write_data(std::vector<VariableReference *> given_vars) { 
47✔
287
    // do not send anything when there are no variables!
288
    if ( given_vars.size() == 0) {
47✔
289
        return(0);
×
290
    }
291

292
    /* Acquire sole access to vars[ii]->buffer_in. */
293
    if ( pthread_mutex_trylock(&copy_mutex) == 0 ) {
47✔
294
        // Swap buffer_in and buffer_out for each vars[ii].
295
        for (int i = 0 ; i < given_vars.size() ; i++ ) {
96✔
296
            void *temp_p              = given_vars[i]->buffer_in;
49✔
297
            given_vars[i]->buffer_in  = given_vars[i]->buffer_out;
49✔
298
            given_vars[i]->buffer_out = temp_p;
49✔
299
        }
300
        /* Relinquish sole access to vars[ii]->buffer_in. */
301
        pthread_mutex_unlock(&copy_mutex) ;
47✔
302

303
        char buf1[ MAX_MSG_LEN ];
304

305
        if (binary_data) {
47✔
306
            int index = 0;
×
307

308
            do {
×
309
                int ret = write_binary_data( index, buf1, given_vars, VS_SEND_ONCE );
×
310
                if ( ret >= 0 ) {
×
311
                    index = ret ;
×
312
                } else {
313
                    return(-1) ;
×
314
                }
315
            } while( index < (int)given_vars.size() );
×
316

317
            return 0;
×
318

319
        } else { /* ascii mode */
320
            return write_ascii_data(buf1, sizeof(buf1), given_vars, VS_SEND_ONCE);
47✔
321
        }
322
    }
323
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc