Coverage Report

Created: 2026-05-16 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/dcmdata/libsrc/dcvrui.cc
Line
Count
Source
1
/*
2
 *
3
 *  Copyright (C) 1994-2024, OFFIS e.V.
4
 *  All rights reserved.  See COPYRIGHT file for details.
5
 *
6
 *  This software and supporting documentation were developed by
7
 *
8
 *    OFFIS e.V.
9
 *    R&D Division Health
10
 *    Escherweg 2
11
 *    D-26121 Oldenburg, Germany
12
 *
13
 *
14
 *  Module:  dcmdata
15
 *
16
 *  Author:  Gerd Ehlers, Andreas Barth
17
 *
18
 *  Purpose: Implementation of class DcmUniqueIdentifier
19
 *
20
 */
21
22
23
#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
24
25
#include "dcmtk/ofstd/ofstream.h"
26
#include "dcmtk/ofstd/ofstring.h"
27
#include "dcmtk/ofstd/ofstd.h"
28
#include "dcmtk/dcmdata/dcvrui.h"
29
#include "dcmtk/dcmdata/dcuid.h"
30
31
0
#define MAX_UI_LENGTH 64
32
33
34
// ********************************
35
36
37
DcmUniqueIdentifier::DcmUniqueIdentifier(const DcmTag &tag,
38
                                         const Uint32 len)
39
0
  : DcmByteString(tag, len)
40
0
{
41
    /* padding character is NULL not a space! */
42
0
    setPaddingChar('\0');
43
0
    setMaxLength(MAX_UI_LENGTH);
44
0
    setNonSignificantChars("\\");
45
0
}
46
47
48
DcmUniqueIdentifier::DcmUniqueIdentifier(const DcmUniqueIdentifier &old)
49
0
  : DcmByteString(old)
50
0
{
51
0
}
52
53
54
DcmUniqueIdentifier::~DcmUniqueIdentifier()
55
0
{
56
0
}
57
58
59
DcmUniqueIdentifier &DcmUniqueIdentifier::operator=(const DcmUniqueIdentifier &obj)
60
0
{
61
0
    DcmByteString::operator=(obj);
62
0
    return *this;
63
0
}
64
65
66
OFCondition DcmUniqueIdentifier::copyFrom(const DcmObject& rhs)
67
0
{
68
0
  if (this != &rhs)
69
0
  {
70
0
    if (rhs.ident() != ident()) return EC_IllegalCall;
71
0
    *this = OFstatic_cast(const DcmUniqueIdentifier &, rhs);
72
0
  }
73
0
  return EC_Normal;
74
0
}
75
76
77
// ********************************
78
79
80
DcmEVR DcmUniqueIdentifier::ident() const
81
0
{
82
0
    return EVR_UI;
83
0
}
84
85
86
OFCondition DcmUniqueIdentifier::checkValue(const OFString &vm,
87
                                            const OFBool /*oldFormat*/)
88
0
{
89
0
    OFString strVal;
90
    /* get "raw value" without any modifications (if possible) */
91
0
    OFCondition l_error = getStringValue(strVal);
92
0
    if (l_error.good())
93
0
        l_error = DcmUniqueIdentifier::checkStringValue(strVal, vm);
94
0
    return l_error;
95
0
}
96
97
98
// ********************************
99
100
101
void DcmUniqueIdentifier::print(STD_NAMESPACE ostream &out,
102
                                const size_t flags,
103
                                const int level,
104
                                const char * /*pixelFileName*/,
105
                                size_t * /*pixelCounter*/)
106
0
{
107
0
    if (valueLoaded())
108
0
    {
109
        /* get string data (possibly multi-valued) */
110
0
        char *stringVal = NULL;
111
0
        Uint32 stringLen = 0;
112
0
        getString(stringVal, stringLen);
113
0
        if ((stringVal != NULL) && (stringLen > 0))
114
0
        {
115
0
            const char *symbol = NULL;
116
0
            if (!(flags & DCMTypes::PF_doNotMapUIDsToNames))
117
0
            {
118
                /* check whether UID number can be mapped to a UID name */
119
0
                symbol = dcmFindNameOfUID(stringVal);
120
0
            }
121
0
            if ((symbol != NULL) && (strlen(symbol) > 0))
122
0
            {
123
0
                const size_t bufSize = strlen(symbol) + 1 /* for "=" */ + 1;
124
0
                char *buffer = new char[bufSize];
125
0
                if (buffer != NULL)
126
0
                {
127
                    /* concatenate "=" and the UID name */
128
0
                    OFStandard::strlcpy(buffer, "=", bufSize);
129
0
                    OFStandard::strlcat(buffer, symbol, bufSize);
130
0
                    printInfoLine(out, flags, level, buffer, NULL /*tag*/, OFFalse /*isInfo*/);
131
                    /* delete temporary character buffer */
132
0
                    delete[] buffer;
133
0
                } else /* could not allocate buffer */
134
0
                    DcmByteString::print(out, flags, level);
135
0
            } else /* no symbol (UID name) found or mapping switched off */
136
0
                DcmByteString::print(out, flags, level);
137
0
        } else
138
0
            printInfoLine(out, flags, level, "(no value available)");
139
0
    } else
140
0
        printInfoLine(out, flags, level, "(not loaded)");
141
0
}
142
143
144
// ********************************
145
146
147
OFCondition DcmUniqueIdentifier::getOFString(OFString &stringVal,
148
                                             const unsigned long pos,
149
                                             OFBool normalize)
