Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / indexedvectorfilereader2.cc @ a3be1d55

History | View | Annotate | Download (5.4 KB)

1 01873262 Georg Kunz
//=========================================================================
2
//  INDEXEDVECTORFILEREADER2.CC - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Tamas Borbely
7
//
8
//=========================================================================
9
10
/*--------------------------------------------------------------*
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16
17
#include "platmisc.h"
18
#include "opp_ctype.h"
19
#include "channel.h"
20
#include "scaveutils.h"
21
#include "vectorfilereader.h"
22
#include "indexedvectorfilereader2.h"
23
24
USING_NAMESPACE
25
26
using namespace std;
27
28
#define LL  INT64_PRINTF_FORMAT
29
30
IndexedVectorFileReaderNode2::IndexedVectorFileReaderNode2(const char *filename, size_t bufferSize) :
31
  ReaderNode(filename, bufferSize), index(NULL), fFinished(false)
32
{
33
34
}
35
36
IndexedVectorFileReaderNode2::~IndexedVectorFileReaderNode2()
37
{
38
    if (index) {
39
        delete index;
40
        index = NULL;
41
    }
42
}
43
44
Port *IndexedVectorFileReaderNode2::addVector(const VectorResult &vector)
45
{
46
    PortData& portdata = ports[vector.vectorId];
47
    portdata.ports.push_back(Port(this));
48
    Port& port = portdata.ports.back();
49
    return &port;
50
}
51
52
bool IndexedVectorFileReaderNode2::isReady() const
53
{
54
    return true;
55
}
56
57
void IndexedVectorFileReaderNode2::process()
58
{
59
    if (!index)
60
        readIndexFile();
61
62
    // read one block from each vector
63
64
    // FIXME read the blocks sequentially instead of round-robin
65
    bool found = false;
66
    for (PortMap::iterator it = ports.begin(); it != ports.end(); ++it)
67
    {
68
        PortData &portData = it->second;
69
        found |= readNextBlock(portData);
70
    }
71
72
73
    if (!found)
74
        fFinished = true;
75
}
76
77
bool IndexedVectorFileReaderNode2::isFinished() const
78
{
79
    return fFinished;
80
}
81
82
void IndexedVectorFileReaderNode2::readIndexFile()
83
{
84
    const char *fn = filename.c_str();
85
86
    if (!IndexFile::isVectorFile(fn))
87
        throw opp_runtime_error("indexed vector file reader: not a vector file, file %s", fn);
88
    if (!IndexFile::isIndexFileUpToDate(fn))
89
        throw opp_runtime_error("indexed vector file reader: index file is not up to date, file %s", fn);
90
91
    string indexFileName = IndexFile::getIndexFileName(fn);
92
    IndexFileReader reader(indexFileName.c_str());
93
    index = reader.readAll();
94
95
    for (PortMap::iterator it = ports.begin(); it != ports.end(); ++it)
96
    {
97
        int vectorId = it->first;
98
        PortData &portData = it->second;
99
100
        portData.vector = index->getVectorById(vectorId);
101
102
        if (!portData.vector)
103
            throw opp_runtime_error("indexed vector file reader: vector %d not found, file %s",
104
                                        vectorId, indexFileName.c_str());
105
    }
106
}
107
108
bool IndexedVectorFileReaderNode2::readNextBlock(PortData &portData)
109
{
110
    assert(portData.vector);
111
112
    VectorData *vector = portData.vector;
113
    if (portData.currentBlockIndex >= (int)vector->blocks.size())
114
        return false;
115
116
    const char *file = filename.c_str();
117
    file_offset_t offset;
118
#define CHECK(cond, msg) {if (!cond) throw opp_runtime_error(msg ", file %s, offset %"LL"d", file, (int64)offset); }
119
120
121
    Block &block = vector->blocks[portData.currentBlockIndex++];
122
    file_offset_t startOffset = block.startOffset;
123
    long count = block.getCount();
124
125
    reader.seekTo(startOffset);
126
127
    char *line;
128
    for (long k = 0; k < count && (line=reader.getNextLineBufferPointer())!=NULL; ++k)
129
    {
130
        offset = reader.getCurrentLineStartOffset();
131
        int length = reader.getCurrentLineLength();
132
        tokenizer.tokenize(line, length);
133
134
        int numtokens = tokenizer.numTokens();
135
        char **vec = tokenizer.tokens();
136
        int vectorId;
137
138
        // check vector id
139
        CHECK((numtokens >= 3) && opp_isdigit(vec[0][0]), "vector file reader: data line too short");
140
        CHECK(parseInt(vec[0], vectorId), "invalid vector file syntax: invalid vector id column");
141
        CHECK(vectorId == vector->vectorId, "vector file reader: unexpected vector id");
142
143
        // parse columns
144
        Datum a = parseColumns(vec, numtokens, vector->columns, file, -1, offset);
145
146
        // write to port(s)
147
        for (PortVector::const_iterator port = portData.ports.begin(); port != portData.ports.end(); ++port)
148
            port->getChannel()->write(&a,1);
149
    }
150
151
    return true;
152
}
153
154
//-----
155
156
const char *IndexedVectorFileReaderNode2Type::getDescription() const
157
{
158
    return "Reads indexed output vector files.";
159
}
160
161
void IndexedVectorFileReaderNode2Type::getAttributes(StringMap& attrs) const
162
{
163
    attrs["filename"] = "name of the output vector file (.vec)";
164
}
165
166
Node *IndexedVectorFileReaderNode2Type::create(DataflowManager *mgr, StringMap& attrs) const
167
{
168
    checkAttrNames(attrs);
169
170
    const char *fname = attrs["filename"].c_str();
171
172
    Node *node = new IndexedVectorFileReaderNode2(fname);
173
    node->setNodeType(this);
174
    mgr->addNode(node);
175
    return node;
176
}
177
178
Port *IndexedVectorFileReaderNode2Type::getPort(Node *node, const char *portname) const
179
{
180
    // vector id is used as port name
181
    IndexedVectorFileReaderNode2 *node1 = dynamic_cast<IndexedVectorFileReaderNode2 *>(node);
182
    VectorResult vector;
183
    if (!parseInt(portname, vector.vectorId))
184
        throw opp_runtime_error("indexed file reader node: port should be a vector id, received: %s", portname);
185
    return node1->addVector(vector);
186
}