This file is indexed.

/usr/include/dcmtk/ofstd/ofmem.h is in libdcmtk-dev 3.6.2-3build3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/*
 *
 *  Copyright (C) 2012-2017, OFFIS e.V.
 *  All rights reserved.  See COPYRIGHT file for details.
 *
 *  This software and supporting documentation were developed by
 *
 *    OFFIS e.V.
 *    R&D Division Health
 *    Escherweg 2
 *    D-26121 Oldenburg, Germany
 *
 *
 *  Module:  ofstd
 *
 *  Author:  Jan Schlamelcher
 *
 *  Purpose: Implement fallback support for modern memory management
 *           approaches (e.g. smart pointers) for older compilers.
 *
 */

#ifndef OFMEM_H
#define OFMEM_H

#include "dcmtk/config/osconfig.h" // make sure OS specific configuration is included first
#include "dcmtk/ofstd/ofutil.h"

// use native classes when c++11 is supported
#if defined(HAVE_STL_MEMORY) && defined(HAVE_CXX11)

#include <memory>
template<typename... ARGS>
using OFshared_ptr = std::shared_ptr<ARGS...>;
template<typename... ARGS>
using OFunique_ptr = std::unique_ptr<ARGS...>;

#else //fallback implementations

#if defined HAVE_SYNC_ADD_AND_FETCH && defined HAVE_SYNC_SUB_AND_FETCH
#define OF_SHARED_PTR_COUNTER_TYPE size_t
#elif defined HAVE_INTERLOCKED_INCREMENT && defined HAVE_INTERLOCKED_DECREMENT
#if _MSC_VER <= 1200
#define OF_SHARED_PTR_COUNTER_TYPE LONG
#else
#define OF_SHARED_PTR_COUNTER_TYPE volatile LONG
#endif
#else
#define OF_SHARED_PTR_COUNTER_TYPE size_t
#define OF_SHARED_PTR_NEED_MUTEX 1
#include "dcmtk/ofstd/ofthread.h"
#endif

#ifdef HAVE_WINDOWS_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

/** OFshared_ptr is a smart pointer that retains shared ownership of an object through a pointer.
 *  Several OFshared_ptr objects may own the same object; the object is destroyed when the last remaining
 *  OFshared_ptr referring to it is destroyed or reset.
 *
 *  An OFshared_ptr may also own no objects, in which case it is called empty.
 *
 *  OFshared_ptr meets the requirements of CopyConstructible and CopyAssignable.
 *  @tparam T the type of the managed object, e.g. int for an OFshared_ptr behaving like an int*.
 *  @note this implementation is meant to be a subset of the c++11's std::shared_ptr that lacks the
 *    following features: swap support, support for weak references, atomic access to the managed object,
 *                        custom deleters and some functions like comparing OFshared_ptrs or read access
 *                        to the reference counter.
 *    see http://en.cppreference.com/w/cpp/memory/shared_ptr to compare OFshared_ptr against std::shared_ptr.
 */
template<typename T>
class OFshared_ptr
{
public:
    /** Constructs a shared_ptr with pt as the managed object.
     *  @param pt the managed object that this shared_ptr takes
     *    the ownership to.
     */
    OFshared_ptr( T* const pt = OFnullptr )
    : m_pData( new Data( pt ) )
    {

    }

    /** Constructs a shared_ptr which shares ownership of the object managed by other.
     *  If other manages no object, *this manages no object too.
     *  @param other another shared_ptr that this one will be copy constructed from.
     */
    OFshared_ptr( const OFshared_ptr& other )
    : m_pData( other.m_pData )
    {
        m_pData->increment_count();
    }

    /** Replaces the managed object with the one managed by other.
     *  @param other another shared_ptr that this one will be copy assigned from.
     */
    OFshared_ptr& operator=( const OFshared_ptr& other )
    {
        if( this != &other )
        {
            destroy();
            m_pData = other.m_pData;
            m_pData->increment_count();
        }
        return *this;
    }

    /** If *this owns an object and it is the last shared_ptr owning it,
     *  the object is destroyed. Otherwise does nothing.
     */
    ~OFshared_ptr()
    {
        destroy();
    }

    /** Checks if *this manages an object, i.e. whether get() != 0.
     *  @return OFTrue if *this manages an object, OFFalse otherwise.
     */
    operator OFBool() const
    {
        return m_pData->pointer() != OFnullptr;
    }

    /** Checks if *this does not manage an object, i.e. whether get() == 0.
     *  @return OFFalse if *this manages an object, OFTrue otherwise.
     */
    OFBool operator!() const
    {
        return !m_pData->pointer();
    }

