vtkUnicodeStringArray.cxx 9.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkUnicodeStringArray.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright 2004 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
  license for use of this work by or on behalf of the
  U.S. Government. Redistribution and use in source and binary forms, with
  or without modification, are permitted provided that this Notice and any
  statement of authorship are reproduced on all copies.

=========================================================================*/

#include "vtkIdList.h"
#include "vtkObjectFactory.h"
#include "vtkUnicodeStringArray.h"

22
#include <vector>
23
#include <algorithm>
24

25
class vtkUnicodeStringArray::Implementation
26 27
{
public:
28
  typedef std::vector<vtkUnicodeString> StorageT;
29 30 31
  StorageT Storage;
};

32 33
vtkStandardNewMacro(vtkUnicodeStringArray);

34
vtkUnicodeStringArray::vtkUnicodeStringArray()
35
{
36
  this->Internal = new Implementation;
37 38 39 40
}

vtkUnicodeStringArray::~vtkUnicodeStringArray()
{
41
  delete this->Internal;
42 43 44 45 46 47 48 49 50
}

void vtkUnicodeStringArray::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

int vtkUnicodeStringArray::Allocate(vtkIdType sz, vtkIdType)
{
51
  this->Internal->Storage.reserve(sz);
52 53 54 55 56 57
  this->DataChanged();
  return 1;
}

void vtkUnicodeStringArray::Initialize()
{
58
  this->Internal->Storage.clear();
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
  this->DataChanged();
}

int vtkUnicodeStringArray::GetDataType()
{
  return VTK_UNICODE_STRING;
}

int vtkUnicodeStringArray::GetDataTypeSize()
{
  return 0;
}

int vtkUnicodeStringArray::GetElementComponentSize()
{
  return sizeof(vtkUnicodeString::value_type);
}

void vtkUnicodeStringArray::SetNumberOfTuples(vtkIdType number)
{
79
  this->Internal->Storage.resize(number);
80 81 82 83 84 85 86 87 88 89 90 91
  this->DataChanged();
}

void vtkUnicodeStringArray::SetTuple(vtkIdType i, vtkIdType j, vtkAbstractArray* source)
{
  vtkUnicodeStringArray* const array = vtkUnicodeStringArray::SafeDownCast(source);
  if(!array)
    {
    vtkWarningMacro("Input and output array data types do not match.");
    return;
    }

92
  this->Internal->Storage[i] = array->Internal->Storage[j];
93 94 95 96 97 98 99 100 101 102 103 104
  this->DataChanged();
}

void vtkUnicodeStringArray::InsertTuple(vtkIdType i, vtkIdType j, vtkAbstractArray* source)
{
  vtkUnicodeStringArray* const array = vtkUnicodeStringArray::SafeDownCast(source);
  if(!array)
    {
    vtkWarningMacro("Input and output array data types do not match.");
    return;
    }

105 106
  if(static_cast<vtkIdType>(this->Internal->Storage.size()) <= i)
    this->Internal->Storage.resize(i + 1);
107

108
  this->Internal->Storage[i] = array->Internal->Storage[j];
109 110 111
  this->DataChanged();
}

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
void vtkUnicodeStringArray::InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds,
                                         vtkAbstractArray *source)
{
  vtkUnicodeStringArray* const array =
      vtkUnicodeStringArray::SafeDownCast(source);
  if(!array)
    {
    vtkWarningMacro("Input and output array data types do not match.");
    return;
    }

  vtkIdType numIds = dstIds->GetNumberOfIds();
  if (srcIds->GetNumberOfIds() != numIds)
    {
    vtkWarningMacro("Input and output id array sizes do not match.");
    return;
    }

  // Find maximum destination id and resize if needed
  vtkIdType maxDstId = 0;
  for (vtkIdType idIndex = 0; idIndex < numIds; ++idIndex)
    {
    maxDstId = std::max(maxDstId, dstIds->GetId(idIndex));
    }

  if (static_cast<vtkIdType>(this->Internal->Storage.size()) <= maxDstId)
    {
    this->Internal->Storage.resize(maxDstId + 1);
    }

  // Copy data
  for (vtkIdType idIndex = 0; idIndex < numIds; ++idIndex)
    {
    this->Internal->Storage[dstIds->GetId(idIndex)] =
        array->Internal->Storage[srcIds->GetId(idIndex)];
    }

  this->DataChanged();
}

