1999-09-27 18:44:28 +00:00
|
|
|
// -*- C++ -*-
|
|
|
|
/*
|
|
|
|
* File: array.h
|
|
|
|
* Purpose: A general purpose resizable array.
|
|
|
|
* Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
|
|
|
|
* Created: January 1996
|
|
|
|
*
|
|
|
|
* Dependencies: None (almost)
|
|
|
|
*
|
2000-03-09 03:36:48 +00:00
|
|
|
* Copyright: 1996, Alejandro Aguilar Sierra
|
1999-09-27 18:44:28 +00:00
|
|
|
* 1997 The LyX Team!
|
|
|
|
*
|
|
|
|
* You are free to use and modify this code under the terms of
|
|
|
|
* the GNU General Public Licence version 2 or later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#ifndef byte
|
|
|
|
#define byte unsigned char
|
|
|
|
#endif
|
|
|
|
|
2000-08-07 20:58:24 +00:00
|
|
|
/** A resizable array.
|
|
|
|
A general purpose resizable array.
|
|
|
|
@author Alejandro Aguilar Sierra
|
|
|
|
@version January 1996
|
1999-09-27 18:44:28 +00:00
|
|
|
*/
|
|
|
|
class LyxArrayBase {
|
|
|
|
public:
|
|
|
|
///
|
|
|
|
enum {
|
|
|
|
///
|
|
|
|
ARRAY_SIZE = 256,
|
|
|
|
///
|
|
|
|
ARRAY_STEP = 16,
|
|
|
|
///
|
|
|
|
ARRAY_MIN_SIZE = 4
|
|
|
|
};
|
|
|
|
|
|
|
|
///
|
2000-04-08 17:02:02 +00:00
|
|
|
explicit
|
1999-12-01 00:57:31 +00:00
|
|
|
LyxArrayBase(int size = ARRAY_STEP);
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
LyxArrayBase(LyxArrayBase const &);
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
~LyxArrayBase();
|
|
|
|
|
2000-04-08 17:02:02 +00:00
|
|
|
/// Constructs a new array with dx elements starting at pos
|
2000-09-14 17:53:12 +00:00
|
|
|
LyxArrayBase & operator=(LyxArrayBase const &);
|
2000-04-08 17:02:02 +00:00
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
int empty() const { return (last == 0); }
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
///
|
|
|
|
int Last() { return last; }
|
|
|
|
|
|
|
|
/// Fills with 0 the entire array and set last to 0
|
|
|
|
void Init();
|
|
|
|
|
|
|
|
/// Make the allocated memory fit the needed size
|
|
|
|
void Fit();
|
|
|
|
|
|
|
|
/// Remove dx elements from position pos. Don't changes the size
|
|
|
|
void Remove(int pos, int dx);
|
|
|
|
|
|
|
|
/// Merge dx elements from array a at pos. Changes the size if necessary.
|
1999-12-01 00:57:31 +00:00
|
|
|
void Merge(LyxArrayBase * a, int pos, int dx);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/// Same as Merge but doesn't changes the size (dangerous)
|
1999-12-01 00:57:31 +00:00
|
|
|
void MergeF(LyxArrayBase * a, int pos, int dx);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/// Copy dx byts from an array at position pos
|
|
|
|
void Copy(void *, int pos, int dx);
|
|
|
|
|
|
|
|
/// Constructs a new array with dx elements starting at pos
|
1999-12-01 00:57:31 +00:00
|
|
|
LyxArrayBase * Extract(int pos, int dx);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/// Insert a character at position pos
|
|
|
|
void Insert(int pos, byte);
|
|
|
|
|
|
|
|
/// Constructs a new array with dx elements starting at pos
|
|
|
|
byte operator[](const int);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
///
|
|
|
|
void Resize(int newsize);
|
|
|
|
///
|
|
|
|
bool Move(int p, int shift);
|
|
|
|
|
|
|
|
/// Buffer
|
1999-12-01 00:57:31 +00:00
|
|
|
byte * bf;
|
1999-09-27 18:44:28 +00:00
|
|
|
/// Last position inserted.
|
|
|
|
int last;
|
|
|
|
/// Max size of the array.
|
|
|
|
int maxsize;
|
|
|
|
private:
|
|
|
|
///
|
|
|
|
friend class MathedIter;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************ Inline functions *****************************/
|
|
|
|
|
|
|
|
inline
|
|
|
|
void LyxArrayBase::Init()
|
|
|
|
{
|
|
|
|
memset(bf, 0, maxsize);
|
|
|
|
last = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline // Hmmm, Hp-UX's CC can't handle this inline. Asger.
|
|
|
|
void LyxArrayBase::Resize(int newsize)
|
|
|
|
{
|
|
|
|
if (newsize<ARRAY_MIN_SIZE)
|
|
|
|
newsize = ARRAY_MIN_SIZE;
|
|
|
|
newsize += ARRAY_STEP - (newsize % ARRAY_STEP);
|
|
|
|
byte *nwbf = new byte[newsize];
|
|
|
|
if (last >= newsize) last = newsize-1;
|
|
|
|
maxsize = newsize;
|
|
|
|
memcpy(nwbf, bf, last);
|
|
|
|
delete[] bf;
|
|
|
|
bf = nwbf;
|
|
|
|
bf[last] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
LyxArrayBase::LyxArrayBase(int size)
|
|
|
|
{
|
|
|
|
maxsize = (size<ARRAY_MIN_SIZE) ? ARRAY_MIN_SIZE: size;
|
|
|
|
bf = new byte[maxsize]; // this leaks
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
LyxArrayBase::~LyxArrayBase()
|
|
|
|
{
|
|
|
|
delete[] bf;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
LyxArrayBase::LyxArrayBase(LyxArrayBase const & a)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
maxsize = a.maxsize;
|
|
|
|
bf = new byte[maxsize];
|
|
|
|
memcpy(&bf[0], &a.bf[0], maxsize);
|
|
|
|
last = a.last;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
LyxArrayBase & LyxArrayBase::operator=(LyxArrayBase const & a)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
if (this != &a) {
|
|
|
|
Resize(a.maxsize);
|
|
|
|
memcpy(&bf[0], &a.bf[0], maxsize);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
bool LyxArrayBase::Move(int p, int shift)
|
|
|
|
{
|
|
|
|
bool result = false;
|
2000-09-14 17:53:12 +00:00
|
|
|
if (p <= last) {
|
|
|
|
if (last + shift >= maxsize) {
|
1999-09-27 18:44:28 +00:00
|
|
|
Resize(last + shift);
|
|
|
|
}
|
2000-09-14 17:53:12 +00:00
|
|
|
memmove(&bf[p + shift], &bf[p], last - p);
|
1999-09-27 18:44:28 +00:00
|
|
|
last += shift;
|
|
|
|
bf[last] = 0;
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
void LyxArrayBase::Fit()
|
|
|
|
{
|
|
|
|
Resize(last);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
void LyxArrayBase::Remove(int pos, int dx)
|
|
|
|
{
|
2000-09-14 17:53:12 +00:00
|
|
|
Move(pos + dx, -dx);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
void LyxArrayBase::Merge(LyxArrayBase * a, int p, int dx)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
Move(p, dx);
|
|
|
|
memcpy(&bf[p], &a->bf[0], dx);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
void LyxArrayBase::MergeF(LyxArrayBase * a, int p, int dx)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
memcpy(&bf[p], &a->bf[0], dx);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
void LyxArrayBase::Copy(void * a, int p, int dx)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
memcpy(&bf[p], a, dx);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2000-09-14 17:53:12 +00:00
|
|
|
LyxArrayBase * LyxArrayBase::Extract(int, int dx)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2000-09-14 17:53:12 +00:00
|
|
|
LyxArrayBase * a = new LyxArrayBase(dx);
|
1999-09-27 18:44:28 +00:00
|
|
|
a->Merge(this, 0, dx);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
byte LyxArrayBase::operator[](const int i)
|
|
|
|
{
|
|
|
|
return bf[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
void LyxArrayBase::Insert(int pos, byte c)
|
|
|
|
{
|
2000-09-14 17:53:12 +00:00
|
|
|
if (pos < 0) pos = last;
|
|
|
|
if (pos >= maxsize)
|
|
|
|
Resize(maxsize + ARRAY_STEP);
|
1999-09-27 18:44:28 +00:00
|
|
|
bf[pos] = c;
|
2000-09-14 17:53:12 +00:00
|
|
|
if (pos >= last)
|
|
|
|
last = pos + 1;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|