CVME.h

Go to the documentation of this file.
00001 /*
00002     This software is Copyright by the Board of Trustees of Michigan
00003     State University (c) Copyright 2005.
00004 
00005     You may use this software under the terms of the GNU public license
00006     (GPL).  The terms of this license are described at:
00007 
00008      http://www.gnu.org/licenses/gpl.txt
00009 
00010      Author:
00011              Ron Fox
00012              NSCL
00013              Michigan State University
00014              East Lansing, MI 48824-1321
00015 */
00016 
00017 /*
00018   \class CVME
00019   \file CVME.h
00020 
00021   Encapsulates a CVME object. CVMEs purpose for existence is so that
00022   CVMEptr's wont cause memory leaks. A CVME contains a reference counted
00023   pointer which points to a CVMEptr object which holds the actual mapped
00024   address and performs the actual reads and writes. When a CVME is
00025   constructed, its reference count is incremented, and when one is
00026   destructed, its reference count is decremented. When the reference count
00027   falls to zero, the object is deleted. This way, the object wont be
00028   deleted before we are done with it.
00029 
00030   Author:
00031      Jason Venema
00032      NSCL
00033      Michigan State University
00034      East Lansing, MI 48824-1321
00035      mailto: venemaja@msu.edu
00036 */
00037 
00038 #ifndef __CVME_H
00039 #define __CVME_H
00040 
00041 #ifndef __CVMEPTR_H
00042 #include <CVMEptr.h>
00043 #endif
00044 
00045 #ifndef __REFPTR_H
00046 #include <Refptr.h>
00047 #endif
00048 
00049 template<class T>
00050 class CVME
00051 {
00052 private:
00053   CRefcountedPtr<CVMEptr<T> > m_pRCptr;  // a reference counted pointer to the
00054                                          // CVMEptr which holds the mapping.
00055   UInt_t   m_nOffset;                    // We need our own offset to do ++ e.g. 
00056 
00057  public:
00058   // Enumeration of possible Vme devices to access
00059   enum VmeSpace {
00060     a16d16,
00061     a24d16,
00062     a24d32,
00063     a32d32,
00064     geo
00065   };
00066 
00067   // Default constructor
00068   CVME<T>(VmeSpace space, UInt_t base, UInt_t length, UInt_t crate=0);
00069   CVME<T>();
00070   CVME<T>(CVMEptr<T>* aCVMEptr);
00071   // Copy constructor
00072   CVME<T>(const CVME& aCVME);
00073   // Operator= assignment operator
00074   CVME<T>& operator= (const CVME<T>& aCVME);
00075 
00076   // Operator== equality operator
00077   int operator== (const CVME<T>& aCVME)
00078     {
00079       return (m_pRCptr == aCVME.m_pRCptr);
00080     }
00081 
00082   // Mutator functions
00083  protected:
00084   void setRCptr(CVMEptr<T> aRCptr) { m_pRCptr = aRCptr; }
00085 
00086   // Public accessor functions
00087  public:
00088   UInt_t getOffset() { return m_nOffset;  }
00089   UInt_t getLength() { return m_pRCptr.operator*().getLength(); }
00090   Address_t getStart() { return m_pRCptr.operator*().getStart(); }
00091   Address_t getgenptr(UInt_t nOffset);
00092   Address_t getcurrptr();
00093 
00094   // Public member functions
00095  public:
00096   // Pointer dereference/indexing
00097   T& operator*();
00098   T* operator->();
00099   T& operator[] (UInt_t nOffset);
00100   T& operator[] (UInt_t nOffset) const;
00101 
00102   // Pointer addition/subtraction
00103   CVME<T>& operator+(UInt_t nOffset);
00104   CVME<T>& operator-(UInt_t nOffset);
00105   CVME<T>& operator+=(UInt_t nOffset);
00106   CVME<T>& operator-=(UInt_t nOffset);
00107 
00108   // Pointer pre-increment/decrement
00109   CVME<T>& operator++();
00110   CVME<T>& operator--();
00111 
00112   // Pointer post-increment/decrement
00113   CVME<T>& operator++(Int_t);
00114   CVME<T>& operator--(Int_t);
00115 
00116   // Type conversion operators
00117  public:
00118   volatile UChar_t*      asChar();
00119   volatile UShort_t*  asShort();
00120   volatile ULong_t*   asLong();
00121 };
00122 
00123 
00124 /*
00125   \fn CVME<T>::CVME<T>(VmeSpace space, UInt_t base, UInt_t length)
00126 
00127   Operation Type:
00128      Constructor
00129 
00130   Purpose:
00131      Construct a CVME<T> by newing into existence a 
00132      CVMEptr<T> and encapsulating it in a RefcountedPtr.
00133   
00134   \param VmeSpace space - indicates the vme device to map
00135          UInt_t base    - the base address of the module
00136          UInt_t length  - the length of the mapping (bytes)
00137          UInt_t crate   - VME Crate number.
00138  */
00139 template<class T>
00140 CVME<T>::CVME(VmeSpace space, UInt_t base, UInt_t length, UInt_t crate) :
00141   m_nOffset(0)
00142 {
00143   CRefcountedPtr<CVMEptr<T> > p(new CVMEptr<T>(space, base, length, crate));
00144   m_pRCptr = p;
00145 }
00146 
00147 /*
00148   \fn CVME<T>::CVME<T>()
00149 
00150   Operation Type:
00151      Constructor
00152 
00153   Purpose:
00154      Construct a CVME<T> which points to nothing.
00155 */
00156 template<class T>
00157 CVME<T>::CVME() :
00158   m_nOffset(0)
00159 {
00160   m_pRCptr = 0;
00161 }
00162 
00163 /*
00164   CVME<T>::CVME<T>(CVMEptr<T>& aCVMEptr)
00165 
00166   Operation Type:
00167      Constructor
00168 
00169   Purpose:
00170      Constructs an object of type CVME<T> given a CVMEptr object.
00171 
00172   \param CVMEptr<T>& aCVMEptr - the CVMEptr from which to construct this
00173 */
00174 template<class T>
00175 CVME<T>::CVME(CVMEptr<T>* aCVMEptr) :
00176   m_nOffset(0)
00177 {
00178   m_pRCptr = CRefcountedPtr<CVMEptr<T> >(aCVMEptr);
00179 
00180 }
00181 
00182 /*
00183   \fn CVME<T>::CVME<T>(const CVME<T>& aCVME)
00184 
00185   Operation Type:
00186      Copy Constructor
00187 
00188   Purpose:
00189      Construct a CVME<T> by copying one.
00190 */
00191 template<class T>
00192 CVME<T>::CVME(const CVME<T>& aCVME) :
00193   m_pRCptr(aCVME.m_pRCptr),
00194   m_nOffset(aCVME.m_nOffset)
00195 {
00196 
00197 }
00198 
00199 /*
00200   \fn CVME<T>& CVME<T>::operator=(const CVME<T>& aCVME)
00201 
00202   Operation Type:
00203      Assignment
00204 
00205   Purpose:
00206      Assign another CVME to this
00207 */
00208 template<class T>
00209 CVME<T>&
00210 CVME<T>::operator=(const CVME<T>& aCVME)
00211 {
00212   if(this != &aCVME) {
00213   
00214     m_nOffset = m_nOffset;
00215     m_pRCptr  = aCVME.m_pRCptr;
00216   }
00217   return *this;
00218 }
00219 
00220 /*
00221   \fn T& CVME<T>::operator*()
00222 
00223   Operation Type:
00224      Pointer dereference
00225 
00226   Purpose:
00227      Returns the value stored by the encapsulated CVMEptr at its 
00228      current offset. Throws a CRangeError exception if it catches one.
00229 */
00230 template<class T>
00231 T&
00232 CVME<T>::operator*()
00233 {
00234   try {
00235     return (*m_pRCptr)[m_nOffset];
00236   }
00237   catch(CRangeError& re) {
00238     throw re;
00239   }
00240 }
00241 
00242 /*
00243   \fn T* CVME<T>::operator->()
00244 
00245   Operation Type:
00246      Pointer dereference
00247 
00248   Purpose:
00249      Returns a pointer to the value stored by the encapsulated CVMEptr at 
00250      its current offset. Throws a CRangeError exception if it catches one.
00251 */
00252 template<class T>
00253 T*
00254 CVME<T>::operator->()
00255 {
00256   UInt_t nOffset = m_pRCptr->getOffset();
00257 
00258   try {
00259     m_pRCptr->setOffset(m_nOffset);
00260     T* ptr =  m_pRCptr.operator*().operator->();   // Here's where we could throw.
00261     m_pRCptr->setOffset(nOffset);
00262     return ptr;
00263   }
00264   catch(CRangeError& re) {
00265     m_pRCptr->setOffset(nOffset);                  // Be sure to restore the offset.
00266     throw re;
00267   }
00268 }
00269 
00270 /*
00271   \fn T& CVME<T>::operator[](UInt_t nOffset)
00272 
00273   Operation Type:
00274      Indexing(read/write)
00275 
00276   Purpose:
00277      Returns the value stored in the encapsulated CVMEptr at
00278      index nOffset. Throws a CRangeError exception if it catches one.
00279 
00280   \param UInt_t nOffset - the offset at which the value is stored.
00281 */
00282 template<class T>
00283 T&
00284 CVME<T>::operator[](UInt_t nOffset)
00285 {
00286   try {
00287     return m_pRCptr.operator*().operator[](nOffset + m_nOffset);
00288   }
00289   catch(CRangeError& re) { 
00290     throw re;
00291   }
00292 }
00293 
00294 /*
00295   \fn T& CVME<T>::operator[](UInt_t nOffset) const
00296 
00297   Operation Type:
00298      Indexing(read/write)
00299 
00300   Purpose:
00301      Returns the value stored in the encapsulated CVMEptr at
00302      index nOffset. Throws a CRangeError exception if it catches one.
00303 
00304   \param UInt_t nOffset - the offset at which the value is stored.
00305 */
00306 template<class T>
00307 T&
00308 CVME<T>::operator[](UInt_t nOffset) const
00309 {
00310   try {
00311     return m_pRCptr.operator*().operator[](nOffset + m_nOffset);
00312   }
00313   catch(CRangeError& re) {
00314     throw re;
00315   }
00316 }
00317 
00318 /*
00319   \fn CVME<T>& CVME<T>::operator+(UInt_t nOffset)
00320 
00321   Operation Type:
00322      Mutator
00323 
00324      binary + note that this will involve a minimum of 2 copy
00325      constructions/destructions of a CVME<T>.. however this is not
00326      too expensive, since it's just a matter  of some reference counting
00327      stuff.
00328 
00329      No attempt is made to ensure that the resulting pointer actually
00330      points into the VME space range originally specified.
00331 
00332   \param UInt_t nOffset - the value to add to the current offset
00333 */
00334 template<class T>
00335 CVME<T>&
00336 CVME<T>::operator+(UInt_t nOffset)
00337 {
00338   CVME<T> result(*this);
00339   result.m_nOffset += nOffset;
00340   return result;
00341 
00342 }
00343 
00344 /*
00345   \fn CVME<T>& CVME<T>::operator-(UInt_t nOffset)
00346 
00347   Operation Type:
00348      Mutator
00349 
00350      Same as operator+ but nOffset is subtracted.
00351 
00352   \param UInt_t nOffset - the value to add to the current offset
00353 */
00354 template<class T>
00355 CVME<T>&
00356 CVME<T>::operator-(UInt_t nOffset)
00357 {
00358   return operator+(-nOffset);
00359 
00360 }
00361 
00362 /*
00363   \fn CVME<T>& CVME<T>::operator+=(UInt_t nOffset)
00364 
00365   Operation Type:
00366      Mutator
00367 
00368   Purpose:
00369      Add a value to the encapsulated CVMEptr<T>'s current
00370      offset. Returns a pointer to self .
00371      exception if it catches one.
00372 
00373   \param UInt_t nOffset - the value to add to the current offset
00374 */
00375 template<class T>
00376 CVME<T>&
00377 CVME<T>::operator+=(UInt_t nOffset)
00378 {
00379   m_nOffset += nOffset;
00380   return *this;
00381 
00382 }
00383 
00384 /*
00385   \fn CVME<T>& CVME<T>::operator-=(UInt_t nOffset)
00386 
00387   Operation Type:
00388      Mutator
00389 
00390   Purpose:
00391      Subtracts a value from the encapsulated CVMEptr<T>'s current
00392      offset. Returns the new 'pointer' or throws a CRangeError
00393      exception if it catches one.
00394 
00395   \param UInt_t nOffset - the value to add to the current offset
00396 */
00397 template<class T>
00398 CVME<T>&
00399 CVME<T>::operator-=(UInt_t nOffset)
00400 {
00401   m_nOffset -= nOffset;
00402   return *this;
00403 
00404 }
00405 
00406 /*
00407   \fn CVME<T>& CVME<T>::operator++()
00408 
00409   Operation Type:
00410      Mutator
00411 
00412   Purpose:
00413      (Pre)Increment the current offset into the encapsulated CVME<T>.
00414      Throws a CRangeError exception if it catches one.
00415 */
00416 template<class T>
00417 CVME<T>&
00418 CVME<T>::operator++()
00419 {
00420   m_nOffset++;
00421   return *this;
00422 
00423 }
00424 
00425 /*
00426   \fn CVME<T>& CVME<T>::operator--()
00427 
00428   Operation Type:
00429      Mutator
00430 
00431   Purpose:
00432      (Pre)Decrement the current offset into the encapsulated CVME<T>.
00433      Throws a CRangeError exception if it catches one.
00434 */
00435 template<class T>
00436 CVME<T>&
00437 CVME<T>::operator--()
00438 {
00439   m_nOffset--;
00440   return *this;
00441 
00442 }
00443 
00444 /*
00445   \fn CVME<T>& CVME<T>::operator++(Int_t n)
00446 
00447   Operation Type:
00448      Mutator
00449 
00450   Purpose:
00451      (Post)Increment the current offset into the encapsulated CVME<T>.
00452      Throws a CRangeError exception if it catches one.
00453 
00454   \param Int_t n - dummy parameter to indicate this is a 
00455                    post-increment operator.
00456 */
00457 template<class T>
00458 CVME<T>&
00459 CVME<T>::operator++(Int_t n)
00460 {
00461   CVME<T> result(*this);
00462   m_nOffset++;
00463   return result;
00464 
00465 }
00466 
00467 /*
00468   \fn CVME<T>& CVME<T>::operator--(Int_t n)
00469 
00470   Operation Type:
00471      Mutator
00472 
00473   Purpose:
00474      (Post)Decrement the current offset into the encapsulated CVME<T>.
00475      Throws a CRangeError exception if it catches one.
00476 
00477   \param Int_t n - dummy parameter to indicate this is a 
00478                    post-decrement operator.
00479 */
00480 template<class T>
00481 CVME<T>&
00482 CVME<T>::operator--(Int_t n)
00483 {
00484   CVME<T> result(*this);
00485   m_nOffset--;
00486   return result;
00487 
00488 }
00489 
00490 /*
00491   \fn Address_t CVME<T>::getgenptr(UInt_t nOffset)
00492 
00493   Operation Type:
00494      Selector
00495 
00496   Purpose:
00497      Return a pointer to the current address+offset into the module
00498      (via the encapsulated CVMEptr<T>).
00499 
00500   \param UInt_t nOffset - an offset to use to determine the pointer
00501 */
00502 template<class T>
00503 Address_t
00504 CVME<T>::getgenptr(UInt_t nOffset)
00505 {
00506   Address_t p = m_pRCptr.operator*().getgenptr(nOffset+m_nOffset);
00507   if(p) return p;
00508   else return (Address_t)-1;
00509 }
00510 
00511 /*
00512   \fn Address_t CVME<T>::getcurrptr()
00513 
00514   Operation Type:
00515      Selector
00516 
00517   Purpose:
00518      Return a pointer to the current address+current offset into the
00519      module (via the encapsulated CVMEptr<T>).
00520 */
00521 template<class T>
00522 Address_t
00523 CVME<T>::getcurrptr()
00524 {
00525   Address_t p = m_pRCptr.operator*().getgenptr(m_nOffset);
00526   return p;
00527 }
00528 
00529 /*
00530   \fn CVME<UChar_t> CVME<T>::asChar()
00531 
00532   Operation Type:
00533      Type conversion operator
00534 
00535   Purpose:
00536      Returns this as a CVME which maps m_pStart to an address space
00537      containing data of type UChar_t.
00538 */
00539 template<class T>
00540 volatile UChar_t*
00541 CVME<T>::asChar()
00542 {
00543   volatile UChar_t* p = (UChar_t*)m_pRCptr->getStart();
00544   p         += m_pRCptr->getOffset() * sizeof(T)/sizeof(UChar_t);
00545 
00546   return p;
00547 
00548 }
00549 
00550 /*
00551   \fn CVME<UShort_t> CVME<T>::asShort()
00552 
00553   Operation Type:
00554      Type conversion operator
00555 
00556   Purpose:
00557      Returns this as a CVME which maps m_pStart to an address space
00558      containing data of type UShort_t.
00559 */
00560 template<class T>
00561 volatile UShort_t*
00562 CVME<T>::asShort()
00563 {
00564   volatile UShort_t* p = (UShort_t*)m_pRCptr->getStart();
00565   p         += m_nOffset * sizeof(T)/sizeof(UShort_t);
00566 
00567   return p;
00568 }
00569 
00570 /*
00571   \fn CVME<ULong_t> CVME<T>::asLong()
00572 
00573   Operation Type:
00574      Type conversion operator
00575 
00576   Purpose:
00577      Returns this as a CVME which maps m_pStart to an address space
00578      containing data of type ULong_t.
00579 */
00580 template<class T>
00581 volatile ULong_t*
00582 CVME<T>::asLong()
00583 {
00584   volatile ULong_t* p = (ULong_t*)m_pRCptr->getStart();
00585   p         += m_nOffset * sizeof(T)/sizeof(ULong_t);
00586 
00587   return p;
00588 }
00589 #endif

Generated on Wed Sep 17 08:38:09 2008 for NSCL Device support. by  doxygen 1.5.1