152 153 154 155 156 157 158 159 160
vtkIdType vtkUnicodeStringArray::InsertNextTuple(vtkIdType j, vtkAbstractArray* source)
{
  vtkUnicodeStringArray* const array = vtkUnicodeStringArray::SafeDownCast(source);
  if(!array)
    {
    vtkWarningMacro("Input and output array data types do not match.");
    return 0;
    }

161
  this->Internal->Storage.push_back(array->Internal->Storage[j]);
162
  this->DataChanged();
163
  return this->Internal->Storage.size() - 1;
164 165 166 167
}

void* vtkUnicodeStringArray::GetVoidPointer(vtkIdType id)
{
168
  // Err.. not totally sure what to do here
169
  if (this->Internal->Storage.empty())
170 171
    return 0;
  else
172
    return &this->Internal->Storage[id];
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
}

void vtkUnicodeStringArray::DeepCopy(vtkAbstractArray* da)
{
  if(!da)
    return;

  if(this == da)
    return;

  vtkUnicodeStringArray* const array = vtkUnicodeStringArray::SafeDownCast(da);
  if(!array)
    {
    vtkWarningMacro("Input and output array data types do not match.");
    return;
    }

190
  this->Internal->Storage = array->Internal->Storage;
191 192 193 194 195 196 197 198
  this->DataChanged();
}

void vtkUnicodeStringArray::InterpolateTuple(vtkIdType i, vtkIdList *ptIndices,
    vtkAbstractArray* source,  double* weights)
{
  if(this->GetDataType() != source->GetDataType())
    {
199
    vtkErrorMacro("Cannot CopyValue from array of type "
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
      << source->GetDataTypeAsString());
    return;
    }

  if (ptIndices->GetNumberOfIds() == 0)
    {
    // nothing to do.
    return;
    }

  // We use nearest neighbour for interpolating strings.
  // First determine which is the nearest neighbour using the weights-
  // it's the index with maximum weight.
  vtkIdType nearest = ptIndices->GetId(0);
  double max_weight = weights[0];
  for (int k=1; k < ptIndices->GetNumberOfIds(); k++)
    {
    if (weights[k] > max_weight)
      {
      nearest = ptIndices->GetId(k);
      max_weight = weights[k];
      }
    }

  this->InsertTuple(i, nearest, source);
}

227 228
void vtkUnicodeStringArray::InterpolateTuple(vtkIdType i,
    vtkIdType id1, vtkAbstractArray* source1,
229 230
    vtkIdType id2, vtkAbstractArray* source2, double t)
{
231
  if (source1->GetDataType() != this->GetDataType() ||
232 233 234 235 236 237 238 239 240 241 242 243 244 245
    source2->GetDataType() != this->GetDataType())
    {
    vtkErrorMacro("All arrays to InterpolateValue() must be of same type.");
    return;
    }

  if (t >= 0.5)
    {
    // Use p2
    this->InsertTuple(i, id2, source2);
    }
  else
    {
    // Use p1.
246
    this->InsertTuple(i, id1, source1);
247 248 249 250 251
    }
}

void vtkUnicodeStringArray::Squeeze()
{
252
  Implementation::StorageT(this->Internal->Storage).swap(this->Internal->Storage);
253 254 255 256 257
  this->DataChanged();
}

int vtkUnicodeStringArray::Resize(vtkIdType numTuples)
{
258
  this->Internal->Storage.resize(numTuples);
259 260 261 262 263 264 265 266 267 268 269 270
  this->DataChanged();
  return 1;
}