150
0
{
151
0
    OFCondition l_error = DcmByteString::getOFString(stringVal, pos, normalize);
152
0
    if (l_error.good() && normalize)
153
0
        normalizeString(stringVal, !MULTIPART, !DELETE_LEADING, DELETE_TRAILING, getPaddingChar() /* NULL-byte */);
154
0
    return l_error;
155
0
}
156
157
158
// ********************************
159
160
161
OFCondition DcmUniqueIdentifier::putString(const char *stringVal)
162
0
{
163
    /* determine length of the string value */
164
0
    const size_t stringLen = (stringVal != NULL) ? strlen(stringVal) : 0;
165
    /* call the real function */
166
0
    return putString(stringVal, OFstatic_cast(Uint32, stringLen));
167
0
}
168
169
170
OFCondition DcmUniqueIdentifier::putString(const char *stringVal,
171
                                           const Uint32 stringLen)
172
0
{
173
0
    const char *uid = stringVal;
174
0
    Uint32 uidLen = stringLen;
175
    /* check whether parameter contains a UID name instead of a UID number */
176
0
    if ((stringVal != NULL) && (stringVal[0] == '='))
177
0
    {
178
0
        uid = dcmFindUIDFromName(stringVal + 1);
179
        /* check whether UID name could be mapped to a UID number */
180
0
        if (uid == NULL)
181
0
        {
182
0
            DCMDATA_DEBUG("DcmUniqueIdentifier::putString() cannot map UID name '"
183
0
                << OFSTRING_GUARD(stringVal + 1) << "' to UID value");
184
            /* return with an error */
185
0
            return EC_UnknownUIDName;
186
0
        } else
187
0
            uidLen = OFstatic_cast(Uint32, strlen(uid));
188
0
    }
189
    /* call inherited method to set the UID string */
190
0
    return DcmByteString::putString(uid, uidLen);
191
0
}
192
193
194
// ********************************
195
196
OFCondition DcmUniqueIdentifier::makeMachineByteString(const Uint32 length)
197
0
{
198
    /* get string data */
199
0
    char *value = OFstatic_cast(char *, getValue());
200
    /* determine initial string length */
201
0
    const size_t len = (length == 0) ? getLengthField() : length;
202
0
    if ((value != NULL) && (len > 0))
203
0
    {
204
        /* check whether string representation is not the internal one */
205
0
        if (getStringMode() != DCM_MachineString)
206
0
        {
207
            /* check whether automatic input data correction is enabled */
208
0
            if (dcmEnableAutomaticInputDataCorrection.get())
209
0
            {
210
                /*
211
                ** Remove any leading, embedded, or trailing white space.
212
                ** This manipulation attempts to correct problems with
213
                ** incorrectly encoded UIDs which have been observed in
214
                ** some images.
215
                */
216
0
                size_t curPos = 0;
217
0
                for (size_t i = 0; i < len; i++)
218
0
                {
219
0
                   if (!OFStandard::isspace(value[i]))
220
0
                      value[curPos++] = value[i];
221
0
                }
222
                /* there was at least one space character in the string */
223
0
                if (curPos < len)
224
0
                {
225
0
                    DCMDATA_WARN("DcmUniqueIdentifier: Element " << getTagName() << " " << getTag()
226
0
                        << " contains one or more space characters, which were removed");
227
                    /* remember new length */
228
0
                    const Uint32 newLen = OFstatic_cast(Uint32, curPos);
229
                    /* blank out all trailing characters */
230
0
                    while (curPos < len)
231
0
                        value[curPos++] = '\0';
232
                    /* call inherited method: re-computes the string length, etc. */
233
0
                    return DcmByteString::makeMachineByteString(newLen);
234
0
                }
235
0
            }
236
0
        }
237
0
    }
238
    /* call inherited method: re-computes the string length, etc. */
239
0
    return DcmByteString::makeMachineByteString(OFstatic_cast(Uint32, len));
240
0
}
241
242
243
// ********************************
244
245
246
OFCondition DcmUniqueIdentifier::checkStringValue(const OFString &value,
247
                                                  const OFString &vm)
248
0
{
249
0
    return DcmByteString::checkStringValue(value, vm, "ui", 9, MAX_UI_LENGTH);
250
0
}