Project

General

Profile

Statistics
| Branch: | Revision:

root / src / sim / cflyweightstringpool.cc @ 3e29b8a0

History | View | Annotate | Download (3.44 KB)

1
//==========================================================================
2
//  CSTRINGPOOL.CC - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//==========================================================================
7

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

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

    
16
#include "cflyweightstringpool.h"
17
#include "cownedobject.h"
18
#include "stringutil.h"
19

    
20
USING_NAMESPACE
21

    
22
cFlyweightStringPool::cFlyweightStringPool(const char *poolName)
23
{
24
    name = opp_nulltoempty(poolName);
25
    alive = true;
26
}
27

    
28
cFlyweightStringPool::~cFlyweightStringPool()
29
{
30
    // do not release strings -- clients are supposed to call releaseString()
31
    // for their strings, so cStringPool gets empty by itself.
32

    
33
    // we may want to dump unreleased strings (except after Ctrl+C on Windows)
34
    //TODO: put it into some #ifdef DEVELOPER_DEBUG
35
    //if (!cStaticFlag::isExiting())
36
    //    dump();
37

    
38
    alive = false;
39
}
40

    
41
void cFlyweightStringPool::dump() const
42
{
43
    if (!pool.empty())
44
    {
45
        printf("contents of stringpool \"%s\":\n", name.c_str());
46
        for (StringIntMap::const_iterator it = pool.begin(); it!=pool.end(); ++it)
47
            printf("  \"%s\" %p, %d ref(s)\n", it->first, it->first, it->second);
48
    }
49
}
50

    
51
const char *cFlyweightStringPool::get(const char *s)
52
{
53

    
54
    if (!cStaticFlag::isSet())
55
        {fprintf(stderr, "ERROR: cStringPool::get(\"%s\") invoked outside main() -- please do not use cStringPool from global objects", s); return opp_strdup(s);}
56
    if (!s)
57
        return NULL;
58

    
59
    StringIntMap::iterator it = pool.find(const_cast<char *>(s));
60
    if (it==pool.end())
61
    {
62
        // allocate new string
63
        char *str = new char[strlen(s)+1];
64
        strcpy(str, s);
65
        pool[str] = 1;
66
        return str;
67
    }
68
    else
69
    {
70
        // increment refcount of existing string
71
        it->second++;
72
        return it->first;
73
    }
74
}
75

    
76
const char *cFlyweightStringPool::peek(const char *s) const
77
{
78

    
79
    if (!cStaticFlag::isSet())
80
        {fprintf(stderr, "ERROR: cStringPool::peek(\"%s\") invoked outside main() -- please do not use cStringPool from global objects", s); return false;}
81
    if (!s)
82
        return NULL;
83

    
84
    StringIntMap::const_iterator it = pool.find(const_cast<char *>(s));
85
    return it==pool.end() ? NULL : it->first;
86

    
87
}
88

    
89
void cFlyweightStringPool::release(const char *s)
90
{
91
    if (!s)
92
        return;
93

    
94
    if (!alive)
95
        return; // prevents crash when stringpool is a global object, and program exits via exit()
96

    
97
    if (!cStaticFlag::isSet())
98
        {fprintf(stderr, "Warning: cStringPool::release(): string \"%s\" released too late, after main() already exited\n", s); return;}
99

    
100
    StringIntMap::iterator it = pool.find(const_cast<char *>(s));
101

    
102
    // sanity checks
103
    if (it==pool.end())
104
        {fprintf(stderr, "ERROR: cStringPool::release(): string %p \"%s\" not in stringpool\n", s, s); return;}
105
    if (it->first!=s)
106
        {fprintf(stderr, "ERROR: cStringPool::release(): wrong string pointer %p \"%s\", stringpool has a different copy of the same string\n", s, s); return;}
107

    
108
    // decrement refcount or release string
109
    if (--(it->second) == 0)
110
    {
111
        delete [] s; // that is, it->first
112
        pool.erase(it);
113
    }
114

    
115
}
116

    
117