Back to index

CLabel.C

 
//----------------------------------------------------------------------------- 
//  $Header: /tmp_mnt/asis/offline/ceres/cool/project/RCS/CLabel.C,v 2.1 1996/10/04 08:42:57 voigt Exp $ 
// 
//  COOL Program Library   
//  Copyright (C) CERES collaboration, 1996 
// 
//  Implementation of class CLabel. 
// 
//----------------------------------------------------------------------------- 
#include "CLabel.h" 
#include <string.h> 
#include <iomanip.h> 
#include "CDataStream.h" 
 
CLabel::CLabel() 
{ 
   id = 0; 
   length = 0; 
   size = 0; 
   data = 0; 
   swapped = False; 
   asciiReverted = False; 
   name = ""; 
} 
 
CLabel::CLabel(const CLabel& label) 
{ 
   id = label.id; 
   length = label.length; 
   size = label.size; 
   name = label.name; 
   swapped = label.swapped; 
   asciiReverted = label.asciiReverted; 
   if (label.size > 0) { 
      data = new CWord[label.size]; 
      memcpy(data, label.data, label.size*sizeof(CWord)); 
   } 
   else 
      data = 0; 
} 
 
CLabel& CLabel::operator= (const CLabel& label) 
{   
   if (this == &label)                // same class object 
      return *this; 
   else {         
      if (size > 0) delete [] data;        // free old store 
      id = label.id; 
      length = label.length; 
      size = label.size; 
      name = label.name; 
      swapped = label.swapped; 
      asciiReverted = label.asciiReverted; 
      if (label.size > 0) { 
         data = new CWord[label.size]; 
         memcpy(data, label.data, label.size*sizeof(CWord)); 
      } 
      else 
         data = 0; 
      return *this; 
   } 
} 
 
int CLabel::operator== (const CLabel& label) const 
{ 
   return (label.id == id); 
} 
 
CLabel::~CLabel() 
{ 
   delete [] data; 
} 
 
void CLabel::swap() 
{ 
   for (int i=0; i<size; i++) 
      data[i] = (data[i] << 16 | data[i] >> 16); 
 
   swapped = swapped ? False : True;  
} 
 
void CLabel::list(ostream& ost) 
{ 
   ost << setw(10) << dec << name << setw(10) << id 
       << setw(10) << length << setw(10) << size << endl;  
} 
 
void CLabel::dump(ostream& ost, int nWordsToDump) 
{ 
   // 
   //  Header line 
   // 
   ost << "label: " << name << " (" << dec << id << "), "; 
   ost << (swapped ? "swapped" : "not swapped") << endl; 
   ost << "total length: " << dec << length << " words"; 
   ost << ", data size: " << dec << size << " words" << endl; 
    
   // 
   //  Hex dump 
   //              
   unsigned long *ldata = (unsigned long *) &data[0]; 
   int nWords; 
   nWords = (nWordsToDump == -1 ? size : nWordsToDump); 
   for (int i=0; i<nWords; i++) { 
      if (i%8 == 0) 
         ost << hex << setw(8) << setfill('0') << i*2 << ":\t"; 
      ost << ' ' << hex << setw(8) << setfill('0') << ldata[i]; 
      if (i%8 == 7 || i == nWords-1) 
         ost << dec << endl; 
   } 
} 
 
void CLabel::revertAsciiData() 
{ 
#ifdef ARCH_IS_LITTLE_ENDIAN 
  // On architectures using the little-endian byte-ordering, 
  // the interpretation of characters needs special treatment. 
  // To be interpreted correctly, all character's need to be 
  // re-ordered in their original sequence. Hence: 
  int index=0; 
  unsigned long *pbuf = data; 
  for (index=0; index<size; index++) { 
    reverse4Bytes((char *) pbuf); 
    pbuf++; 
  } 
  // now we ARE back to Big-Endian format of the buffer ... 
 
  asciiReverted = asciiReverted ? False : True; // flag it... 
 
#endif 
} 
 
