Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / indexedvectorfilereader2.cc @ cbd2c699

History | View | Annotate | Download (5.4 KB)

1
//=========================================================================
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
}
187