Project

General

Profile

Statistics
| Branch: | Revision:

root / src / sim / parsim / cfilecommbuffer.cc @ e1750c09

History | View | Annotate | Download (10.6 KB)

1
//=========================================================================
2
//  CFILECOMMBUFFER.CC - part of
3
//
4
//                  OMNeT++/OMNEST
5
//           Discrete System Simulation in C++
6
//
7
//  Author: Andras Varga, 2003
8
//          Dept. of Electrical and Computer Systems Engineering,
9
//          Monash University, Melbourne, Australia
10
//
11
//=========================================================================
12

    
13
/*--------------------------------------------------------------*
14
  Copyright (C) 2003-2008 Andras Varga
15
  Copyright (C) 2006-2008 OpenSim Ltd.
16

17
  This file is distributed WITHOUT ANY WARRANTY. See the file
18
  `license' for details on this and other legal matters.
19
*--------------------------------------------------------------*/
20

    
21
#include <string.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <locale.h>
25

    
26
#include "cfilecommbuffer.h"
27
#include "simutil.h"
28
#include "cownedobject.h"
29
#include "globals.h"
30
#include "regmacros.h"
31

    
32
USING_NAMESPACE
33

    
34
Register_Class(cFileCommBuffer);
35

    
36
#define STORE(FMT,d)    {sprintf(mBuffer+mMsgSize, FMT "\n", d); mMsgSize+=strlen(mBuffer+mMsgSize);}
37
#define EXTRACT(FMT,d)  {sread(mBuffer, mPosition, FMT, &d);}
38

    
39
// TBD store/extract as ASCII not binary
40
#define STOREARRAY(type,d,size)   {memcpy(mBuffer+mMsgSize,d,size*sizeof(type)); mMsgSize+=size*sizeof(type);}
41
#define EXTRACTARRAY(type,d,size) {memcpy(d,mBuffer+mPosition,size*sizeof(type)); mPosition+=size*sizeof(type);}
42

    
43
#define LL  LONGLONG_PRINTF_FORMAT
44

    
45

    
46
// helper: match type (i.e. "i " from "i 134")
47
static void matchtype(char *buffer, int& pos, const char *&fmt)
48
{
49
    char *buf = buffer+pos;
50
    const char *origfmt = fmt;
51
    while (*buf && *fmt!=' ')
52
    {
53
        if (*fmt != *buf)
54
            throw cRuntimeError("cFileCommBuffer: unpack(): format prefix '%s' doesn't match input", origfmt);
55
        fmt++; buf++;
56
    }
57
    if (!*buf)
58
        throw cRuntimeError("cFileCommBuffer: unpack(): premature end of input (format prefix '%s' missing)", origfmt);
59
    fmt++; buf++;
60
    pos = buf-buffer;
61
}
62

    
63
static void sread(char *buffer, int& pos, const char *fmt, void *d)
64
{
65
    matchtype(buffer, pos, fmt);
66
    char *buf = buffer+pos;
67
    setlocale(LC_NUMERIC, "C");
68
    if (sscanf(buf,fmt,d)!=1)
69
        throw cRuntimeError("cFileCommBuffer: unpack(): could not convert data");
70
    // skip data + delimiter whitespace
71
    while (*buf && *buf!=' ' && *buf!='\n') buf++;
72
    while (*buf==' ' || *buf=='\n') buf++;
73
    pos = buf-buffer;
74
}
75

    
76
cFileCommBuffer::cFileCommBuffer()
77
{
78
}
79

    
80
cFileCommBuffer::~cFileCommBuffer()
81
{
82
}
83

    
84
void cFileCommBuffer::setMessageSize(int size)
85
{
86
    mMsgSize = size;
87
    mPosition = 0;
88

    
89
    // add a terminating NULL character
90
    ASSERT(mBufferSize>mMsgSize);
91
    mBuffer[size] = '\0';
92
}
93

    
94
void cFileCommBuffer::pack(char d)
95
{
96
    extendBufferFor(16);
97
    STORE("c %d",(int)d);
98
}
99

    
100
void cFileCommBuffer::pack(unsigned char d)
101
{
102
    extendBufferFor(16);
103
    STORE("uc %u",(unsigned int)d);
104
}
105

    
106
void cFileCommBuffer::pack(bool d)
107
{
108
    extendBufferFor(16);
109
    STORE("b %d",(int)d);
110
}
111

    
112
void cFileCommBuffer::pack(short d)
113
{
114
    extendBufferFor(16);
115
    STORE("s %d",(int)d);
116
}
117

    
118
void cFileCommBuffer::pack(unsigned short d)
119
{
120
    extendBufferFor(16);
121
    STORE("us %u",(unsigned int)d);
122
}
123

    
124
void cFileCommBuffer::pack(int d)
125
{
126
    extendBufferFor(16);
127
    STORE("i %d",d);
128
}
129

    
130
void cFileCommBuffer::pack(unsigned int d)
131
{
132
    extendBufferFor(16);
133
    STORE("ui %u",d);
134
}
135

    
136
void cFileCommBuffer::pack(long d)
137
{
138
    extendBufferFor(16);
139
    STORE("l %ld",d);
140
}
141

    
142
void cFileCommBuffer::pack(unsigned long d)
143
{
144
    extendBufferFor(16);
145
    STORE("ul %lu",d);
146
}
147

    
148
void cFileCommBuffer::pack(opp_long_long d)
149
{
150
    extendBufferFor(30);
151
    STORE("ll %"LL"d",d);
152
}
153

    
154
void cFileCommBuffer::pack(opp_unsigned_long_long d)
155
{
156
    extendBufferFor(30);
157
    STORE("ull %"LL"u",d);
158
}
159

    
160
void cFileCommBuffer::pack(float d)
161
{
162
    extendBufferFor(30);
163
    STORE("f %g",d);
164
}
165

    
166
void cFileCommBuffer::pack(double d)
167
{
168
    extendBufferFor(30);
169
    STORE("d %g",d);
170
}
171

    
172
void cFileCommBuffer::pack(long double d)
173
{
174
    // packing as double because "%Lg" does not work on MinGW, see
175
    // http://www.mingw.org/MinGWiki/index.php/long%20double
176
    extendBufferFor(30);
177
    STORE("ld %g",(double)d);
178
}
179

    
180
// pack a string
181
void cFileCommBuffer::pack(const char *d)
182
{
183
    int len = d ? strlen(d) : 0;
184
    extendBufferFor(strlen(d)+16);
185
    sprintf(mBuffer+mMsgSize, "S %d|%s\n", len,d);
186
    mMsgSize+=strlen(mBuffer+mMsgSize);
187
}
188

    
189
void cFileCommBuffer::pack(const opp_string& d)
190
{
191
    pack(d.c_str());
192
}
193

    
194
void cFileCommBuffer::pack(SimTime d)
195
{
196
    pack((opp_long_long)d.raw());
197
}
198

    
199
void cFileCommBuffer::pack(const char *d, int size)
200
{
201
    extendBufferFor(size*sizeof(char));
202
    STOREARRAY(char,d,size);
203
}
204

    
205
void cFileCommBuffer::pack(const unsigned char *d, int size)
206
{
207
    extendBufferFor(size*sizeof(unsigned char));
208
    STOREARRAY(unsigned char,d,size);
209
}
210

    
211
void cFileCommBuffer::pack(const bool *d, int size)
212
{
213
    extendBufferFor(size*sizeof(bool));
214
    STOREARRAY(bool,d,size);
215
}
216

    
217
void cFileCommBuffer::pack(const short *d, int size)
218
{
219
    extendBufferFor(size*sizeof(short));
220
    STOREARRAY(short,d,size);
221
}
222

    
223
void cFileCommBuffer::pack(const unsigned short *d, int size)
224
{
225
    extendBufferFor(size*sizeof(unsigned short));
226
    STOREARRAY(unsigned short,d,size);
227
}
228

    
229
void cFileCommBuffer::pack(const int *d, int size)
230
{
231
    extendBufferFor(size*sizeof(int));
232
    STOREARRAY(int,d,size);
233
}
234

    
235
void cFileCommBuffer::pack(const unsigned int *d, int size)
236
{
237
    extendBufferFor(size*sizeof(unsigned int));
238
    STOREARRAY(unsigned int,d,size);
239
}
240

    
241
void cFileCommBuffer::pack(const long *d, int size)
242
{
243
    extendBufferFor(size*sizeof(long));
244
    STOREARRAY(long,d,size);
245
}
246

    
247
void cFileCommBuffer::pack(const unsigned long *d, int size)
248
{
249
    extendBufferFor(size*sizeof(unsigned long));
250
    STOREARRAY(unsigned long,d,size);
251
}
252

    
253
void cFileCommBuffer::pack(const opp_long_long *d, int size)
254
{
255
    extendBufferFor(size*sizeof(opp_long_long));
256
    STOREARRAY(opp_long_long,d,size);
257
}
258

    
259
void cFileCommBuffer::pack(const opp_unsigned_long_long *d, int size)
260
{
261
    extendBufferFor(size*sizeof(opp_unsigned_long_long));
262
    STOREARRAY(opp_unsigned_long_long,d,size);
263
}
264

    
265
void cFileCommBuffer::pack(const float *d, int size)
266
{
267
    extendBufferFor(size*sizeof(float));
268
    STOREARRAY(float,d,size);
269
}
270

    
271
void cFileCommBuffer::pack(const double *d, int size)
272
{
273
    extendBufferFor(size*sizeof(double));
274
    STOREARRAY(double,d,size);
275
}
276

    
277
void cFileCommBuffer::pack(const long double *d, int size)
278
{
279
    extendBufferFor(size*sizeof(long double));
280
    STOREARRAY(long double,d,size);
281
}
282

    
283
// pack string array
284
void cFileCommBuffer::pack(const char **d, int size)
285
{
286
    for (int i = 0; i < size; i++)
287
        pack(d[i]);
288
}
289

    
290
void cFileCommBuffer::pack(const opp_string *d, int size)
291
{
292
    for (int i = 0; i < size; i++)
293
        pack(d[i]);
294
}
295

    
296
void cFileCommBuffer::pack(const SimTime *d, int size)
297
{
298
    for (int i = 0; i < size; i++)
299
        pack(d[i]);
300
}
301

    
302
//--------------------------------
303

    
304
void cFileCommBuffer::unpack(char& d)
305
{
306
    int tmp;
307
    EXTRACT("c %d",tmp);
308
    d = tmp;
309
}
310

    
311
void cFileCommBuffer::unpack(unsigned char& d)
312
{
313
    int tmp;
314
    EXTRACT("uc %d",tmp);
315
    d = tmp;
316
}
317

    
318
void cFileCommBuffer::unpack(bool& d)
319
{
320
    int tmp;
321
    EXTRACT("b %d",tmp);
322
    d = tmp;
323
}
324

    
325
void cFileCommBuffer::unpack(short& d)
326
{
327
    int tmp;
328
    EXTRACT("s %d",tmp);
329
    d = tmp;
330
}
331

    
332
void cFileCommBuffer::unpack(unsigned short& d)
333
{
334
    int tmp;
335
    EXTRACT("us %d",tmp);
336
    d = tmp;
337
}
338

    
339
void cFileCommBuffer::unpack(int& d)
340
{
341
    EXTRACT("i %d",d);
342
}
343

    
344
void cFileCommBuffer::unpack(unsigned int& d)
345
{
346
    EXTRACT("ui %d",d);
347
}
348

    
349
void cFileCommBuffer::unpack(long& d)
350
{
351
    EXTRACT("l %ld",d);
352
}
353

    
354
void cFileCommBuffer::unpack(unsigned long& d)
355
{
356
    EXTRACT("ul %ld",d);
357
}
358

    
359
void cFileCommBuffer::unpack(opp_long_long& d)
360
{
361
    EXTRACT("ll %"LL"d",d);
362
}
363

    
364
void cFileCommBuffer::unpack(opp_unsigned_long_long& d)
365
{
366
    EXTRACT("ull %"LL"u",d);
367
}
368

    
369
void cFileCommBuffer::unpack(float& d)
370
{
371
    double tmp;
372
    EXTRACT("f %lg",tmp);
373
    d = tmp;
374
}
375

    
376
void cFileCommBuffer::unpack(double& d)
377
{
378
    EXTRACT("d %lg",d);
379
}
380

    
381
void cFileCommBuffer::unpack(long double& d)
382
{
383
    // packing as double because "%Lg" does not work on MinGW, see
384
    // http://www.mingw.org/MinGWiki/index.php/long%20double
385
    double tmp;
386
    EXTRACT("ld %lg",tmp);
387
    d = tmp;
388
}
389

    
390
// unpack a string
391
void cFileCommBuffer::unpack(const char *&d)
392
{
393
    const char *fmt = "S ";
394
    matchtype(mBuffer,mPosition,fmt);
395
    char *buf = mBuffer+mPosition;
396
    int len = atoi(buf);
397
    while (*buf && *buf!='|') buf++;
398
    if (!*buf)
399
        throw cRuntimeError("cFileCommBuffer: unpack(): missing '|' with in string format");
400
    buf++;
401
    char *tmp = new char[len+1];
402
    memcpy(tmp,buf,len);
403
    tmp[len] = '\0';
404
    buf+=len;
405
    // skip delimiter whitespace
406
    while (*buf==' ' || *buf=='\n') buf++;
407
    d = tmp;
408
    mPosition = buf-mBuffer;
409
}
410

    
411
void cFileCommBuffer::unpack(opp_string& d)
412
{
413
    char *s;
414
    unpack((const char *&)s);
415
    d.reserve(strlen(s)+1);
416
    strcpy(d.buffer(),s);
417
    delete [] s;
418
}
419

    
420
void cFileCommBuffer::unpack(SimTime& d)
421
{
422
    opp_long_long raw;
423
    unpack(raw);
424
    d.setRaw(raw);
425
}
426

    
427
void cFileCommBuffer::unpack(char *d, int size)
428
{
429
    EXTRACTARRAY(char,d,size);
430
}
431

    
432
void cFileCommBuffer::unpack(unsigned char *d, int size)
433
{
434
    EXTRACTARRAY(unsigned char,d,size);
435
}
436

    
437
void cFileCommBuffer::unpack(bool *d, int size)
438
{
439
    EXTRACTARRAY(bool,d,size);
440
}
441

    
442
void cFileCommBuffer::unpack(short *d, int size)
443
{
444
    EXTRACTARRAY(short,d,size);
445
}
446

    
447
void cFileCommBuffer::unpack(unsigned short *d, int size)
448
{
449
    EXTRACTARRAY(unsigned short,d,size);
450
}
451

    
452
void cFileCommBuffer::unpack(int *d, int size)
453
{
454
    EXTRACTARRAY(int,d,size);
455
}
456

    
457
void cFileCommBuffer::unpack(unsigned int *d, int size)
458
{
459
    EXTRACTARRAY(unsigned,d,size);
460
}
461

    
462
void cFileCommBuffer::unpack(long *d, int size)
463
{
464
    EXTRACTARRAY(long,d,size);
465
}
466

    
467
void cFileCommBuffer::unpack(unsigned long *d, int size)
468
{
469
    EXTRACTARRAY(unsigned long,d,size);
470
}
471

    
472
void cFileCommBuffer::unpack(opp_long_long *d, int size)
473
{
474
    EXTRACTARRAY(opp_long_long,d,size);
475
}
476

    
477
void cFileCommBuffer::unpack(opp_unsigned_long_long *d, int size)
478
{
479
    EXTRACTARRAY(opp_unsigned_long_long,d,size);
480
}
481

    
482
void cFileCommBuffer::unpack(float *d, int size)
483
{
484
    EXTRACTARRAY(float,d,size);
485
}
486

    
487
void cFileCommBuffer::unpack(double *d, int size)
488
{
489
    EXTRACTARRAY(double,d,size);
490
}
491

    
492
void cFileCommBuffer::unpack(long double *d, int size)
493
{
494
    EXTRACTARRAY(long double,d,size);
495
}
496

    
497
void cFileCommBuffer::unpack(const char **d, int size)
498
{
499
    for (int i = 0; i < size; i++)
500
        unpack(d[i]);
501
}
502

    
503
void cFileCommBuffer::unpack(opp_string *d, int size)
504
{
505
    for (int i = 0; i < size; i++)
506
        unpack(d[i]);
507
}
508

    
509
void cFileCommBuffer::unpack(SimTime *d, int size)
510
{
511
    for (int i = 0; i < size; i++)
512
        unpack(d[i]);
513
}
514