コード例 #1
0
PRUint32 nsOEScanBoxes::CountMailboxes( MailboxEntry *pBox)
{
  if (pBox == nsnull) {
    if (m_pFirst != nsnull)
      pBox = m_pFirst;
    else {
      if (m_entryArray.Count() > 0)
        pBox = (MailboxEntry *) m_entryArray.ElementAt( 0);
    }
  }
  PRUint32    count = 0;

  MailboxEntry *  pChild;
  while (pBox) {
    count++;
    if (pBox->child) {
      pChild = GetIndexEntry( pBox->child);
      if (pChild != nsnull)
        count += CountMailboxes( pChild);
    }
    if (pBox->sibling != -1) {
      pBox = GetIndexEntry( pBox->sibling);
    }
    else
      pBox = nsnull;
  }

  return( count);
}
コード例 #2
0
ファイル: stMNode.cpp プロジェクト: tureba/arboretum
//------------------------------------------------------------------------------
stDistance stMIndexNode::GetMinimumRadius(){
   int i;
   stDistance d = 0;
   stDistance r;

   for (i = 0; i < GetNumberOfEntries(); i++){
      r = GetIndexEntry(i).Distance + GetIndexEntry(i).Radius;
      if (d < r){
         d = r;
      }//end if
   }//end for

   return d;
}//end stMIndexNode::GetMinimumRadius
コード例 #3
0
ファイル: stSlimNode.cpp プロジェクト: tureba/arboretum
//------------------------------------------------------------------------------
stDistance stSlimIndexNode::GetMinimumRadius(){
   stDistance minRadius = 0;
   stDistance distance;
   stCount i;

   // For each entry.
   for (i = 0; i < GetNumberOfEntries(); i++){
      distance = GetIndexEntry(i).Distance + GetIndexEntry(i).Radius;
      if (minRadius < distance){
         minRadius = distance;
      }//end if
   }//end for

   return minRadius;
}//end stSlimIndexNode::GetMinimumRadius
コード例 #4
0
void nsOEScanBoxes::AddChildEntry( MailboxEntry *pEntry, PRUint32 rootIndex)
{
  if (!m_pFirst) {
    if (pEntry->parent == rootIndex) {
      m_pFirst = pEntry;
      m_entryArray.AppendElement( pEntry);
    }
    else {
      delete pEntry;
    }
    return;
  }

  MailboxEntry *  pParent = nsnull;
  MailboxEntry *  pSibling = nsnull;
  if (pEntry->parent == rootIndex) {
    pSibling = m_pFirst;
  }
  else {
    pParent = GetIndexEntry( pEntry->parent);
  }

  if (!pParent && !pSibling) {
    delete pEntry;
    return;
  }

  if (pParent && (pParent->child == 0)) {
    pParent->child = pEntry->index;
    m_entryArray.AppendElement( pEntry);
    return;
  }

  if (!pSibling)
    pSibling = GetIndexEntry( pParent->child);

  while (pSibling && (pSibling->sibling != -1)) {
    pSibling = GetIndexEntry( pSibling->sibling);
  }

  if (!pSibling) {
    delete pEntry;
    return;
  }

  pSibling->sibling = pEntry->index;
  m_entryArray.AppendElement( pEntry);
}
コード例 #5
0
TC_Error_Code TCDS_Ascii_Harmonic::LoadData(const wxString &data_file_path)
{
    if(m_IndexFile) IndexFileIO( IFF_CLOSE, 0 );

    m_indexfile_name = data_file_path;

    TC_Error_Code error_return = init_index_file();
    if(error_return != TC_NO_ERROR)
        return error_return;

    wxFileName f(data_file_path);
    m_harmfile_name = f.GetPath( wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME );
    m_harmfile_name += f.GetName();
    error_return = LoadHarmonicConstants(m_harmfile_name);

    //  Mark the index entries individually with invariant harmonic constants
    unsigned int max_index = GetMaxIndex();
    for(unsigned int i=0 ; i < max_index ; i++) {
        IDX_entry *pIDX = GetIndexEntry( i );
        if(pIDX) {
            pIDX->num_nodes = num_nodes;
            pIDX->num_csts = num_csts;
            pIDX->num_epochs = num_epochs;
            pIDX->m_cst_speeds = m_cst_speeds;
            pIDX->m_cst_nodes = m_cst_nodes;
            pIDX->m_cst_epochs = m_cst_epochs;
            pIDX->first_year = m_first_year;
            pIDX->m_work_buffer = m_work_buffer;
        }
    }

    return error_return;
}
コード例 #6
0
ファイル: stSlimNode.cpp プロジェクト: tureba/arboretum
//------------------------------------------------------------------------------
stCount stSlimIndexNode::GetTotalObjectCount(){
   stSize count;
   stCount i;

   count = 0;
   for (i = 0; i < GetNumberOfEntries(); i++){
      count += GetIndexEntry(i).NEntries;
   }//end for

   return count;
}//end stSlimIndexNode::GetTotalObjectCount
コード例 #7
0
ファイル: AreaNodeIndex.cpp プロジェクト: dotevo/sosmscout
  bool AreaNodeIndex::GetOffsets(const StyleConfig& styleConfig,
                                 double minlon,
                                 double minlat,
                                 double maxlon,
                                 double maxlat,
                                 const std::vector<TypeId>& types,
                                 size_t maxNodeCount,
                                 std::vector<FileOffset>& nodeOffsets) const
  {
    std::vector<FileOffset> newNodeOffsets;
    bool                    stop;
    std::vector<size_t>     ctx;  // tile x coordinates in this level
    std::vector<size_t>     cty;  // tile y coordinates in this level
    std::vector<FileOffset> co;   // offsets in this level

    std::vector<size_t>     ntx;  // tile x coordinates in next level
    std::vector<size_t>     nty;  // tile y coordinates in next level
    std::vector<FileOffset> no;   // offsets in next level

    nodeOffsets.clear();
    nodeOffsets.reserve(std::min(100000u,(uint32_t)maxNodeCount));
    newNodeOffsets.reserve(std::min(100000u,(uint32_t)maxNodeCount));
/*
    minlon+=180;
    maxlon+=180;
    minlat+=90;
    maxlat+=90;
*/
    stop=false;
    for (std::vector<TypeId>::const_iterator type=types.begin();
         !stop && type!=types.end();
         ++type) {
      if (*type>=topLevelOffsets.size() ||
          topLevelOffsets[*type]==0) {
        continue;
      }

      newNodeOffsets.clear();

      // Start at the top of the index
      ctx.clear();
      cty.clear();
      co.clear();
      ctx.push_back(0);
      cty.push_back(0);
      co.push_back(topLevelOffsets[*type]);

      for (size_t level=0;
           !stop &&
           !co.empty();
           level++) {
        // Clear the list of new index tiles
        ntx.clear();
        nty.clear();
        no.clear();

        // For all tiles...
        for (size_t i=0; !stop && i<co.size(); i++) {
          size_t cx;
          size_t cy;
          double x;
          double y;

          LeafCache::CacheRef entry;

          if (!GetIndexEntry(co[i],entry)) {
            std::cerr << "Cannot find offset " << co[i] << " in level " << level << ", => aborting!" << std::endl;
            return false;
          }

          // Evaluate data

          if (nodeOffsets.size()+
              newNodeOffsets.size()+entry->value.offsets.size()>maxNodeCount) {
            /*
            std::cout << "Maximum node limit hit: " << nodeOffsets.size();
            std::cout << "+" << newNodeOffsets.size();
            std::cout << "+" << entry->value.offsets.size();
            std::cout << ">" << maxNodeCount << " for type " << types[*type] << std::endl;*/
            stop=true;
            break;
          }

          for (std::vector<FileOffset>::const_iterator offset=entry->value.offsets.begin();
               offset!=entry->value.offsets.end();
               ++offset) {
            newNodeOffsets.push_back(*offset);
          }

          // Now calculate the new index tiles for the next level

          cx=ctx[i]*2;
          cy=cty[i]*2;

          if (entry->value.children[0]!=0) {
            // top left

            x=cx*cellWidth[level+1];
            y=(cy+1)*cellHeight[level+1];

            if (!(x>maxlon ||
                  y>maxlat ||
                  x+cellWidth[level+1]<minlon ||
                  y+cellHeight[level+1]<minlat)) {
              ntx.push_back(cx);
              nty.push_back(cy+1);
              no.push_back(entry->value.children[0]);
            }
          }

          if (entry->value.children[1]!=0) {
            // top right
            x=(cx+1)*cellWidth[level+1];
            y=(cy+1)*cellHeight[level+1];

            if (!(x>maxlon ||
                  y>maxlat ||
                  x+cellWidth[level+1]<minlon ||
                  y+cellHeight[level+1]<minlat)) {
              ntx.push_back(cx+1);
              nty.push_back(cy+1);
              no.push_back(entry->value.children[1]);
            }
          }

          if (entry->value.children[2]!=0) {
            // bottom left
            x=cx*cellWidth[level+1];
            y=cy*cellHeight[level+1];

            if (!(x>maxlon ||
                  y>maxlat ||
                  x+cellWidth[level+1]<minlon ||
                  y+cellHeight[level+1]<minlat)) {
              ntx.push_back(cx);
              nty.push_back(cy);
              no.push_back(entry->value.children[2]);
              }
          }

          if (entry->value.children[3]!=0) {
            // bottom right
            x=(cx+1)*cellWidth[level+1];
            y=cy*cellHeight[level+1];

            if (!(x>maxlon ||
                  y>maxlat ||
                  x+cellWidth[level+1]<minlon ||
                  y+cellHeight[level+1]<minlat)) {
              ntx.push_back(cx+1);
              nty.push_back(cy);
              no.push_back(entry->value.children[3]);
            }
          }
        }

        ctx=ntx;
        cty=nty;
        co=no;
      }

      if (!stop) {
        for (std::vector<FileOffset>::const_iterator offset=newNodeOffsets.begin();
             offset!=newNodeOffsets.end();
             ++offset) {
          nodeOffsets.push_back(*offset);
        }
      }
    }

    return true;
  }