void CLabel::read(Cifstream& ist) 
{ 
   // 
   //  Init data member 
   // 
   id = 0; 
   delete [] data; 
   data = 0; 
   length = 0; 
   size = 0; 
   name = ""; 
 
   if (ist.eof() || ist.bad()) return;                // nothing to read 
 
   // 
   //  Read label header 
   // 
   CWord magic; 
   ist.read((char*) &length, sizeof(CWord)); 
   ist.read((char*) &magic, sizeof(CWord)); 
    
   // 
   //  Check for magic word and read label identifiers. 
   //  If the magic word isn't at the expected position  
   //  an iterative search is started until it is found 
   //  or an EoF or corrupted istream state is detected. 
   // 
   if (magic != MagicWord) { 
      while (ist.good() && !ist.eof() && magic != MagicWord) { 
         length = (int) magic; 
         ist.read((char*) &magic, sizeof(CWord)); 
      } 
      if (ist.bad() || ist.eof()) { 
         length = 0; 
         return; 
      } 
   } 
   char text[sizeof(CWord)]; 
   ist.read((char*) &id, sizeof(CWord)); 
   ist.read(text, sizeof(CWord)); 
 
#ifdef ARCH_IS_LITTLE_ENDIAN 
   reverse4Bytes(text); // character strings need to be re-ordered... 
#endif 
 
   name = CString(text,sizeof(CWord)); 
 
   // 
   //  Store label data in newly allocated memory 
   // 
   if (length-4 > 0) { 
      data = new CWord[length-4]; 
      if (data == 0) { 
         cerr << "CLabel::read():\n"; 
         cerr << "\tERROR\n"; 
         cerr << "\tFailed allocating " << length-4 << " long words to hold data.\n"; 
         return; 
      } 
      ist.read((char*) &data[0], (length-4)*sizeof(CWord)); 
      size = ist.gcount()/sizeof(CWord); 
      if (size != length-4) { 
         cerr << "CLabel::read():\n"; 
         cerr << "\tERROR\n"; 
         cerr << "\tExtracted less data words than noted in label header.\n"; 
         cerr << "\t" << length-4 << " words expected, "; 
         cerr << size << " words read.\n"; 
      } 
   } 
    
   // 
   //  Check status of input stream 
   // 
   if (ist.bad()) { 
      cerr << "CLabel::read():\n"; 
      cerr << "\tERROR\n"; 
      cerr << "\tFailed reading complete label from input stream.\n"; 
      cerr << "\tist.bad()=" << dec << ist.bad(); 
      cerr << ", ist.rdstate()=" << dec << ist.rdstate() << endl; 
   } 
 
} 
 
void CLabel::write(Cofstream& ost) 
{ 
   if (!ost || ost.bad())  return;		// no valid ostream 
   // 
   //  Write label header 
   // 
   CWord realLength = size+4; 
   ost.write((char*) &realLength, sizeof(CWord)); 
 
#ifdef ARCH_IS_LITTLE_ENDIAN 
   char *pname = new char[sizeof(CWord)];  
   // here we need to copy in order to ensure integrity 
   // since the buffer IS modified after all 
   strncpy(pname, (const char*) &MagicWord, sizeof(CWord));  
   ost.write(pname, sizeof(CWord)); 
#else 
   ost.write((char*) &MagicWord,  sizeof(CWord)); 
#endif 
 
   ost.write((char*) &id,         sizeof(CWord)); 
 
#ifdef ARCH_IS_LITTLE_ENDIAN 
   // here we need to copy in order to ensure integrity 
   // since the buffer IS modified after all 
   strncpy(pname, name.data(), sizeof(CWord)); 
   ost.write(pname, sizeof(CWord)); 
   delete [] pname; 
#else 
   ost.write((char*) name.data(), sizeof(CWord)); 
#endif 
 
   // 
   //  Check if data are swapped or reverted 
   //  If swapped/reverted undo this before writing, but redo afterwards. 
   // 
   CBoolean wasSwapped = swapped; 
   if (swapped) this->swap(); 
    
   CBoolean wasReverted = asciiReverted; 
   if (asciiReverted) this->revertAsciiData(); 
    
   // 
   //  Write data 
   // 
   ost.write((char*) data, size*sizeof(CWord)); 
    
   if (wasSwapped) this->swap();		// back to previous state 
   if (wasReverted) this->revertAsciiData();		// back to previous state 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 

Back to index