1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 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 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
|
#include <iostream>
using namespace std;
#include <string>
#include <string.h>
#include "exception.hpp"
#include "rpc/rpc.h"
#define VIRTUAL
class Codeur {
public:
static bool_t CodeX(XDR *, Codeur *);
protected:
Codeur() {};
// Methode appelee par realiser le codage des donnees
// Sera redefinie dans chaque classe derivee
public:
virtual ~Codeur() {};
virtual bool_t Code(XDR *) = 0;
};
template <class T>
class ArrayXdrBase;
template <class T>
class ArrayRef {
private:
class ArrayXdrBase<T>& _A;
int _i;
public:
ArrayRef(ArrayXdrBase<T>& A, int I):_A(A), _i(I) {}
ArrayRef<T>& operator=(const T& v);
operator T ();
T* operator&();
};
// Classe de représentation du buffer XDR, permet
// effectuer du reference counting et de manimiser les
// allocations et les copies.
template <class T>
class _ArrayXdrRep {
public:
_ArrayXdrRep(unsigned int nbElem, const T* Buf);
_ArrayXdrRep(const _ArrayXdrRep &A);
_ArrayXdrRep& operator=(const _ArrayXdrRep &A);
~_ArrayXdrRep() { delete [] _array; }
int _refCount;
unsigned int _length;
T* _array;
};
// Tableau de longueur fixe permet d'instancier les types de base car la methode code n'est pas définie
template <class T>
class ArrayXdrBase : public Codeur {
friend class ArrayRef<T>;
public:
ArrayXdrBase(unsigned int nbElem=0, const T* Buf=NULL) { _rep = new _ArrayXdrRep<T>(nbElem, Buf); }
ArrayXdrBase(const ArrayXdrBase<T>& A) {_rep = A._rep; _rep->_refCount++; }
ArrayXdrBase<T>& operator=(const ArrayXdrBase<T>& Buf);
virtual ~ArrayXdrBase() { if (--_rep->_refCount <= 0) delete _rep; }
ArrayRef<T> operator [](int n);
unsigned int MaxLength() const { return _rep->_length; }
virtual void SetMaxLength(unsigned int v);
protected:
// Methode utilitaire de copie de deux tableaux
void Copier(const ArrayXdrBase<T>& Buf);
// Methode utilitaire de duplication du tableau interne
void Dupliquer();
_ArrayXdrRep<T> *_rep;
};
template <class T>
inline
ArrayRef<T>& ArrayRef<T>::operator=(const T& v) {
// Deplace les tableaux si plusieurs reference
_A.Dupliquer();
_A._rep->_array[_i]=v;
return *this;
}
template <class T>
inline
ArrayRef<T>::operator T () {
return _A._rep->_array[_i];
}
template <class T>
inline
T* ArrayRef<T>::operator&() {
return &_A._rep->_array[_i];
}
template <class T>
inline
void ArrayXdrBase<T>::Dupliquer() {
if (_rep->_refCount > 1) {
--_rep->_refCount;
_rep = new _ArrayXdrRep<T>(_rep->_length, _rep->_array);
if (_rep == NULL)
throw(ENOMEMORY("Duplication de tableaux"));
}
}
template <class T>
inline
_ArrayXdrRep<T>::_ArrayXdrRep(unsigned int nbElem, const T* Buf) {
int i;
if (nbElem <= 0) {
_array = NULL;
}
else {
if ((_array = new T[nbElem]) == NULL)
throw(ENOMEMORY("Construction ArrayXdrBase"));
if (Buf != NULL) {
for (i = 0; i < nbElem; i++)
_array[i]=Buf[i];
}
}
_length=nbElem;
_refCount=1;
}
template <class T>
inline
_ArrayXdrRep<T>::_ArrayXdrRep(const _ArrayXdrRep<T> &A) {
if (A._length <= 0) {
_array = NULL;
}
else {
if ((_array = new T[A._length]) == NULL)
throw(ENOMEMORY("Construction ArrayXdrBase"));
for (int i = 0; i < A._length; i++)
_array[i]=A._array[i];
}
_length=A._length;
_refCount=1;
}
template <class T>
inline
_ArrayXdrRep<T>& _ArrayXdrRep<T>::operator=(const _ArrayXdrRep<T> &A) {
if (this != &A) {
for (int i=0; i< (_length < A._length ? _length : A._length); i++) {
_array[i]=A._array[i];
}
}
return *this;
}
template <class T>
inline
ArrayXdrBase<T>& ArrayXdrBase<T>::operator=(const ArrayXdrBase<T>& Buf) {
if (this != &Buf) {
// Si le tableau a copier a une taille superieure au tableau destination
// ne pas effectuer la copie et lever une exception
if (_rep->_length < Buf.rep->_length)
throw(EINVRANGE("Affectation ArrayXdrBase"));
}
Copier(Buf);
return *this;
}
// Tableau de longueur fixe definissant une methode code
// permettant d'instancier des types composés de Codeur
template <class T>
class ArrayXdr : public ArrayXdrBase<T> {
public:
ArrayXdr(unsigned int nbElem=0, const T* Buf=NULL): ArrayXdrBase<T>(nbElem, Buf) {}
ArrayXdr(const ArrayXdr<T>& A): ArrayXdrBase<T>(A) {}
bool_t Code(XDR *xdrs);
};
// Tableau de longueur variable Base
template <class T>
class ArrayVarXdrBase : public ArrayXdrBase<T> {
public:
ArrayVarXdrBase(unsigned int nbElem=0, const T* Buf=NULL): ArrayXdrBase<T>(nbElem, Buf),
_actualLength(nbElem) {}
ArrayVarXdrBase(const ArrayVarXdrBase<T>& Buf): ArrayXdrBase<T>(Buf),
_actualLength(Buf.rep->_length) {}
ArrayVarXdrBase<T>& operator=(const ArrayVarXdrBase<T>&);
~ArrayVarXdrBase() {}
virtual void SetMaxLength(unsigned int v);
unsigned int Length() const { return _actualLength; }
void SetLength(unsigned int v);
protected:
unsigned int _actualLength; // taille du utilisee pour la transmission
};
// Tableaux de taille variable exportables
template <class T>
inline
ArrayVarXdrBase<T>& ArrayVarXdrBase<T>::operator=(const ArrayVarXdrBase<T>& Buf) {
if (this != &Buf) return *this;
// Si le tableau a copier a une taille superieure au tableau destination
// ne pas effectuer la copie et lever une exception
if (_rep->_length < Buf._actualLength)
throw(ETOOBIG("Affectation ArrayVarXdrBase"));
Copier(Buf);
_actualLength=Buf._actualLength;
return *this;
}
template <class T>
class ArrayVarXdr : public ArrayVarXdrBase<T> {
public:
ArrayVarXdr(unsigned int nbElem=0, const T* Buf=NULL): ArrayVarXdrBase<T>(nbElem, Buf) {}
ArrayVarXdr(const ArrayVarXdr<T>& A): ArrayVarXdrBase<T>(A) {}
bool_t Code(XDR *xdrs);
};
// Iterateur sur un tableau de taille Fixe
template <class T>
class ArrayXdrIter {
public:
ArrayXdrIter(ArrayXdr<T>& Array): _array(Array), _i(0) {}
void First() { _i=0; }
bool_t Next();
T* Current() { return (_i > 0)? &_array[_i-1]: NULL; }
private:
int _i;
ArrayXdr<T>& _array;
};
template <class T>
inline bool_t ArrayXdrIter<T>::Next() {
if (_i < _array.MaxLength()) {
_i++;
return TRUE;
}
else {
return FALSE;
}
}
// Iterateur sur un tableau de taille variable
template <class T>
class ArrayVarXdrIter {
public:
ArrayVarXdrIter(ArrayVarXdrBase<T>& Array):_array(Array),_i(0) {}
void First() { _i=0; }
bool_t Next();
T* Current() { return (_i > 0)? &_array[_i-1]: NULL; }
private:
int _i;
ArrayVarXdrBase<T>& _array;
};
template <class T>
inline bool_t ArrayVarXdrIter<T>::Next() {
if (_i < _array.Length()) {
_i++;
return TRUE;
}
else {
return FALSE;
}
} |
Partager