コード例 #8
0
void nsOEScanBoxes::BuildMailboxList( MailboxEntry *pBox, nsIFile * root, PRInt32 depth, nsISupportsArray *pArray)
{
  if (pBox == nsnull) {
    if (m_pFirst != nsnull) {
      pBox = m_pFirst;

      IMPORT_LOG0( "Assigning start of mailbox list to m_pFirst\n");
    }
    else {
      if (m_entryArray.Count() > 0) {
        pBox = (MailboxEntry *) m_entryArray.ElementAt( 0);

        IMPORT_LOG0( "Assigning start of mailbox list to entry at index 0\n");
      }
    }

    if (pBox == nsnull) {
      IMPORT_LOG0( "ERROR ASSIGNING STARTING MAILBOX\n");
    }

  }

  nsresult            rv;
  nsCOMPtr <nsILocalFile> file;
  MailboxEntry *  pChild;
  nsIImportMailboxDescriptor *  pID;
  nsISupports *          pInterface;
  PRInt64            size;

  nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
  if (NS_FAILED( rv))
    return;

  while (pBox) {
    rv = impSvc->CreateNewMailboxDescriptor( &pID);
    if (NS_SUCCEEDED( rv)) {
      pID->SetDepth( depth);
      pID->SetIdentifier( pBox->index);
      pID->SetDisplayName( (PRUnichar *)pBox->mailName.get());
      if (!pBox->fileName.IsEmpty()) {
        pID->GetFile( getter_AddRefs(file));
                                nsCOMPtr <nsILocalFile> localRoot = do_QueryInterface(root);
        file->InitWithFile(localRoot);
        file->AppendNative( pBox->fileName);
        size = 0;
        file->GetFileSize( &size);
        pID->SetSize( size);
      }
      rv = pID->QueryInterface( kISupportsIID, (void **) &pInterface);
      pArray->AppendElement( pInterface);
      pInterface->Release();
      pID->Release();
    }

    if (pBox->child) {
      pChild = GetIndexEntry( pBox->child);
      if (pChild != nsnull)
        BuildMailboxList( pChild, root, depth + 1, pArray);
    }
    if (pBox->sibling != -1) {
      pBox = GetIndexEntry( pBox->sibling);
    }
    else
      pBox = nsnull;
  }

}
コード例 #9
0
PRBool nsOEScanBoxes::Find50MailBoxes( nsIFile* descFile)
{
  Reset();

  nsresult  rv;
  PRBool    isFile = PR_FALSE;

  rv = descFile->IsFile( &isFile);
  if (NS_FAILED( rv) || !isFile)
    return( PR_FALSE);

        nsCOMPtr <nsIInputStream> descInputStream;

        rv = NS_NewLocalFileInputStream(getter_AddRefs(descInputStream), descFile);
  if (NS_FAILED( rv))
    return( PR_FALSE);

  IMPORT_LOG0( "Reading the folders.dbx file\n");

  PRUint32 *    pIndex;
  PRUint32    indexSize = 0;
  if (!nsOE5File::ReadIndex( descInputStream, &pIndex, &indexSize)) {
    IMPORT_LOG0( "*** NOT USING FOLDERS.DBX!!!\n");
    return( PR_FALSE);
  }

  PRUint32  marker;
  PRUint32  size;
  char  *  pBytes;
  PRUint32    cntRead;
  PRInt32    recordId;
  PRInt32    strOffset;

  PRUint8    tag;
  PRUint32  data;
  PRInt32    dataOffset;

  PRUint32    id;
  PRUint32    parent;
  PRUint32    numMessages;
  char *      pFileName;
  char *      pDataSource;

  MailboxEntry *  pEntry;
  MailboxEntry *  pLastEntry = nsnull;

  PRUint32  localStoreId = 0;

  for (PRUint32 i = 0; i < indexSize; i++) {
    if (!ReadLong( descInputStream, marker, pIndex[i])) continue;
    if (marker != pIndex[i]) continue;
    if (!ReadLong( descInputStream, size, pIndex[i] + 4)) continue;
    size += 4;
    pBytes = new char[size];
    rv = descInputStream->Read( pBytes, size, &cntRead);
    if (NS_FAILED( rv) || ((PRUint32)cntRead != size)) {
      delete [] pBytes;
      continue;
    }
    recordId = pBytes[2];
    strOffset = (recordId * 4) + 4;
    if (recordId == 4)
      strOffset += 4;

    id = 0;
    parent = 0;
    numMessages = 0;
    pFileName = nsnull;
    pDataSource = nsnull;
    dataOffset = 4;
    while (dataOffset < strOffset) {
      tag = (PRUint8) pBytes[dataOffset];

      data = 0; // make sure all bytes are 0 before copying 3 bytes over.
      memcpy( &data, &(pBytes[dataOffset + 1]), 3);
      switch( tag) {
        case 0x80: // id record
          id = data;
        break;
        case 0x81:  // parent id
          parent = data;
        break;
        case 0x87:  // number of messages in this mailbox
          numMessages = data;
        break;
        case 0x03:  // file name for this mailbox
          if (((PRUint32)strOffset + data) < size)
            pFileName = (char *)(pBytes + strOffset + data);
        break;
        case 0x05:  // data source for this record (this is not a mailbox!)
          if (((PRUint32)strOffset + data) < size)
            pDataSource = (char *) (pBytes + strOffset + data);
        break;
      }
      dataOffset += 4;
    }

    // now build an entry if necessary!
    if (pDataSource) {
      if (!PL_strcasecmp( pDataSource, "LocalStore"))
      {
        localStoreId = id;
        // See if we have any child folders that need to be added/processed for this top level parent.
        ProcessPendingChildEntries(localStoreId, localStoreId, m_pendingChildArray);
        // Clean up the pending list.
        RemoveProcessedChildEntries();
      }
    }
    else if (id && localStoreId && parent) {
      // veryify that this mailbox is in the local store
      data = parent;
      while (data && (data != localStoreId)) {
        pEntry = GetIndexEntry( data);
        if (pEntry)
          data = pEntry->parent;
        else
          data = 0;
      }
      if (data == localStoreId) {
        // Create an entry for this bugger
        pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
        if (pEntry)
        {
          AddChildEntry( pEntry, localStoreId);
          pEntry->processed =  PR_TRUE;
          // See if we have any child folders that need to be added/processed.
          ProcessPendingChildEntries(id, localStoreId, m_pendingChildArray);
          // Clean up the pending list.
          RemoveProcessedChildEntries();
        }
      }
      else
      {
        // Put this folder into child array and process it when its parent shows up.
        pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
        if (pEntry)
          m_pendingChildArray.AppendElement(pEntry);
      }
    }
    else if (pFileName)
    {
      // Put this folder into child array and process it when its parent shows up.
      // For some reason, it's likely that child folders come before their parents.
      pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
      if (pEntry)
        m_pendingChildArray.AppendElement(pEntry);
    }

    delete [] pBytes;
  }


  delete [] pIndex;

  if (m_entryArray.Count())
    return( PR_TRUE);
  else
    return( PR_FALSE);
}
コード例 #10
0
PRBool nsOEScanBoxes::FindMailBoxes( nsIFile* descFile)
{
  Reset();

  nsresult  rv;
  PRBool    isFile = PR_FALSE;

  rv = descFile->IsFile( &isFile);
  if (NS_FAILED( rv) || !isFile)
    return( PR_FALSE);

        nsCOMPtr <nsIInputStream> descInputStream;

        rv = NS_NewLocalFileInputStream(getter_AddRefs(descInputStream), descFile);
  if (NS_FAILED( rv))
    return( PR_FALSE);

  IMPORT_LOG0( "Reading the folders.nch file\n");

  PRUint32    curRec;
  if (!ReadLong( descInputStream, curRec, 20)) {
    return( PR_FALSE);
  }

  // Now for each record
  PRBool      done = PR_FALSE;
  PRUint32    equal;
  PRUint32    size;
  PRUint32    previous;
  PRUint32    next;
  MailboxEntry *  pEntry;
  PRBool      failed;
  nsCString    ext;
  nsCString    mbxExt( ".mbx");

  while (!done) {

    if (!ReadLong( descInputStream, equal, curRec)) return( PR_FALSE);
    if (curRec != equal) {
      IMPORT_LOG1( "Record start invalid: %ld\n", curRec);
      break;
    }
    if (!ReadLong( descInputStream, size, curRec + 4)) return( PR_FALSE);
    if (!ReadLong( descInputStream, previous, curRec + 8)) return( PR_FALSE);
    if (!ReadLong( descInputStream, next, curRec + 12)) return( PR_FALSE);
    failed = PR_FALSE;
    pEntry = new MailboxEntry;
    if (!ReadLong( descInputStream, pEntry->index, curRec + 16)) failed = PR_TRUE;
    if (!ReadString( descInputStream, pEntry->mailName, curRec + 20)) failed = PR_TRUE;
    if (!ReadString( descInputStream, pEntry->fileName, curRec + 279)) failed = PR_TRUE;
    if (!ReadLong( descInputStream, pEntry->parent, curRec + 539)) failed = PR_TRUE;
    if (!ReadLong( descInputStream, pEntry->child, curRec + 543)) failed = PR_TRUE;
    if (!ReadLong( descInputStream, pEntry->sibling, curRec + 547)) failed = PR_TRUE;
    if (!ReadLong( descInputStream, pEntry->type, curRec + 551)) failed = PR_TRUE;
    if (failed) {
      delete pEntry;
      return( PR_FALSE);
    }

    #ifdef _TRACE_MAILBOX_ENTRIES
    IMPORT_LOG0( "------------\n");
    IMPORT_LOG2( "    Offset: %lx, index: %ld\n", curRec, pEntry->index);
    IMPORT_LOG2( "      previous: %lx, next: %lx\n", previous, next);
    IMPORT_LOG2( "      Name: %S, File: %s\n", (PRUnichar *) pEntry->mailName, (const char *) pEntry->fileName);
    IMPORT_LOG3( "      Parent: %ld, Child: %ld, Sibling: %ld\n", pEntry->parent, pEntry->child, pEntry->sibling);
    #endif

    pEntry->fileName.Right( ext, 4);
    if (!ext.Equals(mbxExt))
      pEntry->fileName.Append( ".mbx");

    m_entryArray.AppendElement( pEntry);

    curRec = next;
    if (!next)
      done = PR_TRUE;
  }

  MailboxEntry *pZero = GetIndexEntry( 0);
  if (pZero)
    m_pFirst = GetIndexEntry( pZero->child);

  IMPORT_LOG1( "Read the folders.nch file, found %ld mailboxes\n", (long) m_entryArray.Count());

  return( PR_TRUE);
}
コード例 #11
0
TC_Error_Code TCDS_Binary_Harmonic::LoadData(const wxString &data_file_path)
{
    if(!open_tide_db (data_file_path.mb_str())) return TC_TCD_FILE_CORRUPT;

    //Build the tables of constituent data

    DB_HEADER_PUBLIC hdr = get_tide_db_header ();

    source_ident = wxString( hdr.version, wxConvUTF8 );

    num_csts = hdr.constituents;
    if(0 == num_csts)
        return TC_GENERIC_ERROR;

    num_nodes = hdr.number_of_years;
    if(0 == num_nodes)
        return TC_GENERIC_ERROR;
    
    //  Allocate a working buffer
    m_work_buffer = (double *) malloc (num_csts * sizeof (double));

    //  Constituent speeds
    m_cst_speeds = (double *) malloc (num_csts * sizeof (double));

    for (int a=0; a<num_csts; a++) {
        m_cst_speeds[a] = get_speed (a);
        m_cst_speeds[a] *= M_PI / 648000; /* Convert to radians per second */
    }

    //  Equilibrium tables by year
    m_first_year = hdr.start_year;
    num_epochs = hdr.number_of_years;

    m_cst_epochs = (double **) malloc (num_csts * sizeof (double *));
    for (int i=0; i<num_csts; i++)
        m_cst_epochs[i] = (double *) malloc (num_epochs * sizeof (double));

    for (int i=0; i<num_csts; i++)
    {
        for (int year=0; year<num_epochs; year++)
        {
            m_cst_epochs[i][year] = get_equilibrium (i, year);
            m_cst_epochs[i][year] *= M_PI / 180.0;
        }
    }

    //  Node factors

    m_cst_nodes = (double **) malloc (num_csts * sizeof (double *));
    for (int a=0; a<num_csts; a++)
        m_cst_nodes[a] = (double *) malloc (num_nodes * sizeof (double));

    for (int a=0; a<num_csts; a++) {
        for (int year=0; year<num_nodes; year++)
            m_cst_nodes[a][year] = get_node_factor (a, year);
    }


    // now load and create the index

    TIDE_RECORD *ptiderec = (TIDE_RECORD *)calloc(sizeof(TIDE_RECORD), 1);
    for(unsigned int i=0 ; i < hdr.number_of_records ; i++) {
        read_tide_record (i, ptiderec);

        num_IDX++; // Keep counting entries for harmonic file stuff
        IDX_entry *pIDX = new IDX_entry;
        pIDX->source_data_type = SOURCE_TYPE_BINARY_HARMONIC;
        pIDX->pDataSource = NULL;

        pIDX->Valid15 = 0;

        pIDX->pref_sta_data = NULL;                     // no reference data yet
        pIDX->IDX_Useable = 1;                          // but assume data is OK
        pIDX->IDX_tzname = NULL;

        pIDX->IDX_lon = ptiderec->header.longitude;
        pIDX->IDX_lat = ptiderec->header.latitude;

        const char *tz = get_tzfile (ptiderec->header.tzfile);
        change_time_zone ((char *)tz);
        if(tz_info)
            pIDX->IDX_time_zone = -tz_info->tzi.Bias;


        strncpy(pIDX->IDX_station_name, ptiderec->header.name, MAXNAMELEN);
//        if(strstr(ptiderec->header.name, "Beaufort") != NULL)
//            int yyp = 4;

        pIDX->IDX_flood_dir = ptiderec->max_direction;
        pIDX->IDX_ebb_dir = ptiderec->min_direction;

        if(REFERENCE_STATION == ptiderec->header.record_type) {
            //    Establish Station Type
            wxString caplin(pIDX->IDX_station_name, wxConvUTF8);
            caplin.MakeUpper();
            if(caplin.Contains(_T("CURRENT")))
                pIDX->IDX_type = 'C';
            else
                pIDX->IDX_type = 'T';

            int t1 = ptiderec->zone_offset;
            double zone_offset = (double)(t1 / 100) + ((double)(t1 % 100))/60.;
//            pIDX->IDX_time_zone = t1a;

            pIDX->IDX_ht_time_off = pIDX->IDX_lt_time_off = 0;
            pIDX->IDX_ht_mpy      = pIDX->IDX_lt_mpy = 1.0;
            pIDX->IDX_ht_off      = pIDX->IDX_lt_off = 0.0;
            pIDX->IDX_ref_dbIndex = ptiderec->header.reference_station;         // will be -1

            //  build a Station_Data class, and add to member array

            Station_Data *psd = new Station_Data;

            psd->amplitude = (double *)malloc(num_csts * sizeof(double));
            psd->epoch     = (double *)malloc(num_csts * sizeof(double));
            psd->station_name = (char *)malloc(ONELINER_LENGTH);

            strncpy(psd->station_name, ptiderec->header.name, MAXNAMELEN);
            psd->station_type = pIDX->IDX_type;


            // Get meridian, which is seconds difference from UTC, not figuring DST, so that New York is always (-300 * 60)
            psd->meridian =  -(tz_info->tzi.Bias * 60);
            psd->zone_offset = zone_offset;

            // Get units
            strncpy (psd->unit, get_level_units (ptiderec->level_units), 40 - 1);
            psd->unit[40 -1] = '\0';

            psd->have_BOGUS = (findunit(psd->unit) != -1) && (known_units[findunit(psd->unit)].type == BOGUS);

            int unit_c;
            if (psd->have_BOGUS)
                unit_c = findunit("knots");
            else
                unit_c = findunit(psd->unit);

            if(unit_c != -1) {
                strncpy (psd->units_conv, known_units[unit_c].name, sizeof(psd->units_conv)-1);
                strncpy (psd->units_abbrv, known_units[unit_c].abbrv, sizeof(psd->units_abbrv)-1);
            }
            else {
                strncpy (psd->units_conv, psd->unit, 40 - 1);
                psd->units_conv[40 - 1] = '\0';
                strncpy (psd->units_abbrv, psd->unit, 20 - 1);
                psd->units_abbrv[20 - 1] = '\0';
            }


            // Get constituents
            for (int a=0; a<num_csts; a++)
            {
                psd->amplitude[a] = ptiderec->amplitude[a];
                psd->epoch[a] = ptiderec->epoch[a] * M_PI / 180.;
            }

            psd->DATUM = ptiderec->datum_offset;

            m_msd_array.Add(psd);                     // add it to the member array
            pIDX->pref_sta_data = psd;
            pIDX->IDX_ref_dbIndex = i;
            pIDX->have_offsets = 0;
        }
        else if(SUBORDINATE_STATION == ptiderec->header.record_type) {
            //    Establish Station Type
            wxString caplin(pIDX->IDX_station_name, wxConvUTF8);
            caplin.MakeUpper();
            if(caplin.Contains(_T("CURRENT")))
                pIDX->IDX_type = 'c';
            else
                pIDX->IDX_type = 't';

            int t1 = ptiderec->max_time_add;
            double t1a = (double)(t1 / 100) + ((double)(t1 % 100))/60.;
            t1a *= 60;                  // Minutes
            pIDX->IDX_ht_time_off = t1a;
            pIDX->IDX_ht_mpy = ptiderec->max_level_multiply;
            if(0. == pIDX->IDX_ht_mpy) pIDX->IDX_ht_mpy = 1.0;
            pIDX->IDX_ht_off = ptiderec->max_level_add;


            t1 = ptiderec->min_time_add;
            t1a = (double)(t1 / 100) + ((double)(t1 % 100))/60.;
            t1a *= 60;                  // Minutes
            pIDX->IDX_lt_time_off = t1a;
            pIDX->IDX_lt_mpy = ptiderec->min_level_multiply;
            if(0. == pIDX->IDX_lt_mpy) pIDX->IDX_lt_mpy = 1.0;
            pIDX->IDX_lt_off = ptiderec->min_level_add;

            pIDX->IDX_ref_dbIndex = ptiderec->header.reference_station;
//           strncpy(pIDX->IDX_reference_name, ptiderec->header.name, MAXNAMELEN);

            if( pIDX->IDX_ht_time_off ||
                    pIDX->IDX_ht_off != 0.0 ||
                    pIDX->IDX_lt_off != 0.0 ||
                    pIDX->IDX_ht_mpy != 1.0 ||
                    pIDX->IDX_lt_mpy != 1.0)
                pIDX->have_offsets = 1;
        }

        m_IDX_array.Add(pIDX);
    }



    //  Mark the index entries individually with invariant harmonic constants
    unsigned int max_index = GetMaxIndex();
    for(unsigned int i=0 ; i < max_index ; i++) {
        IDX_entry *pIDX = GetIndexEntry( i );
        if(pIDX) {
            pIDX->num_nodes = num_nodes;
            pIDX->num_csts = num_csts;
            pIDX->num_epochs = num_epochs;
            pIDX->m_cst_speeds = m_cst_speeds;
            pIDX->m_cst_nodes = m_cst_nodes;
            pIDX->m_cst_epochs = m_cst_epochs;
            pIDX->first_year = m_first_year;
            pIDX->m_work_buffer = m_work_buffer;
        }
    }
    free( ptiderec );

    return TC_NO_ERROR;
}