void vtkUnicodeStringArray::SetVoidArray(void*, vtkIdType, int)
{
  vtkErrorMacro("Not implemented.");
}

unsigned long vtkUnicodeStringArray::GetActualMemorySize()
{
  unsigned long count = 0;
271
  for(Implementation::StorageT::size_type i = 0; i != this->Internal->Storage.size(); ++i)
272
    {
273
    count += static_cast<unsigned long>(this->Internal->Storage[i].byte_count());
Jeff Baumes's avatar
Jeff Baumes committed
274
    count += static_cast<unsigned long>(sizeof(vtkUnicodeString));
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    }
  return count;
}

int vtkUnicodeStringArray::IsNumeric()
{
  return 0;
}

vtkArrayIterator* vtkUnicodeStringArray::NewIterator()
{
  vtkErrorMacro("Not implemented.");
  return 0;
}

290 291 292 293 294
vtkVariant vtkUnicodeStringArray::GetVariantValue(vtkIdType idx)
{
  return this->GetValue(idx);
}

295
vtkIdType vtkUnicodeStringArray::LookupValue(vtkVariant value)
296
{
297 298
  const vtkUnicodeString search_value = value.ToUnicodeString();

299
  for(Implementation::StorageT::size_type i = 0; i != this->Internal->Storage.size(); ++i)
300 301 302 303 304
    {
    if(this->Internal->Storage[i] == search_value)
      return i;
    }

305 306 307
  return -1;
}

308
void vtkUnicodeStringArray::LookupValue(vtkVariant value, vtkIdList* ids)
309
{
310 311
  const vtkUnicodeString search_value = value.ToUnicodeString();

312
  ids->Reset();
313
  for(Implementation::StorageT::size_type i = 0; i != this->Internal->Storage.size(); ++i)
314 315 316 317
    {
    if(this->Internal->Storage[i] == search_value)
      ids->InsertNextId(i);
    }
318 319
}

320
void vtkUnicodeStringArray::SetVariantValue(vtkIdType id, vtkVariant value)
321
{
322
  this->SetValue( id, value.ToUnicodeString() );
323 324 325 326
}

void vtkUnicodeStringArray::DataChanged()
{
327
  this->MaxId = this->Internal->Storage.size() - 1;
328 329 330 331 332 333 334 335
}

void vtkUnicodeStringArray::ClearLookup()
{
}

vtkIdType vtkUnicodeStringArray::InsertNextValue(const vtkUnicodeString& value)
{
336
  this->Internal->Storage.push_back(value);
337
  this->DataChanged();
338
  return this->Internal->Storage.size() - 1;
339 340
}

341 342 343
void vtkUnicodeStringArray::InsertValue(vtkIdType i, const vtkUnicodeString& value)
{
  // Range check
344 345
  if(static_cast<vtkIdType>(this->Internal->Storage.size()) <= i)
    this->Internal->Storage.resize(i + 1);
346 347 348 349

  this->SetValue(i, value);
}

350 351
void vtkUnicodeStringArray::SetValue(vtkIdType i, const vtkUnicodeString& value)
{
352
  this->Internal->Storage[i] = value;
353 354 355 356 357
  this->DataChanged();
}

vtkUnicodeString& vtkUnicodeStringArray::GetValue(vtkIdType i)
{
358
  return this->Internal->Storage[i];
359 360 361 362 363 364 365
}

void vtkUnicodeStringArray::InsertNextUTF8Value(const char* value)
{
  this->InsertNextValue(vtkUnicodeString::from_utf8(value));
}

366 367 368 369 370
void vtkUnicodeStringArray::SetUTF8Value(vtkIdType i, const char* value)
{
  this->SetValue(i, vtkUnicodeString::from_utf8(value));
}

371 372
const char* vtkUnicodeStringArray::GetUTF8Value(vtkIdType i)
{
373
  return this->Internal->Storage[i].utf8_str();
374 375
}