Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phDataObject.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <phObject.h>
00033 #include <phMutex.h>
00034 #include <phSemaphore.h>
00035 #include <phCondition.h>
00036 #include <phRWLock.h>
00037 #include <phThread.h>
00038 #include <phList.h>
00039 #include <phTimeStamp.h>
00040 #include <phTimeInterval.h>
00041 #include <phLiveObject.h>
00042 
00043 #include <phDataObject.h>
00044 
00045 #ifdef HAVE_UNISTD_H
00046 //    #include <unistd.h>
00047 #endif
00048 #ifdef HAVE_ERRNO_H
00049 //    #include <errno.h>
00050 #endif
00051 
00052 #include <phError.h>
00053 #include <phMemory.h>
00054 #include <phPrint.h>
00055 
00056 #if 0
00057 // this is just an idea that I will leave here in the commented code for now
00058 /* ---------------------------------------------------------------------- */
00059 typedef struct phTimeElement_t {
00060     struct timeval time_stamp;
00061     struct phTimeElement *next;
00062     struct phTimeElement *prev;
00063 } phTimeElement;
00064 
00065 class phTimeArray : public phMutex
00066 {
00067 protected:
00068     phTimeElement *head;
00069     phTimeElement *tail;
00070 };
00071 #endif
00072 
00073 /* ---------------------------------------------------------------------- */
00074 phDataObject::phDataObject( )
00075 {
00076     phFUNCTION("phDataObject::phDataObject")
00077 
00078     this->phLiveObject::setName("phDataObject");
00079 
00080     this->m_temp        = NULL;
00081     this->m_temp_size   = 0;
00082     this->m_data        = NULL;
00083     this->m_size        = 0x0;
00084 }
00085 
00086 /* ---------------------------------------------------------------------- */
00087 phDataObject::~phDataObject( )
00088 {
00089     phFUNCTION("phDataObject::~phDataObject")
00090     int locked      = 0;
00091 
00092     /* lock the phLiveObject part of this class */
00093     phTHIS_LOOSE_LOCK(locked);
00094  
00095     rc = this->reset();
00096     phPRINT_RC(rc,NULL,"this->reset()");
00097 }
00098 
00099 /* ---------------------------------------------------------------------- */
00100 uint32_t phDataObject::getSize() 
00101 { 
00102     return this->m_size; 
00103 }
00104 
00105 /* ---------------------------------------------------------------------- */
00106 const void *phDataObject::getData() 
00107 { 
00108     return (const void *)this->m_data;
00109 }
00110 
00111 /* ---------------------------------------------------------------------- */
00112 int phDataObject::copy( phObject *copyto_object ) 
00113 {
00114     phFUNCTION("phDataObject::copy")
00115     
00116     if (this->isNamed(((phObject *)copyto_object)->getName()))
00117     {
00118         phDataObject *copyto_data = (phDataObject *)copyto_object;
00119         return copyto_data->setData(*this);
00120     }
00121     /* Otherwise I'll assume they are incompatible */
00122     else
00123     {
00124         phPRINT_RC(-1,NULL, "Invalid object pairing in update."
00125                           "[ this:%s != target:%s ]",
00126                  this->getName(), ((phObject *)copyto_object)->getName());
00127         return phFAIL;
00128     }
00129 }
00130 
00131 /* ---------------------------------------------------------------------- */
00132 int phDataObject::swap( phObject *object ) 
00133 {
00134     phFUNCTION("phDataObject::swap")
00135     
00136     if (this->isNamed(((phObject *)object)->getName()))
00137     {
00138         phDataObject *data = (phDataObject *)object;
00139         
00140         return data->swapData(*this);
00141     }
00142     /* Otherwise I'll assume they are incompatible */
00143     else
00144     {
00145         phPRINT_RC(-1,NULL, "Invalid object pairing in update."
00146                           "[ this:%s != target:%s ]",
00147                  this->getName(), ((phObject *)object)->getName());
00148         return phFAIL;
00149     }
00150 
00151 }
00152 
00153 /* ---------------------------------------------------------------------- */
00154 int phDataObject::getCopy( phDataObject &object )
00155 {
00156     phFUNCTION("phDataObject::getCopy")
00157     int locked      = 0;
00158     int obj_locked  = 0;
00159 
00160     phTHIS_READLOCK(locked);
00161     phWRITELOCK(object,obj_locked);
00162 
00163     rc = object.setData(this->getSize(),this->getData());
00164     phCHECK_RC(rc,NULL,"object.setData");
00165     
00166     phRWUNLOCK(object,obj_locked);
00167     phTHIS_RWUNLOCK(locked);
00168     
00169     return phSUCCESS;
00170 error:
00171     phRWUNLOCK_ERROR(object,obj_locked);
00172     phTHIS_RWUNLOCK_ERROR(locked);
00173    
00174     return phFAIL;
00175 }
00176 
00177 /* ---------------------------------------------------------------------- */
00178 int phDataObject::setData( phDataObject &copyfrom, 
00179                            int          disable_notify )
00180 {
00181     phFUNCTION("phDataObject::setData")
00182     int locked      = 0;
00183     int copy_locked = 0;
00184 
00185     phTHIS_WRITELOCK(locked);
00186     phREADLOCK(copyfrom,copy_locked);
00187    
00188     /* setData calls notify */
00189     rc = this->setData(copyfrom.getSize(),
00190                        copyfrom.getData(),
00191                        disable_notify );
00192     phCHECK_RC(rc,NULL,"this->setData(i,p,i)");    
00193     
00194     phRWUNLOCK(copyfrom,copy_locked); 
00195     phTHIS_RWUNLOCK(locked);
00196     
00197     return phSUCCESS;
00198 error:
00199     phRWUNLOCK_ERROR(copyfrom,copy_locked); 
00200     phTHIS_RWUNLOCK_ERROR(locked);
00201     
00202     return phFAIL;
00203 }
00204 
00205 /* ---------------------------------------------------------------------- */
00206 int phDataObject::setData( uint32_t     newsize,
00207                            const void   *newdata,
00208                            int          disable_notify )
00209 {
00210     phFUNCTION("phDataObject::setData")
00211     int     locked      = 0;
00212     int     buffer      = 0;
00213     void    *bufferData = NULL;
00214 
00215     if (newdata == NULL) {
00216         phERR_PRINT("newdata == NULL\n");
00217         return 1;
00218     }
00219 
00220     /* if newdata and the current data are the same, 
00221      * we don't need to do anything, do we? */
00222     if (newdata == this->m_data) {
00223         return 1;
00224     }
00225 
00226     phTHIS_WRITELOCK(locked);
00227     
00228     /* -------------------------------------------- */
00229     /* This checks for overlap because the buffer could 
00230      * be resized and destroy the data in the allocation/resize code below */
00231     if ((newdata >= this->m_data) && 
00232         (newdata <= (((uint8_t *)this->m_data) + this->m_size)))
00233     {
00234         buffer = 1;
00235     }
00236 
00237     if (buffer)
00238     {
00239         bufferData = phMalloc(newsize);
00240         phMemcpy(bufferData,newdata,newsize);
00241     }
00242 
00243     /* Allocate... */
00244     if ((this->m_data == NULL) || (this->m_size == 0))
00245     {
00246         /* need to initialize data to some memory */
00247         this->m_data = (void *)phMalloc(newsize);
00248         phCHECK_NULLPTR(this->m_data,"phMalloc","phMalloc failed");
00249         
00250         phMemset(this->m_data,0,newsize);
00251         
00252         this->m_size = newsize;
00253     }
00254     /* ... Resize */
00255     else if (this->m_size != newsize)
00256     {
00257         /* allocate a different amount of space, more.. less.. */
00258         this->m_data = (void *)phRealloc((void *)this->m_data, newsize );
00259         phCHECK_NULLPTR(this->m_data,"phRealloc","phRealloc failed");        
00260         
00261         this->m_size = newsize;
00262     }
00263 
00264 
00265     /* if we buffered the data coming in, then copy the data into the object */
00266     if (buffer)
00267     {
00268         phMemcpy(this->m_data,bufferData,this->m_size);
00269         phFree(bufferData);    
00270     }
00271     else
00272     {
00273         phMemcpy(this->m_data,newdata,this->m_size);  
00274     }
00275 
00276     if (disable_notify == 0)
00277     {
00278         rc = this->notify();
00279     }
00280 
00281     phTHIS_RWUNLOCK(locked);
00282     
00283     return phSUCCESS;
00284 error:
00285     phTHIS_RWUNLOCK_ERROR(locked);
00286     
00287     phFree(bufferData);
00288 
00289     return phFAIL;
00290 }
00291 
00292 /* ---------------------------------------------------------------------- */
00293 int phDataObject::setData( uint32_t         newsize,
00294                            const uint8_t    newdata[],
00295                            int              disable_notify )
00296 {
00297     phFUNCTION("phDataObject::setData")
00298     int  locked     = 0;
00299     /* int buffer = 0; */
00300     void *bufferData= NULL;
00301 
00302     if (newdata == NULL) {
00303         phERR_PRINT("newdata == NULL\n");
00304         return 1;
00305     }
00306 
00307     phTHIS_WRITELOCK(locked);
00308     
00309     /* Allocate... */
00310     if ((this->m_data == NULL) || (this->m_size == 0))
00311     {
00312         /* need to initialize data to some memory */
00313         this->m_data = (void *)phMalloc(newsize);
00314         phCHECK_NULLPTR(this->m_data,"phMalloc","phMalloc failed");
00315         
00316         phMemset(this->m_data,0,newsize);
00317         
00318         this->m_size = newsize;
00319     }
00320     /* ... Resize */
00321     else if (this->m_size != newsize)
00322     {
00323         /* allocate a different amount of space, more.. less.. */
00324         this->m_data = (void *)phRealloc((void *)this->m_data, newsize );
00325         phCHECK_NULLPTR(this->m_data,"phRealloc","phRealloc failed");        
00326         
00327         this->m_size = newsize;
00328     }
00329 
00330     phMemmove(this->m_data,newdata,this->m_size);  
00331 
00332     if (disable_notify == 0)
00333     {
00334         rc = this->notify();
00335     }
00336 
00337     phTHIS_RWUNLOCK(locked);
00338     
00339     return phSUCCESS;
00340 error:
00341     phTHIS_RWUNLOCK_ERROR(locked);
00342     
00343     phFree(bufferData);
00344 
00345     return phFAIL;
00346 }
00347 
00348 /* ---------------------------------------------------------------------- */
00349 int phDataObject::swapData( phDataObject    &object, 
00350                             int             disable_notify )
00351 {
00352     phFUNCTION("phDataObject::swapData")
00353     int         locked      = 0;
00354     int         obj_locked  = 0;
00355 
00356     phTHIS_WRITELOCK(locked);
00357 
00358     if (this->isSwapEnabled())
00359     {
00360         phWRITELOCK(object,obj_locked);
00361 
00362         /* swapData will call notify */
00363         rc = this->swapData(&(object.m_size),
00364                             &(object.m_data),
00365                             disable_notify );
00366         phCHECK_RC(rc,NULL,"this->swapData(p,p,i)");    
00367    
00368         phRWUNLOCK(object,obj_locked);
00369     }
00370     else
00371     {
00372         rc = this->setData(object,disable_notify);
00373         phCHECK_RC(rc,NULL,"this->setData(p,i)");    
00374     }
00375     
00376     phTHIS_RWUNLOCK(locked);
00377     
00378     return phSUCCESS;
00379 
00380 error:
00381     phRWUNLOCK_ERROR(object,obj_locked);
00382     phTHIS_RWUNLOCK_ERROR(locked);
00383     
00384     return phFAIL;
00385 }
00386 
00387 /* ---------------------------------------------------------------------- */
00388 int phDataObject::swapData( uint32_t    *psize,
00389                             void        **pdata,
00390                             int         disable_notify )
00391 {
00392     phFUNCTION("phDataObject::swapData")
00393     int         locked  = 0;
00394     void        *ptr    = NULL;
00395     uint32_t    size    = 0;
00396 
00397     if ((pdata == NULL) || (psize == NULL)) return 1;
00398 
00399     phTHIS_WRITELOCK(locked);
00400 
00401     if (this->isSwapEnabled())
00402     {
00403         ptr = *pdata;
00404         *pdata = this->m_data;
00405         this->m_data = ptr;
00406 
00407         size = *psize;
00408         *psize = this->m_size;
00409         this->m_size = size;
00410     
00411         if (disable_notify == 0)
00412         {
00413             rc = this->notify();
00414         }
00415     }
00416     else
00417     {
00418         rc = this->setData(*psize,*pdata,disable_notify);
00419         phCHECK_RC(rc,NULL,"this->setData");
00420     }
00421     phTHIS_RWUNLOCK(locked);
00422     
00423     return phSUCCESS;
00424     
00425 error:
00426     phTHIS_RWUNLOCK_ERROR(locked);
00427     
00428     return phFAIL;
00429 }
00430 
00431 /* ---------------------------------------------------------------------- */
00432 int phDataObject::swapData( uint32_t    size,
00433                             uint8_t     databuf[],
00434                             int         disable_notify )
00435 {
00436     phFUNCTION("phDataObject::swapData")
00437     int         locked      = 0;
00438     int         copysize    = 0;
00439     int         retval      = phSUCCESS;
00440 
00441     if ((databuf == NULL) || (size <= 0)) return 1;
00442     
00443     phTHIS_WRITELOCK(locked);
00444 
00445     phDALLOC_RESIZE(this->m_temp,
00446                     this->m_temp_size,
00447                     size,
00448                     uint8_t);
00449 
00450     phMemcpy(this->m_temp,databuf,size);
00451     
00452     if (this->m_size > 0)
00453     {
00454         retval = this->m_size;
00455         if (size < this->m_size)
00456             copysize = size;
00457         else
00458             copysize = this->m_size;
00459         
00460         phMemcpy(databuf,this->m_data,copysize);
00461     }
00462     
00463     if (this->m_size != size)
00464     {
00465         if (this->m_data != NULL)
00466         {
00467             this->m_data = (uint8_t*)phRealloc((void *)this->m_data,size);
00468             phCHECK_PTR(this->m_data,"phRealloc", "phRealloc failed.");
00469         }
00470         else
00471         {
00472             this->m_data = (uint8_t*)phCalloc(size,sizeof(uint8_t));
00473             phCHECK_PTR(this->m_data,"phCalloc", "phCalloc failed.");
00474         }
00475     }
00476     this->m_size = size;
00477     
00478     phMemcpy(this->m_data,this->m_temp,this->m_size);
00479     
00480     if (disable_notify == 0)
00481     {
00482         rc = this->notify();
00483     }
00484 
00485     phTHIS_RWUNLOCK(locked);
00486     
00487     return retval;
00488     
00489 error:
00490     phTHIS_RWUNLOCK_ERROR(locked);
00491     
00492     return phFAIL;
00493 }
00494 
00495 /* ---------------------------------------------------------------------- */
00496 int phDataObject::allocate( uint32_t newsize )
00497 {
00498     phFUNCTION("phDataObject::allocate")
00499     int locked = 0;
00500 
00501     phTHIS_WRITELOCK(locked);
00502 
00503     phDALLOC(this->m_data,this->m_size,newsize,uint8_t);
00504     
00505     phTHIS_RWUNLOCK(locked);
00506     
00507     return phSUCCESS;
00508 
00509 error:
00510     phTHIS_RWUNLOCK_ERROR(locked);
00511     
00512     return phFAIL;
00513 }
00514 
00515 /* ---------------------------------------------------------------------- */
00516 int phDataObject::allocate( uint32_t nelems, uint32_t elemsize )
00517 {
00518     return this->allocate( nelems * elemsize );
00519 }
00520 
00521 /* ---------------------------------------------------------------------- */
00522 int phDataObject::reset(  )
00523 {
00524     phFUNCTION("phDataObject::reset")
00525     int locked = 0;
00526 
00527     phTHIS_WRITELOCK(locked);
00528 
00529     this->m_temp_size   = 0;
00530     phFree(this->m_temp);
00531     this->m_size        = 0;
00532     phFree(this->m_data);
00533 
00534     phTHIS_RWUNLOCK(locked);
00535     
00536     return phSUCCESS;
00537 
00538 error:
00539     phTHIS_RWUNLOCK_ERROR(locked);
00540     
00541     return phFAIL;
00542 }
00543 
00544 /* ---------------------------------------------------------------------- */
00545 int phDataObject::erase(  )
00546 {
00547     phFUNCTION("phDataObject::erase")
00548     int locked = 0;
00549 
00550     phTHIS_WRITELOCK(locked);
00551 
00552     if ((this->m_data != NULL) && (this->m_size != 0))
00553     {
00554         phMemset (this->m_data,0,this->m_size);
00555     }
00556     
00557     phTHIS_RWUNLOCK(locked);
00558     
00559     return phSUCCESS;
00560 error:
00561     phTHIS_RWUNLOCK_ERROR(locked);
00562     
00563     return phFAIL;
00564 }
00565 
00566 /* ---------------------------------------------------------------------- */
00567 int phDataObject::isNull() 
00568 { 
00569     return ((this->getData() == NULL) ? 1 : 0); 
00570 }
00571 
00572 /* ---------------------------------------------------------------------- */
00573 phDataObject& phDataObject::operator = (phDataObject &rightHand)
00574 {
00575     phFUNCTION("phDataObject::operator =")
00576     int locked      = 0;
00577     int right_locked= 0;
00578 
00579     phTHIS_WRITELOCK(locked);
00580     phWRITELOCK(rightHand,right_locked);
00581     
00582     rc = rightHand.getCopy(*this);
00583     phCHECK_RC(rc,NULL,"getCopy failed");    
00584     
00585 error:
00586     phRWUNLOCK_ERROR(rightHand,right_locked);
00587     phTHIS_RWUNLOCK_ERROR(locked);
00588    
00589     return *this;
00590 }




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4