Array.cc 3.11 KB
Newer Older
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1 2 3 4 5 6 7 8
//========================================================================
//
// Array.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

9 10 11 12
//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
13 14 15
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
16
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
17
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
18
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
19
// Copyright (C) 2013, 2017 Albert Astals Cid <aacid@kde.org>
20
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
21
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
22 23 24 25 26 27
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

Kristian Høgsberg's avatar
Kristian Høgsberg committed
28 29 30 31 32 33 34 35
#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <stdlib.h>
#include <stddef.h>
36
#include <cassert>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
37 38 39 40
#include "goo/gmem.h"
#include "Object.h"
#include "Array.h"

41
#ifdef MULTITHREADED
42
#  define arrayLocker()   MutexLocker locker(&mutex)
43
#else
44
#  define arrayLocker()
45
#endif
Kristian Høgsberg's avatar
Kristian Høgsberg committed
46 47 48 49 50 51
//------------------------------------------------------------------------
// Array
//------------------------------------------------------------------------

Array::Array(XRef *xrefA) {
  xref = xrefA;
52
  elems = nullptr;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
53 54
  size = length = 0;
  ref = 1;
55
#ifdef MULTITHREADED
56 57
  gInitMutex(&mutex);
#endif
Kristian Høgsberg's avatar
Kristian Høgsberg committed
58 59 60 61 62 63 64 65
}

Array::~Array() {
  int i;

  for (i = 0; i < length; ++i)
    elems[i].free();
  gfree(elems);
66
#ifdef MULTITHREADED
67 68 69 70
  gDestroyMutex(&mutex);
#endif
}

71
Object Array::copy(XRef *xrefA) const {
72
  arrayLocker();
Albert Astals Cid's avatar
Albert Astals Cid committed
73
  Array *a = new Array(xrefA);
74
  for (int i = 0; i < length; ++i) {
Albert Astals Cid's avatar
Albert Astals Cid committed
75
    a->add(elems[i].copy());
76
  }
Albert Astals Cid's avatar
Albert Astals Cid committed
77
  return Object(a);
78 79 80
}

int Array::incRef() {
81
  arrayLocker();
82 83 84 85 86
  ++ref;
  return ref;
}

int Array::decRef() {
87
  arrayLocker();
88 89
  --ref;
  return ref;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
90 91
}

Albert Astals Cid's avatar
Albert Astals Cid committed
92
void Array::add(Object &&elem) {
93
  arrayLocker();
Kristian Høgsberg's avatar
Kristian Høgsberg committed
94 95 96 97 98 99
  if (length == size) {
    if (length == 0) {
      size = 8;
    } else {
      size *= 2;
    }
100
    elems = (Object *)greallocn(elems, size, sizeof(Object));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
101
  }
Albert Astals Cid's avatar
Albert Astals Cid committed
102 103
  elems[length].initNullAfterMalloc();
  elems[length] = std::move(elem);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
104 105 106
  ++length;
}

107
void Array::remove(int i) {
108
  arrayLocker();
109
  if (i < 0 || i >= length) {
110
    assert(i >= 0 && i < length);
111 112 113
    return;
  }
  --length;
114
  memmove( static_cast<void*>(elems + i), elems + i + 1, sizeof(elems[0]) * (length - i) );
115 116
}

117
Object Array::get(int i, int recursion) const {
Kristian Høgsberg's avatar
Kristian Høgsberg committed
118
  if (i < 0 || i >= length) {
Albert Astals Cid's avatar
Albert Astals Cid committed
119
    return Object(objNull);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
120
  }
Albert Astals Cid's avatar
Albert Astals Cid committed
121
  return elems[i].fetch(xref, recursion);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
122 123
}

124
Object Array::getNF(int i) const {
Kristian Høgsberg's avatar
Kristian Høgsberg committed
125
  if (i < 0 || i >= length) {
Albert Astals Cid's avatar
Albert Astals Cid committed
126
    return Object(objNull);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
127
  }
Albert Astals Cid's avatar
Albert Astals Cid committed
128
  return elems[i].copy();
Kristian Høgsberg's avatar
Kristian Høgsberg committed
129
}
130

131
GBool Array::getString(int i, GooString *string) const
132
{
Albert Astals Cid's avatar
Albert Astals Cid committed
133 134
  Object obj = getNF(i);
  if (obj.isString()) {
135 136 137 138 139 140 141
    string->clear();
    string->append(obj.getString());
    return gTrue;
  } else {
    return gFalse;
  }
}