/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SBVector.h" #include #include #include /** * Set the debug level * @param level 0 means no debug printouts. * @return the previous level */ int SBVector::debug (int level) { return SShared::debug(level); } /** * Create a vector from a const vector. This is * used when you do * SBVector v = old; * @param v is the old */ SBVector::SBVector (const SBVector& v) { // Assign the common buffer and increment the reference count buffer = (SShared*) v.buffer; buffer->count++; } /** * Assign a vector from a const vector. This is * used when you do * SBVector v; * v = old; * @param v is the old */ SBVector& SBVector::operator=(const SBVector& v) { refer (v); return *this; } /** * Assign a vector from a const vector by changing the reference. * @param v is the input vector */ void SBVector::refer(const SBVector& v) { // Are we the same objects if (&v==this) return; cleanup (); buffer = (SShared*) v.buffer; buffer->count++; return; } /** * Replace char's with len length at index * @param index is the reference index of len blocks * @param e is the pointer to the char array to be saved * @param len is the length of the block. */ void SBVector::replace (unsigned int index, const char* in, unsigned int len) { derefer (); const char* e = in; SShared* ns =0; if (len==0) return; if (len > 0 && buffer->array < in && &buffer->array[buffer->arraySize] > in) { fprintf (stderr, "SBVector::replace copying into itself.\n"); ns = new SShared (in, len); e = ns->array; } memcpy (&buffer->array[index], e, len); if (ns) delete ns; } /** * replace one occurance of buffer with another. */ int SBVector::replace (const char* e, unsigned int len, const char* with, unsigned int withLen, unsigned int from, unsigned int align) { derefer (); int i = find (e, len, from, align); if (i<0) return i; // Max element size remove (i, len); insert (i, with, withLen); return i+withLen; } /** * replace one occurance of buffer with another. */ int SBVector::replaceAll (const char* e, unsigned int len, const char* with, unsigned int withLen, unsigned int from, unsigned int align) { derefer (); int count = 0; int begin =from; while (begin>=0) { begin=replace (e, len, with, withLen, begin, align); if (begin > 0) count++; } return count; } /** * Clear the array and make a new SShared. */ void SBVector::clear () { derefer (); cleanup (); buffer = new SShared(); } /** * Find a subvector. */ int SBVector::find (const char* e, unsigned int len, unsigned int from, unsigned int align) const { //fprintf (stderr, "Address=%lx\n", (unsigned long) (e)); unsigned int sz = size(); register char* _array = buffer->array; register unsigned j; for (register unsigned int i=from; i+len <= sz; i+=(unsigned int)align) { for (j=0; jarray[i+j], j, (int) e[j]); if (_array[i+j] != e[j]) break; } if (j>=len) return (int) i; } return -1024; } /** * This is a replay of the obove for SObject collections */ SOVector::SOVector(void) : SBVector() { } /** * This is a replay of the obove for SObject collections */ SOVector::SOVector(unsigned int _size) : SBVector(_size * sizeof (SObject*)) { } SOVector::SOVector(const SOVector& v) : SBVector(v) { } SOVector::~SOVector () { cleanup(); } SOVector& SOVector::operator=(const SOVector& v) { refer (v); return *this; } SObject* SOVector::clone() const { return new SOVector (*this); } void SOVector::replace (unsigned int index, const SObject& v) { derefer(); SObject* r = (SObject*) peek (index); replaceQuetly (index, &v); delete r; } void SOVector::insert (unsigned int index, const SObject& v) { derefer(); SObject* ref= (SObject*) v.clone(); SBVector::insert (index*sizeof(SObject*), (char*)&ref, sizeof (SObject*)); } void SOVector::remove (unsigned int index) { derefer(); SObject* old = (SObject*) peek (index); if (old) delete old; SBVector::remove (index * sizeof (SObject*), sizeof (SObject*)); } unsigned int SOVector::size () const { return SBVector::size()/sizeof(SObject*); } void SOVector::clear () { cleanup (); SBVector::clear(); } void SOVector::refer (const SOVector& v) { if (&v != this) { cleanup(); SBVector::refer(v); } } const SObject* SOVector::peek (unsigned int index) const { return *(SObject**)SBVector::peek (index * sizeof (SObject*)); } void SOVector::derefer() { if (count()==1) return; SBVector::derefer(); for (unsigned int i=0; iclone(); SBVector::replace (index*sizeof(SObject*), (char*) &n, sizeof (SObject*)); } void SOVector::cleanup() { if (count()!=1) return; for (unsigned int i=0; i