Project

General

Profile

Statistics
| Branch: | Revision:

root / src / nedxml / nedutil.cc @ 79bb12dc

History | View | Annotate | Download (7.05 KB)

1
//==========================================================================
2
// nedutil.cc - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
// Contents:
8
//   misc util functions
9
//
10
//==========================================================================
11

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

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

    
20
#include <stdio.h>
21
#include <string.h>
22
#include <math.h>
23
#include "nedexception.h"
24
#include "nedutil.h"
25
#include "stringutil.h"
26
#include "displaystring.h"
27
#include "nedelements.h"
28

    
29
USING_NAMESPACE
30

    
31
static void renameTag(DisplayString& ds, const char *from, const char *to)
32
{
33
    int n = ds.getNumArgs(from);
34
    for (int i=0; i<n; i++)
35
        ds.setTagArg(to, i, ds.getTagArg(from,i));
36
    ds.removeTag(from);
37
}
38

    
39
std::string DisplayStringUtil::upgradeBackgroundDisplayString(const char *s)
40
{
41
    DisplayString ds;
42
    parseDisplayString(s, ds);
43
    renameTag(ds, "p",  "bgp");
44
    renameTag(ds, "b",  "bgb");
45
    renameTag(ds, "tt", "bgtt");
46
    if (ds.containsTag("o"))
47
    {
48
        ds.setTagArg("bgb", 2, ds.getTagArg("o",0));
49
        ds.setTagArg("bgb", 3, ds.getTagArg("o",1));
50
        ds.setTagArg("bgb", 4, ds.getTagArg("o",2));
51
        ds.removeTag("o");
52
    }
53
    return ds.str();
54
}
55

    
56
std::string DisplayStringUtil::upgradeSubmoduleDisplayString(const char *s)
57
{
58
    DisplayString ds;
59
    parseDisplayString(s, ds);
60
    if (ds.containsTag("o"))
61
    {
62
        ds.setTagArg("b", 3, ds.getTagArg("o",0));
63
        ds.setTagArg("b", 4, ds.getTagArg("o",1));
64
        ds.setTagArg("b", 5, ds.getTagArg("o",2));
65
        ds.removeTag("o");
66
    }
67
    return ds.str();
68
}
69

    
70
std::string DisplayStringUtil::upgradeConnectionDisplayString(const char *s)
71
{
72
    DisplayString ds;
73
    parseDisplayString(s, ds);
74
    renameTag(ds, "o", "ls");
75
    // FIXME TT tag: the color parameter (old format 2nd) should go to the 3rd position in the new format
76
    // the 2nd par is position (was not supported previously)
77
    return ds.str();
78
}
79

    
80
void DisplayStringUtil::parseDisplayString(const char *s, DisplayString& ds)
81
{
82
    if (!ds.parse(s))
83
        throw opp_runtime_error("parse error in display string `%s'", s);
84
}
85

    
86
std::string DisplayStringUtil::toOldBackgroundDisplayString(const char *s)
87
{
88
    DisplayString ds;
89
    parseDisplayString(s, ds);
90
    for (int i=0; i<ds.getNumTags(); i++)
91
    {
92
        const char *t = ds.getTagName(i);
93
        if (strcmp(t,"bgp")!=0 && strcmp(t,"bgb")!=0 && strcmp(t,"bgtt")!=0)
94
            ds.removeTag(i--);
95
    }
96
    renameTag(ds, "bgp",  "p");
97
    renameTag(ds, "bgb",  "b");
98
    renameTag(ds, "bgtt", "tt");
99
    if (ds.getNumArgs("b")>3)
100
    {
101
        ds.setTagArg("o", 0, ds.getTagArg("b",3));
102
        ds.setTagArg("o", 1, ds.getTagArg("b",4));
103
        ds.setTagArg("o", 2, ds.getTagArg("b",5));
104
        ds.setTagArg("b", 3, "");
105
        ds.setTagArg("b", 4, "");
106
        ds.setTagArg("b", 5, "");
107
    }
108
    return ds.str();
109
}
110

    
111
std::string DisplayStringUtil::toOldSubmoduleDisplayString(const char *s)
112
{
113
    DisplayString ds;
114
    parseDisplayString(s, ds);
115
    if (ds.getNumArgs("b")>3)
116
    {
117
        ds.setTagArg("o", 0, ds.getTagArg("b",3));
118
        ds.setTagArg("o", 1, ds.getTagArg("b",4));
119
        ds.setTagArg("o", 2, ds.getTagArg("b",5));
120
        ds.setTagArg("b", 3, "");
121
        ds.setTagArg("b", 4, "");
122
        ds.setTagArg("b", 5, "");
123
    }
124
    return ds.str();
125
}
126

    
127
std::string DisplayStringUtil::toOldConnectionDisplayString(const char *s)
128
{
129
    DisplayString ds;
130
    parseDisplayString(s, ds);
131
    renameTag(ds, "ls", "o");
132
    return ds.str();
133
}
134

    
135
//----
136

    
137
const char *NEDElementUtil::getLocalStringProperty(NEDElement *parent, const char *name)
138
{
139
    return propertyAsString(getLocalProperty(parent, name));
140
}
141

    
142
bool NEDElementUtil::getLocalBoolProperty(NEDElement *parent, const char *name)
143
{
144
    return propertyAsBool(getLocalProperty(parent, name));
145
}
146

    
147
PropertyElement *NEDElementUtil::getLocalProperty(NEDElement *parent, const char *name)
148
{
149
    // find first as direct child, then in potential "parameters" section
150
    PropertyElement *result = (PropertyElement *)parent->getFirstChildWithAttribute(NED_PROPERTY, "name", name);
151
    if (result)
152
        return result;
153
    parent = parent->getFirstChildWithTag(NED_PARAMETERS);
154
    if (parent)
155
        result = (PropertyElement *)parent->getFirstChildWithAttribute(NED_PROPERTY, "name", name);
156
    return result;
157
}
158

    
159
LiteralElement *NEDElementUtil::getTheOnlyValueFrom(PropertyElement *property)
160
{
161
    // first (only?) value of the default (only?) key
162
    if (!property)
163
        return NULL;
164
    NEDElement *propertyKey = property->getFirstChildWithAttribute(NED_PROPERTY_KEY, "name", "");
165
    int count = property->getNumChildrenWithTag(NED_PROPERTY_KEY);
166
    if (count != (propertyKey ? 1 : 0))
167
        throw NEDException(property, "should contain a single value");
168
    if (!propertyKey)
169
        return NULL;
170
    if (propertyKey->getNumChildrenWithTag(NED_LITERAL) >= 2)
171
        throw NEDException(property, "should contain a single value");
172
    return (LiteralElement *)propertyKey->getFirstChildWithTag(NED_LITERAL);
173
}
174

    
175
bool NEDElementUtil::propertyAsBool(PropertyElement *property)
176
{
177
    if (!property)
178
        return false;
179
    LiteralElement *literal = getTheOnlyValueFrom(property);
180
    if (!literal)
181
        return true;  // so that @isNetwork is equivalent to @isNetwork(true)
182
    const char *value = literal->getValue();
183
    if (strcmp(value, "true")!=0 && strcmp(value, "false")!=0)
184
        throw NEDException(property, "boolean value expected");
185
    return value[0]=='t';
186
}
187

    
188
const char *NEDElementUtil::propertyAsString(PropertyElement *property)
189
{
190
    if (!property)
191
        return NULL;
192
    LiteralElement *literal = getTheOnlyValueFrom(property);
193
    if (!literal)
194
        return NULL;
195
    return literal->getValue(); // return anything as string
196
}
197

    
198
int NEDElementUtil::compare(NEDElement *node1, NEDElement *node2)
199
{
200
    int diff;
201
    if ((diff=node1->getTagCode()-node2->getTagCode()) != 0)
202
        return diff;
203
    for (int i=0; i<node1->getNumAttributes(); i++)
204
        if ((diff = opp_strcmp(node1->getAttribute(i), node2->getAttribute(i)))!=0)
205
            return diff;
206
    return 0;
207
}
208

    
209
int NEDElementUtil::compareTree(NEDElement *node1, NEDElement *node2)
210
{
211
    int diff;
212
    if ((diff = compare(node1, node2)) != 0)
213
        return diff;
214

    
215
    // recurse
216
    for (NEDElement *child1 = node1->getFirstChild(), *child2 = node2->getFirstChild();
217
         child1 || child2;
218
         child1 = child1->getNextSibling(), child2 = child2->getNextSibling())
219
    {
220
        if (!child1 || !child2)
221
            return child1 ? -1 : 1;
222
        if ((diff = compareTree(child1, child2)) != 0)
223
            return diff;
224
    }
225
    return 0;
226
}
227

    
228
bool NEDElementUtil::isNEDType(NEDElement *node)
229
{
230
    int tag = node->getTagCode();
231
    return tag==NED_SIMPLE_MODULE || tag==NED_MODULE_INTERFACE || tag==NED_COMPOUND_MODULE ||
232
           tag==NED_CHANNEL_INTERFACE || tag==NED_CHANNEL;
233
}
234