    /** Dereferences pointer to the managed object.
     *  @return a reference to the managed object.
     */
    T& operator*() const
    {
        return *m_pData->pointer();
    }

    /** Dereferences pointer to the managed object.
     *  @return a pointer to the managed object.
     */
    T* operator->() const
    {
        return m_pData->pointer();
    }

    /** Returns a pointer to the managed object.
     *  @return a pointer to the managed object.
     */
    T* get() const
    {
        return m_pData->pointer();
    }

    /** Replaces the managed object with an object pointed to by pt.
     *  @param pt pointer to an object to acquire ownership of.
     */
    void reset( T* const pt = OFnullptr )
    {
        destroy();
        m_pData = new Data( pt );
    }

private:
    /** Helper class containing the reference to the
     *  managed object and the reference counter.
     */
    class Data
    {
    public:
        /** Construct reference and counter from a raw pointer.
         *  @param pt the raw pointer that becomes the managed object.
         */
        Data( T* const pt )
        : m_Count( 1 )
        , m_pT( pt )
#ifdef OF_SHARED_PTR_NEED_MUTEX
        , m_Mutex()
#endif
        {

        }

        /** Delete the managed object.
         *  We are deleted only if the reference counter reached zero,
         *  so we now have to delete the managed object.
         */
        ~Data()
        {
            delete m_pT;
        }

        /** Increment the reference counter in a thread-safe and (if possible)
         *  lock-free fashion.
         */
        void increment_count()
        {
#ifdef HAVE_SYNC_ADD_AND_FETCH
            __sync_add_and_fetch( &m_Count, 1 );
#elif defined HAVE_INTERLOCKED_INCREMENT
            InterlockedIncrement( &m_Count );
#else
            m_Mutex.lock();
            ++m_Count;
            m_Mutex.unlock();
#endif
        }

        /** Decrement the reference counter in a thread-safe and (if possible)
         *  lock-free fashion.
         *  @return OFTrue if the reference counter reached zero, OFFalse otherwise.
         */
        OFBool decrement_count()
        {
#ifdef HAVE_SYNC_SUB_AND_FETCH
            return !__sync_sub_and_fetch( &m_Count, 1 );
#elif defined HAVE_INTERLOCKED_DECREMENT
            return !InterlockedDecrement( &m_Count );
#else
            m_Mutex.lock();
            const OFBool result = !--m_Count;
            m_Mutex.unlock();
            return result;
#endif
        }

        /** Get the managed object.
         *  @return a pointer to the managed object.
         */
        T* pointer() const
        {
            return m_pT;
        }

    private:
        // Just to silence some warnings.
        Data(const Data&);
        Data& operator=(const Data&);

        /// The counter.
        OF_SHARED_PTR_COUNTER_TYPE m_Count;
        /// The pointer to the managed object.
        T* const m_pT;
#ifdef OF_SHARED_PTR_NEED_MUTEX
        /// A mutex for platforms that don't support lock-free counters.
        OFMutex m_Mutex;
#endif
    };

    /** decrement the reference counter, destroy the managed
     *  object and the counter if the counter reached zero.
     */
    void destroy()
    {
        if( m_pData->decrement_count() )
            delete m_pData;
    }

    /** A pointer to the management data structure containing the actual
     *  reference to the managed object and the reference counter.
     */
    Data* m_pData;
};

/** OFunique_ptr is a smart pointer that retains sole ownership of an object through a pointer and destroys
 *  that object when the unique_ptr goes out of scope. No two unique_ptr instances can manage the same object.
 *
 *  The object is destroyed and its memory deallocated when either of the following happens:
 *  - unique_ptr managing the object is destroyed
 *  - unique_ptr managing the object is assigned another pointer via reset().
 *
 *  A unique_ptr may also own no objects, in which case it is called empty.
 *
 *  OFunique_ptr is NOT CopyConstructible or CopyAssignable.
 *  @tparam T the type of the managed object, e.g. int for an OFunique_ptr behaving like an int*.
 *  @note this implementation is meant to be a subset of the c++11's std::unique_ptr that lacks the
 *    following features: swap support, custom deleters, specialized handling of pointers to
 *                        arrays and some functions like comparing OFunique_ptrs or creating a hash key.
 *    see http://en.cppreference.com/w/cpp/memory/unique_ptr to compare OFunique_ptr against std::unique_ptr.
 */
