Coverage Report

Created: 2026-11-12 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/ofstd/libsrc/ofuuid.cc
Line
Count
Source
1
/*
2
 *
3
 *  Copyright (C) 2011-2026, 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:  ofstd
15
 *
16
 *  Author:  Uli Schlachter, Harald Roesen
17
 *
18
 *  Purpose: Implementation of a Universally Unique IDentifier (UUID),
19
 *           based on RFC 9562, section 5.7.
20
 *
21
 */
22
23
#include "dcmtk/ofstd/ofdefine.h"
24
#include "dcmtk/ofstd/ofstd.h"
25
#include "dcmtk/ofstd/ofuuid.h"
26
27
#include <iostream>
28
29
30
OFUUID const OFUUID::nil = OFUUID(0x00);
31
OFUUID const OFUUID::max = OFUUID(0xff);
32
33
34
void
35
OFUUID::divideBy10(Uint8 const n,
36
                   Uint8 & q,
37
0
                   Uint8 & r) {
38
    // First we do the higher half of the division.
39
0
    Uint8 next = (r << 4) | (n >> 4);
40
0
    Uint8 tmp = next / 10;
41
0
    r = next % 10;
42
43
    // Then we do the same with the lower half.
44
0
    next = (r << 4) | (n & 0x0f);
45
0
    q = (next / 10) + (tmp << 4);
46
0
    r = next % 10;
47
0
}
48
49
OFBool
50
0
OFUUID::isMax() const {
51
0
  return (*this == OFUUID::max);
52
0
}
53
54
OFBool
55
0
OFUUID::isNil() const {
56
0
  return (*this == OFUUID::nil);
57
0
}
58
59
12
OFUUID::OFUUID(Uint8 const fill) {
60
204
  for (size_t i = 0; i < OFUUID::DATA_LENGTH; ++i) {
61
192
    data_[i] = fill;
62
192
  }
63
12
}
64
65
0
OFUUID::OFUUID(OFUUID const & other) {
66
0
  assert(sizeof(data_) == sizeof(other.data_));
67
0
  memcpy(data_, other.data_, sizeof(data_));
68
0
}
69
70
OFBool
71
operator!=(OFUUID const & lhs,
72
0
           OFUUID const & rhs) {
73
0
  return !(lhs == rhs);
74
0
}
75
76
OFBool
77
operator<(OFUUID const & lhs,
78
0
          OFUUID const & rhs) {
79
0
  for (size_t i = 0; i < OFUUID::DATA_LENGTH; ++i) {
80
0
    if (lhs.data_[i] < rhs.data_[i]) {
81
0
      return OFTrue;
82
0
    }
83
84
0
    if (lhs.data_[i] > rhs.data_[i]) {
85
0
      return OFFalse;
86
0
    }
87
0
  }
88
89
0
  return OFFalse;
90
0
}
91
92
STD_NAMESPACE ostream &
93
operator<<(STD_NAMESPACE ostream & os,
94
0
           OFUUID const & ofuuid) {
95
0
  return ofuuid.print(os);
96
0
}
97
98
OFBool
99
operator<=(OFUUID const & lhs,
100
0
           OFUUID const & rhs) {
101
0
  return !(rhs < lhs);
102
0
}
103
104
OFUUID &
105
0
OFUUID::operator=(OFUUID const & rhs) {
106
0
  if (this == &rhs) {
107
0
    return *this;
108
0
  }
109
110
0
  for (size_t i = 0; i < OFUUID::DATA_LENGTH; ++i) {
111
0
    data_[i] = rhs.data_[i];
112
0
  }
113
114
0
  return *this;
115
0
}
116
117
OFBool
118
operator==(OFUUID const & lhs,
119
0
           OFUUID const & rhs) {
120
0
  for (size_t i = 0; i < OFUUID::DATA_LENGTH; ++i) {
121
0
    if (lhs.data_[i] != rhs.data_[i]) {
122
0
      return OFFalse;
123
0
    }
124
0
  }
125
126
0
  return OFTrue;
127
0
}
128
129
OFBool
130
operator>(OFUUID const & lhs,
131
0
          OFUUID const & rhs) {
132
0
  return (rhs < lhs);
133
0
}
134
135
OFBool
136
operator>=(OFUUID const & lhs,
137
0
           OFUUID const & rhs) {
138
0
  return !(lhs < rhs);
139
0
}
140
141
STD_NAMESPACE ostream&
142
OFUUID::print(STD_NAMESPACE ostream & os,
143
0
              Notation const notation) const {
144
0
  switch (notation) {
145
0
  case NotationOID:
146
0
    os << "2.25.";
147
    // Fall through !
148
149
0
  case NotationInteger:
150
0
    printInteger(os);
151
0
    break;
152
153
0
  case NotationURN:
154
0
    os << "urn:uuid:";
155
    // Fall through !
156
157
0
  case NotationCanonical:
158
0
    printCanonical(os);
159
0
    break;
160
0
  }
161
162
0
  return os;
163
0
}
164
165
void
166
0
OFUUID::printCanonical(STD_NAMESPACE ostream & os) const {
167
  // set new 'os' state and save 'os' old one
168
0
  STD_NAMESPACE ios_base::fmtflags const osFlags = os.flags(STD_NAMESPACE ios_base::hex);
169
0
  unsigned char const osFillChar = os.fill('0');
170
171
0
  size_t i = 0;
172
0
  for (/* EMPTY */; i < 4; ++i) {
173
0
    os << STD_NAMESPACE setw(2) << OFstatic_cast(int, data_[i]);
174
0
  }
175
0
  os << '-';
176
0
  for (/* EMPTY */; i < 6; ++i) {
177
0
    os << STD_NAMESPACE setw(2) << OFstatic_cast(int, data_[i]);
178
0
  }
179
0
  os << '-';
180
0
  for (/* EMPTY */; i < 8; ++i) {
181
0
    os << STD_NAMESPACE setw(2) << OFstatic_cast(int, data_[i]);
182
0
  }
183
0
  os << '-';
184
0
  for (/* EMPTY */; i < 10; ++i) {
185
0
    os << STD_NAMESPACE setw(2) << OFstatic_cast(int, data_[i]);
186
0
  }
187
0
  os << '-';
188
0
  for (/* EMPTY */; i < OFUUID::DATA_LENGTH; ++i) {
189
0
    os << STD_NAMESPACE setw(2) << OFstatic_cast(int, data_[i]);
190
0
  }
191
192
  // restore old 'os' state
193
0
  os.flags(osFlags);
194
0
  os.fill(osFillChar);
195
0
}
196
197
void
198
0
OFUUID::printInteger(STD_NAMESPACE ostream & os) const {
199
0
  if (isNil()) {
200
0
    os << "0";
201
202
0
    return;
203
0
  }
204
205
0
  OFUUID copy(*this);
206
207
  // A 128-bit integer has at most 39 characters in base 10.
208
  // Plus the usual trailing '\0' sums up to 40 characters.
209
  //
210
  // Conversion by continuing division.
211
  //
212
  // Note: The remainder, which make up the integer notation to be, are
213
  // calculated in reverse order.
214
0
  unsigned char chars[40];
215
0
  int idx = OFstatic_cast(int, sizeof(chars)) - 1;
216
0
  while (!copy.isNil()) {
217
0
    Uint8 r = 0;
218
0
    for (size_t i = 0; i < DATA_LENGTH; ++i) {
219
0
      divideBy10(copy.data_[i], copy.data_[i], r);
220
0
    }
221
0
    chars[--idx] = OFstatic_cast(unsigned char, (r + '0'));
222
0
  }
223
0
  chars[sizeof(chars) - 1] = '\0';
224
0
  os << &chars[idx];
225
0
}
226
227
OFString
228
0
OFUUID::toString(Notation const notation) const {
229
0
  OFOStringStream osstream;
230
0
  print(osstream, notation);
231
0
  OFString s;
232
0
  OFSTRINGSTREAM_GETSTR(osstream, string_ptr)
233
0
  s = string_ptr;
234
0
  OFSTRINGSTREAM_FREESTR(string_ptr);
235
236
0
  return s;
237
0
}
238
239
0
OFUUID::~OFUUID() {
240
  // DELIBERATELY EMPTY
241
0
}