Ignore:
Timestamp:
05/28/13 23:25:48 (11 years ago)
Author:
tbretz
Message:
added total_bytes to support the new member functions GetHeapShift and GetTotalBytes (former ComputeGapFromDataToHeap and SkipCurrentTable); ZNAXIS1 and ZNAXIS weren't checked; replaced push_back by emplace_back were reasonable; added some const-qualifiers; further simplified Constructor - now a correct file, but a missing table is reported as eof() && \!bad() as default - therefore removed the mightFail argument from the constructor
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Mars/mcore/fits.h

    r16414 r16415  
    106106        size_t num_rows;
    107107        size_t num_cols;
     108        size_t total_bytes; // NAXIS1*NAXIS2
    108109
    109110        struct Column
     
    254255            offset(off), isCompressed(false), keys(ParseBlock(vec))
    255256        {
    256             if (HasKey("ZTABLE"))
    257             if (Check("ZTABLE", 'B', "T"))
    258             {
     257            if (HasKey("ZTABLE") && Check("ZTABLE", 'B', "T"))
    259258                isCompressed = true;
    260             }
    261259
    262260            if (!Check("XTENSION", 'T', "BINTABLE") ||
     
    272270            if (isCompressed)
    273271            {
    274                 if (!Check("ZPCOUNT", 'I', "0"))
     272                if (!Check("ZNAXIS1", 'I') ||
     273                    !Check("ZNAXIS2", 'I') ||
     274                    !Check("ZPCOUNT", 'I', "0"))
    275275                    return;
    276276            }
     
    281281            }
    282282
     283            total_bytes   = Get<size_t>("NAXIS1")*Get<size_t>("NAXIS2");
    283284            bytes_per_row = isCompressed ? Get<size_t>("ZNAXIS1") : Get<size_t>("NAXIS1");
    284285            num_rows      = isCompressed ? Get<size_t>("ZNAXIS2") : Get<size_t>("NAXIS2");
     
    467468            return it==cols.end() ? 0 : it->second.num;
    468469        }
     470
     471        // There may be a gap between the main table and the start of the heap:
     472        // this computes the offset
     473        streamoff GetHeapShift() const
     474        {
     475            if (!HasKey("THEAP"))
     476                return 0;
     477
     478            const streamoff shift = Get<streamoff>("THEAP");
     479            return shift <= total_bytes ? 0 : shift - total_bytes;
     480        }
     481
     482        // return total number of bytes 'all inclusive'
     483        streamoff GetTotalBytes() const
     484        {
     485            //get offset of special data area from start of main table
     486            const streamoff shift = GetHeapShift();
     487
     488            //and special data area size
     489            const streamoff size  = HasKey("PCOUNT") ? Get<streamoff>("PCOUNT") : 0;
     490
     491            // Get the total size
     492            const streamoff total = total_bytes + size + shift;
     493
     494            // check for padding
     495            if (total%2880==0)
     496                return total;
     497
     498            // padding necessary
     499            return total + (2880 - (total%2880));
     500        }
    469501    };
    470502
     
    534566        // Make sure that no empty vector is returned
    535567        if (endtag && vec.size()%36==0)
    536             vec.push_back(string("END     = '' / "));
     568            vec.emplace_back("END     = '' / ");
    537569
    538570        return endtag==2;
    539571    }
    540572
    541     string Compile(const string &key, int16_t i=-1)
     573    string Compile(const string &key, int16_t i=-1) const
    542574    {
    543575        if (i<0)
     
    549581    }
    550582
    551     //There may be a gap between the main table and the start of the heap: this computes the offset
    552     size_t ComputeGapFromDataToHeap(const Table& table)
    553     {
    554         //get row width
    555         const size_t rowWidth = table.Get<size_t>("NAXIS1");
    556         const size_t numRows  = table.Get<size_t>("NAXIS2");
    557 
    558         //get offset of special data area from start of main table
    559         size_t heapShift = HasKey("THEAP") ? table.Get<size_t>("THEAP") : 0;
    560         if (heapShift > rowWidth*numRows)
    561             heapShift -= rowWidth*numRows;
    562         else
    563             heapShift = 0;
    564 
    565         return heapShift;
    566     }
    567 
    568     //skip the current table
    569     bool SkipCurrentTable(const vector<string>& vector)
    570     {
    571         Table currentTable(vector, tellg());
    572         //get row width
    573         const size_t rowWidth = currentTable.Get<size_t>("NAXIS1");
    574         const size_t numRows  = currentTable.Get<size_t>("NAXIS2");
    575         const off_t  numTableBytes = rowWidth*numRows;
    576 
    577         //get offset of special data area from start of main table
    578         const off_t heapShift = ComputeGapFromDataToHeap(currentTable);
    579 
    580         //and special data area size
    581         const off_t heapSize  = HasKey("PCOUNT") ? currentTable.Get<off_t>("PCOUNT") : 0;
    582 
    583         //skip the row of the table, padded to 2880 bytes
    584         off_t paddingSize     = (rowWidth*numRows + heapSize + heapShift)%2880;
    585         paddingSize += (paddingSize==0) ? 0 : 2880 - paddingSize;
    586 
    587         const off_t whereDoIGo = tellg() + numTableBytes + heapSize + heapShift + paddingSize;
    588         seekg(whereDoIGo);
    589 
    590         return good();
    591     }
    592 
    593     void Constructor(const string &fname, string fout, const string& tableName, bool force, bool mightFail)
     583    void Constructor(const string &fname, string fout, const string& tableName, bool force)
    594584    {
    595585        char simple[10];
     
    616606            while (1)
    617607            {
     608                // If we search for a table, we implicitly assume that
     609                // not finding the table is not an error. The user
     610                // can easily check that by eof() && !bad()
     611                peek();
     612                if (eof() && !bad() && !tableName.empty())
     613                    break;
     614
    618615                // FIXME: Set limit on memory consumption
    619616                const int rc = ReadBlock(block);
    620617                if (!good())
    621618                {
    622                     //we allow that the table is not found (to be checked later on with bool casting)
    623                     if (mightFail) { return;}
    624 
    625619                    clear(rdstate()|ios::badbit);
    626620#ifdef __EXCEPTIONS
     
    648642            }
    649643
    650             if (block.size()==0)
     644            if (block.empty())
    651645                break;
    652646
     
    659653            if (block[0].substr(0, 9)=="XTENSION=")
    660654            {
    661                 //Check for table name. Skip until eof or requested table are found.
    662                 if (tableName != "")
    663                 {
    664                     Table currentTable(block, tellg());
    665                     string currentName = currentTable.Get<string>("EXTNAME");
    666                     if (currentName != tableName)
    667                     {
    668                         SkipCurrentTable(block);
    669                         fChkHeader.reset();
    670                         continue;
    671                     }
    672                 }
    673655                fTable = Table(block, tellg());
    674656                fRow   = (size_t)-1;
    675 
    676                 //fTable.PrintKeys();
    677657
    678658                if (!fTable)
     
    682662                }
    683663
     664                //Check for table name. Skip until eof or requested table are found.
     665                // skip the current table?
     666                if (!tableName.empty() && tableName!=fTable.Get<string>("EXTNAME"))
     667                {
     668                    const streamoff skip = fTable.GetTotalBytes();
     669                    seekg(skip, ios_base::cur);
     670
     671                    fChkHeader.reset();
     672
     673                    continue;
     674                }
     675
     676                //fTable.PrintKeys();
     677
    684678                fBufferRow.resize(fTable.bytes_per_row + 8-fTable.bytes_per_row%4);
    685679                fBufferDat.resize(fTable.bytes_per_row);
    686 
    687                 /*
    688                  // Next table should start at:
    689                  const size_t size = fTable.bytes_per_row*fTable.num_rows;
    690                  const size_t blks = size/(36*80);
    691                  const size_t rest = size%(36*80);
    692 
    693                 seekg((blks+(rest>0?1:0))*(36*80), ios::cur);
    694                 if (!good())
    695                      gLog << ___err___ << "File seems to be incomplete (less data than expected from header)." << endl;
    696 
    697                 fRow   = fTable.num_rows;
    698                  */
    699680
    700681                break;
     
    734715
    735716public:
    736     fits(const string &fname, const string& tableName="", bool force=false, bool mightFail=false) : izstream(fname.c_str())
    737     {
    738         Constructor(fname, "", tableName, force, mightFail);
    739     }
    740 
    741     fits(const string &fname, const string &fout, const string& tableName="", bool force=false, bool mightFail=false) : izstream(fname.c_str())
    742     {
    743         Constructor(fname, fout, tableName, force, mightFail);
     717    fits(const string &fname, const string& tableName="", bool force=false) : izstream(fname.c_str())
     718    {
     719        Constructor(fname, "", tableName, force);
     720    }
     721
     722    fits(const string &fname, const string &fout, const string& tableName, bool force=false) : izstream(fname.c_str())
     723    {
     724        Constructor(fname, fout, tableName, force);
    744725    }
    745726
     
    879860        {
    880861            ostringstream str;
    881             str <<"SetPtrAddress('" << name << "') - Column not found." << endl;
     862            str << "SetPtrAddress('" << name << "') - Column not found." << endl;
    882863#ifdef __EXCEPTIONS
    883864            throw runtime_error(str.str());
     
    892873            return it->second;
    893874
    894         fGarbage.push_back(vector<char>(fTable.cols[name].size*fTable.cols[name].num));
     875        fGarbage.emplace_back(fTable.cols[name].size*fTable.cols[name].num);
    895876
    896877        void *ptr = fGarbage.back().data();
    897878
    898879        fPointers[name] = ptr;
    899         fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
     880        fAddresses.emplace_back(ptr, fTable.cols[name]);
    900881        sort(fAddresses.begin(), fAddresses.end(), Compare);
    901882        return ptr;
     
    948929        //fAddresses[ptr] = fTable.cols[name];
    949930        fPointers[name] = ptr;
    950         fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
     931        fAddresses.emplace_back(ptr, fTable.cols[name]);
    951932        sort(fAddresses.begin(), fAddresses.end(), Compare);
    952933        return true;
     
    996977        //fAddresses[ptr] = fTable.cols[name];
    997978        fPointers[name] = ptr;
    998         fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
     979        fAddresses.emplace_back(ptr, fTable.cols[name]);
    999980        sort(fAddresses.begin(), fAddresses.end(), Compare);
    1000981        return true;
Note: See TracChangeset for help on using the changeset viewer.