Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / vectorfilewriter.cc @ 81ad8b66

History | View | Annotate | Download (6.13 KB)

1
//=========================================================================
2
//  VECTORFILEWRITER.CC - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga
7
//
8
//=========================================================================
9

    
10
/*--------------------------------------------------------------*
11
  Copyright (C) 1992-2008 Andras Varga
12
  Copyright (C) 2006-2008 OpenSim Ltd.
13

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

    
18
#include <stdlib.h>
19
#include <locale.h>
20

    
21
#include "channel.h"
22
#include "vectorfilewriter.h"
23
#include "stringutil.h"
24

    
25
#define VECTOR_FILE_VERSION 2
26

    
27
#define LL  INT64_PRINTF_FORMAT  /* abbreviation */
28

    
29
#ifdef CHECK
30
#undef CHECK
31
#endif
32

    
33
USING_NAMESPACE
34

    
35
#define CHECK(fprintf)    if (fprintf<0) throw opp_runtime_error("Cannot write output vector file `%s'", fileName.c_str())
36

    
37
VectorFileWriterNode::VectorFileWriterNode(const char *fileName, const char *fileHeader)
38
{
39
    f = NULL;
40
    this->prec = DEFAULT_PRECISION;
41
    this->fileName = fileName;
42
    this->fileHeader = (fileHeader ? fileHeader : "");
43
}
44

    
45
VectorFileWriterNode::~VectorFileWriterNode()
46
{
47
}
48

    
49
Port *VectorFileWriterNode::addVector(const VectorResult &vector)
50
{
51
    ports.push_back(Pair(vector.vectorId, vector.moduleNameRef->c_str(), vector.nameRef->c_str(), vector.columns.c_str(), this));
52
    return &(ports.back().port);
53
}
54

    
55
bool VectorFileWriterNode::isReady() const
56
{
57
    for (PortVector::const_iterator it=ports.begin(); it!=ports.end(); it++)
58
        if (it->port()->length()>0)
59
            return true;
60
    return false;
61
}
62

    
63
void VectorFileWriterNode::process()
64
{
65
    // open file if needed
66
    if (!f)
67
    {
68
        f = fopen(fileName.c_str(), "w");
69
        if (!f)
70
            throw opp_runtime_error("cannot open `%s' for write", fileName.c_str());
71

    
72
        setlocale(LC_NUMERIC, "C");
73

    
74
        // print file header and vector declarations
75
        CHECK(fprintf(f,"%s\n\n", fileHeader.c_str()));
76
        CHECK(fprintf(f,"version %d\n", VECTOR_FILE_VERSION));
77

    
78
        for (PortVector::iterator it=ports.begin(); it!=ports.end(); it++)
79
            CHECK(fprintf(f, "vector %d  %s  %s  %s\n", it->id,
80
                             QUOTE(it->moduleName.c_str()),
81
                             QUOTE(it->name.c_str()), it->columns.c_str()));
82
    }
83

    
84
    for (PortVector::iterator it=ports.begin(); it!=ports.end(); it++)
85
    {
86
        Channel *chan = it->port();
87
        int n = chan->length();
88
        std::string &columns = it->columns;
89
        int colno = columns.size();
90
        Datum a;
91
        char buf[64];
92
        char *endp;
93

    
94
        if (colno == 2 && columns[0] == 'T' && columns[1] == 'V')
95
        {
96
            for (int i=0; i<n; i++)
97
            {
98
                chan->read(&a,1);
99
                if (a.xp.isNil())
100
                {
101
                    CHECK(fprintf(f,"%d\t%.*g\t%.*g\n", it->id, prec, a.x, prec, a.y));
102
                }
103
                else
104
                {
105
                    CHECK(fprintf(f,"%d\t%s\t%.*g\n", it->id, BigDecimal::ttoa(buf, a.xp, endp), prec, a.y));
106
                }
107
            }
108
        }
109
        else if (colno == 3 && columns[0] == 'E' && columns[1] == 'T' && columns[2] == 'V')
110
        {
111
            for (int i=0; i<n; i++)
112
            {
113
                chan->read(&a,1);
114
                if (a.xp.isNil())
115
                {
116
                    CHECK(fprintf(f,"%d\t%"LL"d\t%.*g\t%.*g\n", it->id, a.eventNumber, prec, a.x, prec, a.y));
117
                }
118
                else
119
                {
120
                    CHECK(fprintf(f,"%d\t%"LL"d\t%s\t%.*g\n", it->id, a.eventNumber, BigDecimal::ttoa(buf, a.xp, endp), prec, a.y));
121
                }
122
            }
123
        }
124
        else
125
        {
126
            for (int i=0; i<n; i++)
127
            {
128
                chan->read(&a,1);
129
                CHECK(fprintf(f,"%d",it->id));
130
                for (int j=0; j<colno; ++j)
131
                {
132
                    CHECK(fputc('\t', f));
133
                    switch (columns[j])
134
                    {
135
                    case 'T':
136
                        if (a.xp.isNil())
137
                        {
138
                            CHECK(fprintf(f,"%.*g", prec, a.x));
139
                        }
140
                        else
141
                        {
142
                            CHECK(fprintf(f, "%s", BigDecimal::ttoa(buf, a.xp, endp)));
143
                        }
144
                        break;
145
                    case 'V': CHECK(fprintf(f,"%.*g", prec, a.y)); break;
146
                    case 'E': CHECK(fprintf(f,"%"LL"d", a.eventNumber)); break;
147
                    default: throw opp_runtime_error("unknown column type: '%c' while writing %s", columns[j], fileName.c_str());
148
                    }
149
                }
150
                CHECK(fputc('\n', f));
151

    
152
            }
153
        }
154
    }
155
}
156

    
157
bool VectorFileWriterNode::isFinished() const
158
{
159
    for (PortVector::const_iterator it=ports.begin(); it!=ports.end(); it++)
160
        if (!it->port()->isClosing() || it->port()->length()>0)
161
            return false;
162
    return true;
163
}
164

    
165
//-------
166

    
167
const char *VectorFileWriterNodeType::getDescription() const
168
{
169
    return "Writes the output (several streams) into an output vector file.";
170
}
171

    
172
void VectorFileWriterNodeType::getAttributes(StringMap& attrs) const
173
{
174
    attrs["filename"] = "name of the output vector file (.vec)";
175
}
176

    
177
Node *VectorFileWriterNodeType::create(DataflowManager *mgr, StringMap& attrs) const
178
{
179
    checkAttrNames(attrs);
180

    
181
    const char *fileName = attrs["filename"].c_str();
182

    
183
    Node *node = new VectorFileWriterNode(fileName);
184
    node->setNodeType(this);
185
    mgr->addNode(node);
186
    return node;
187
}
188

    
189
Port *VectorFileWriterNodeType::getPort(Node *node, const char *portname) const
190
{
191
    // vector id is used as port name
192
    VectorFileWriterNode *node1 = dynamic_cast<VectorFileWriterNode *>(node);
193
    VectorResult vector;
194
    std::string moduleName = "n/a", name = "n/a";
195
    vector.vectorId = atoi(portname);  // FIXME check it's numeric at all
196
    vector.moduleNameRef = &moduleName;
197
    vector.nameRef = &name;
198
    vector.columns = "TV";             // old vector file format
199
    return node1->addVector(vector);
200
}
201