Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// szv#4 S4163
#include <Interface_IntList.hxx>
// Data organization :
// theents value : 0 no reference
// > 0 : one reference, here is the value; no list
// < 0 : a list of references; we store <rank>, it starts at <rank>+1
// the list is in therefs and is thus constituted :
// list of negative values, ending with a positive value :
// from <rank>+1 to <rank>+nb , <rank>+1 to <rank>+nb-1 are negative and
// <rank>+nb is negative
// a zero means : free space
// Pre-reservation : <rank> notes the current number, in strict positive
// It must then be incremented at each addition
// Contextual usage, you must call SetNumber(num < 0) to exploit this
// info and Add(ref < 0) to manage it.
// If it is not present, we switch to current mode
Interface_IntList::Interface_IntList()
{
thenbe = thenbr = thenum = thecount = therank = 0;
}
Interface_IntList::Interface_IntList(const int nbe)
{
Initialize(nbe);
}
Interface_IntList::Interface_IntList(const Interface_IntList& other, const bool copied)
{
thenbe = other.NbEntities();
thenum = thecount = therank = 0; // szv#4:S4163:12Mar99 initialization needed
thenbr = other.NbReferences();
theents = other.Entities();
therefs = other.References();
if (copied)
{
int i;
occ::handle<NCollection_HArray1<int>> ents = new NCollection_HArray1<int>(0, thenbe);
ents->Init(0);
for (i = 1; i <= thenbe; i++)
{
ents->SetValue(i, theents->Value(i));
}
occ::handle<NCollection_HArray1<int>> refs = new NCollection_HArray1<int>(0, thenbr);
refs->Init(0);
for (i = 1; i <= thenbr; i++)
{
refs->SetValue(i, therefs->Value(i));
}
theents = ents;
therefs = refs;
}
SetNumber(other.Number());
}
void Interface_IntList::Initialize(const int nbe)
{
thenbe = nbe;
thenbr = thenum = thecount = therank = 0;
theents = new NCollection_HArray1<int>(0, nbe);
theents->Init(0);
}
int Interface_IntList::NbReferences() const
{
return thenbr;
}
const occ::handle<NCollection_HArray1<int>>& Interface_IntList::Entities() const
{
return theents;
}
const occ::handle<NCollection_HArray1<int>>& Interface_IntList::References() const
{
return therefs;
}
void Interface_IntList::Internals(int& nbrefs,
occ::handle<NCollection_HArray1<int>>& ents,
occ::handle<NCollection_HArray1<int>>& refs) const
{
nbrefs = thenbr;
ents = theents;
refs = therefs;
}
int Interface_IntList::NbEntities() const
{
return thenbe;
}
void Interface_IntList::SetNbEntities(const int nbe)
{
if (nbe <= theents->Upper())
{
return;
}
int i;
occ::handle<NCollection_HArray1<int>> ents = new NCollection_HArray1<int>(0, nbe);
ents->Init(0);
for (i = 1; i <= thenbe; i++)
{
ents->SetValue(i, theents->Value(i));
}
theents = ents;
thenbe = nbe;
}
void Interface_IntList::SetNumber(const int number)
{
// Pre-reservation usage : to be requested specifically ! -> optimization
// <preres> verifies that the pre-reservation is valid
if (number < 0)
{
if (thenum == -number || number < -thenbe)
{
return;
}
bool preres = true;
thenum = -number;
int val = theents->Value(thenum);
if (val == 0)
{
thecount = 0;
therank = 0;
}
else if (val > 0)
{
thecount = 1;
therank = -1;
}
if (val < -1)
{
therank = -val;
thecount = therefs->Value(therank);
if (thecount <= 0)
{
preres = false;
}
}
if (preres)
{
return;
}
}
// Current usage. The following in current usage or if no pre-reservation
else if (number > 0)
{
if (thenum == number || number > thenbe)
{
return;
}
thenum = number;
}
else
{
return;
}
int val = theents->Value(thenum);
if (val == 0)
{
thecount = 0;
therank = 0;
}
else if (val > 0)
{
thecount = 1;
therank = -1;
}
else if (val < -1)
{
therank = -val;
thecount = 0;
if (therefs->Value(therank + 1) == 0)
{
thecount = -therefs->Value(therank);
}
else
{
for (int j = 1;; j++)
{
val = therefs->Value(therank + j);
if (val >= 0)
{
break;
}
thecount++;
}
if (val > 0)
{
thecount++;
}
}
}
else
{
thecount = 0;
therank = -1;
} // val == -1 reste
}
int Interface_IntList::Number() const
{
return thenum;
}
Interface_IntList Interface_IntList::List(const int number, const bool copied) const
{
Interface_IntList alist(*this, copied);
alist.SetNumber(number);
return alist;
}
void Interface_IntList::SetRedefined(const bool mode)
{
if (!NbEntities() || thenum == 0)
{
return;
}
int val = theents->Value(thenum);
if (val < -1)
{
return;
}
else if (mode)
{
if (val == 0)
{
theents->SetValue(thenum, -1);
}
else if (val > 0)
{
Reservate(2);
theents->SetValue(thenum, -thenbr);
therefs->SetValue(thenbr + 1, val);
thenbr++;
}
}
else if (!mode)
{
if (val == -1)
{
theents->SetValue(thenum, 0);
}
else if (therefs->Value(therank + 1) >= 0)
{
theents->SetValue(thenum, therefs->Value(therank + 1));
if (thenbr == therank + 1)
{
thenbr--;
}
}
}
}
void Interface_IntList::Reservate(const int count)
{
// Reservate (-count) = Reservate (count) + allocation on current entity + 1
if (count < 0)
{
Reservate(-count - 1);
if (thenum == 0)
{
return;
}
thenbr++;
therefs->SetValue(thenbr, 0); // will contain the number ...
therank = thenbr;
theents->SetValue(thenum, -thenbr);
thenbr -= count;
return;
}
int up, oldup = 0;
if (thenbr == 0)
{ // i.e. not yet allocated ...
up = thenbe / 2 + 1;
if (up < 2)
{
up = 2;
}
if (up < count)
{
up = count * 3 / 2;
}
therefs = new NCollection_HArray1<int>(0, up);
therefs->Init(0);
thenbr = 2; // we start after (convenience of addressing)
}
oldup = therefs->Upper();
if (thenbr + count < oldup)
{
return; // OK
}
up = oldup * 3 / 2 + count;
if (up < 2)
{
up = 2;
}
occ::handle<NCollection_HArray1<int>> refs = new NCollection_HArray1<int>(0, up);
refs->Init(0);
for (int i = 1; i <= oldup; i++)
{
refs->SetValue(i, therefs->Value(i));
}
therefs = refs;
}
void Interface_IntList::Add(const int ref)
{
if (thenum == 0)
{
return;
}
// ref < 0 : pre-reservation
if (ref < 0)
{
Add(-ref);
if (therank <= 0)
{
return;
}
if (therefs->Value(therank) >= 0)
{
therefs->SetValue(therank, thecount);
}
return;
}
if (therank == 0)
{
theents->SetValue(thenum, ref);
thecount = 1;
therank = -1;
}
else if (therank < 0)
{
Reservate(2);
therank = thenbr;
int val = theents->Value(thenum);
theents->SetValue(thenum, -thenbr);
if (thecount == 1)
{
therefs->SetValue(thenbr + 1, -val);
thenbr++;
}
therefs->SetValue(thenbr + 1, ref);
thenbr++;
thecount++;
}
else if (thenbr == therank + thecount)
{ // free space at end
therefs->SetValue(thenbr, -therefs->Value(thenbr));
therefs->SetValue(thenbr + 1, ref);
thenbr++;
thecount++;
}
else if (therefs->Value(therank + thecount + 1) == 0)
{ // free space after
therefs->SetValue(therank + thecount, -therefs->Value(therank + thecount));
therefs->SetValue(therank + thecount + 1, ref);
thecount++;
}
else
{ // copy further !
Reservate(thecount + 2);
int rank = therank;
therank = thenbr;
theents->SetValue(thenum, -therank);
for (int i = 1; i < thecount; i++)
{
therefs->SetValue(therank + i, therefs->Value(rank + i));
therefs->SetValue(rank + i, 0);
}
therefs->SetValue(therank + thecount, -therefs->Value(rank + thecount));
therefs->SetValue(rank + thecount, 0);
therefs->SetValue(therank + thecount + 1, ref);
thecount++;
thenbr = therank + thecount + 1;
}
}
int Interface_IntList::Length() const
{
return thecount;
}
bool Interface_IntList::IsRedefined(const int num) const
{
int n = (num == 0 ? thenum : num);
if (!NbEntities() || n == 0)
{
return false;
}
if (theents->Value(n) < 0)
{
return true;
}
return false;
}
int Interface_IntList::Value(const int num) const
{
if (thenum == 0)
{
return 0;
}
if (num <= 0 || num > thecount)
{
return 0;
}
if (thecount == 0)
{
return 0;
}
if (therank <= 0)
{
return theents->Value(thenum);
}
int val = therefs->Value(therank + num);
if (val < 0)
{
return -val;
}
return val;
}
bool Interface_IntList::Remove(const int)
{
return false; // not yet implemented
}
void Interface_IntList::Clear()
{
if (thenbr == 0)
{
return; // already clear
}
int i, low, up;
low = theents->Lower();
up = theents->Upper();
for (i = low; i <= up; i++)
{
theents->SetValue(i, 0);
}
thenbr = 0;
if (therefs.IsNull())
{
return;
}
low = therefs->Lower();
up = therefs->Upper();
for (i = low; i <= up; i++)
{
therefs->SetValue(i, 0);
}
}
void Interface_IntList::AdjustSize(const int margin)
{
int i, up = theents->Upper();
if (up > thenbe)
{
occ::handle<NCollection_HArray1<int>> ents = new NCollection_HArray1<int>(0, thenbe);
ents->Init(0);
for (i = 1; i <= thenbe; i++)
{
ents->SetValue(i, theents->Value(i));
}
theents = ents;
}
if (thenbr == 0)
{
Reservate(margin);
}
else
{
up = therefs->Upper();
if (up >= thenbr && up <= thenbr + margin)
{
return;
}
occ::handle<NCollection_HArray1<int>> refs = new NCollection_HArray1<int>(0, thenbr + margin);
refs->Init(0);
for (i = 1; i <= thenbr; i++)
{
refs->SetValue(i, therefs->Value(i));
}
therefs = refs;
}
}