template<typename T>
class OFunique_ptr
{
public:
    /** typedef of pointer type T* for template programmers.
     */
    typedef T* pointer;
    /** T, the type of the object managed by this unique_ptr.
     */
    typedef T element_type;

    /** Constructs an empty OFunique_ptr
     */
    OFunique_ptr() : m_pData( OFnullptr ) {}

    /** Constructs a OFunique_ptr which owns p.
     *  @param p the pointer that's going to be owned by this unique_ptr.
     */
    explicit OFunique_ptr( pointer p ) : m_pData( p ) {}

    /** Move constructor.
     *  The move constructor <i>moves</i> the ownership of the managed
     *  object from its parameter to the newly created OFunique_ptr
     *  object, effectively emptying the former OFunique_ptr
     *  object.
     *  @param rhs an <i>rvalue reference</i> to another OFunique_ptr
     *    object, e.g. obtained via OFmove.
     *  @details
     *  <h3>Example</h3>
     *  This example shows how to move the ownership of a managed
     *  object from one OFunique_ptr to another. Note that the
     *  ownership always remains unique in this example, even
     *  if an error occurred while reading the Dataset.
     *  Therefore no memory leaks are possible!
     *  @code
     *  void consumeDataset( OFunique_ptr<DcmDataset> pDataset )
     *  . . .
     *  OFunique_ptr<DcmDataset> pDataset( new DcmDataset );
     *  if( pDataset && pDataset->read( ... ).good() )
     *  {
     *    // Error: copy constructor not available, as it would
     *    // compromise the unique ownership principle
     *    // consumeDataset( pDataset );
     *
     *    // OFmove allows us to 'tell' OFunique_ptr we want
     *    // to give away the ownership.
     *    consumeDataset( OFmove( pDataset ) );
     *  }
     *  @endcode
     */
    OFunique_ptr( OFrvalue_ref(OFunique_ptr) rhs )
#ifndef DOXYGEN
    : m_pData( rhs.m_pData )
    {
        OFrvalue_access(rhs).m_pData = OFnullptr;
    }
#else
    ;
#endif

    /** Move assignment operator.
     *  The move assignment operator <i>moves</i> the ownership of the
     *  managed object from its parameter to itself, effectively emptying
     *  the other OFunique_ptr object. See OFunique_ptr's <i>move constructor</i>
     *  for more information.
     *  @param rhs an <i>rvalue reference</i> to another OFunique_ptr
     *    object, e.g. obtained via OFmove.
     */
    OFunique_ptr& operator=( OFrvalue_ref(OFunique_ptr) rhs )
#ifndef DOXYGEN
    {
        OFunique_ptr& other = OFrvalue_access(rhs);
        if( &other != this )
        {
            reset( other.m_pData );
            other.m_pData = OFnullptr;
        }
        return *this;
    }
#else
    ;
#endif

    /** If get() == OFnullptr there are no effects -- otherwise, the owned object is destroyed.
     */
    ~OFunique_ptr() { delete m_pData; }

    /** Replaces the managed object. The previously owned object is deleted if the unique_ptr
     *  was not empty.
     *  @param p the new pointer to be owned, defaults to OFnullptr.
     */
    void reset( pointer p = OFnullptr ) { delete m_pData; m_pData = p; }

    /** Releases the ownership of the managed object if any.
     *  Retrieves the owned object (if any) and lets the unique_ptr become empty.
     *  @return same as get().
     */
    pointer release() { pointer const p = m_pData; m_pData = OFnullptr; return p; }

    /** Returns a pointer to the managed object or OFnullptr if no object is owned.
     *  @return Pointer to the managed object or OFnullptr if no object is owned.
     */
    pointer get() const { return m_pData; }

    /** Checks whether *this owns an object, i.e. whether get() != OFnullptr.
     *  @return get() != OFnullptr.
     */
    operator bool() const { return m_pData != OFnullptr; }

    /** Checks whether *this does NOT own an object, i.e. whether get() == OFnullptr.
     *  @return get() == OFnullptr.
     */
    bool operator!() const { return m_pData == OFnullptr; }

    /** Access the object owned by *this.
     *  @return the object owned by *this, i.e. *get().
     */
    T& operator*() const { return *m_pData; }

    /** Access the object owned by *this.
     *  @return same as get().
     */
    pointer operator->() const { return m_pData; }

private:
    /// Disable copy construction.
    OFunique_ptr(const OFunique_ptr&);
    /// Disable copy assignment.
    OFunique_ptr& operator=(const OFunique_ptr&);

    /// The underlying (raw) pointer.
    pointer m_pData;
};

#endif //c++11

#endif //OFMEM_H