30#include <wx/datetime.h> 
   31#include <wx/hashmap.h> 
   40#include "model/georef.h" 
   49time_t s_next_epoch = TIDE_BAD_TIME; 
 
   50time_t s_this_epoch = TIDE_BAD_TIME; 
 
   53double time2dt_tide(time_t t, 
int deriv, 
IDX_entry *pIDX);
 
   54int yearoftimet(time_t t);
 
   55void happy_new_year(
IDX_entry *pIDX, 
int new_year);
 
   58double time2tide(time_t t, 
IDX_entry *pIDX) { 
return time2dt_tide(t, 0, pIDX); }
 
   64double BOGUS_amplitude(
double mpy, 
IDX_entry *pIDX) {
 
   67  if (!pmsd->have_BOGUS)  
 
   78double time2atide(time_t t, 
IDX_entry *pIDX) {
 
   79  return BOGUS_amplitude(time2tide(t, pIDX), pIDX) + pIDX->
pref_sta_data->DATUM;
 
   90int next_big_event(time_t *tm, 
IDX_entry *pIDX) {
 
   92  int flags = 0, slope = 0;
 
   93  p = time2atide(*tm, pIDX);
 
   95  q = time2atide(*tm, pIDX);
 
   99    if ((slope == 1 && q < p) || (slope == 0 && p < q)) {
 
  101      flags |= (1 << slope);
 
  115      if ((p > marklev && q <= marklev) || (p < marklev && q >= marklev)) {
 
  131          q = time2atide(*tm, pIDX);
 
  132          if ((slope == 1 && q < p) || (slope == 0 && p < q)) {
 
  134            flags |= (1 << slope);
 
  146      if (flags < 4) *tm -= 60;
 
  150    q = time2atide(*tm, pIDX);
 
  159double time2mean(time_t t, 
IDX_entry *pIDX) {
 
  162  int new_year = yearoftimet(t);
 
  163  if (pIDX->
epoch_year != new_year) happy_new_year(pIDX, new_year);
 
  165  for (a = 0; a < pIDX->
num_csts; a++) {
 
  182double time2asecondary(time_t t, 
IDX_entry *pIDX) {
 
  186  if (!(pIDX->
have_offsets)) 
return time2atide(tadj, pIDX);
 
  193#define intervalwidth 15 
  194#define stretchfactor 3 
  196    static time_t lowtime = 0, hightime = 0;
 
  197    static double lowlvl, highlvl; 
 
  199    double S, Z, HI, HS, magicnum;
 
  200    time_t interval = 3600 * intervalwidth;
 
  201    long difflow, diffhigh;
 
  202    int badlowflag = 0, badhighflag = 0;
 
  217    Z = time2mean(T, pIDX);
 
  218    S = time2tide(T, pIDX) - Z;
 
  240      difflow = T - lowtime;
 
  242      difflow = lowtime - T;
 
  244      diffhigh = T - hightime;
 
  246      diffhigh = hightime - T;
 
  249    if (difflow > interval * stretchfactor) badlowflag = 1;
 
  250    if (badlowflag || (difflow > interval && S > 0)) {
 
  254      next_big_event(&tt, pIDX);
 
  255      lowlvl = time2tide(tt, pIDX);
 
  257      while (tt < T + interval) {
 
  258        next_big_event(&tt, pIDX);
 
  259        tl = time2tide(tt, pIDX);
 
  260        if (tl < lowlvl && tt < T + interval) {
 
  267    if (diffhigh > interval * stretchfactor) badhighflag = 1;
 
  268    if (badhighflag || (diffhigh > interval && S < 0)) {
 
  272      next_big_event(&tt, pIDX);
 
  273      highlvl = time2tide(tt, pIDX);
 
  275      while (tt < T + interval) {
 
  276        next_big_event(&tt, pIDX);
 
  277        tl = time2tide(tt, pIDX);
 
  278        if (tl > highlvl && tt < T + interval) {
 
  298      magicnum = 0.5 * S / fabs(highlvl - Z);
 
  300      magicnum = 0.5 * S / fabs(lowlvl - Z);
 
  304    HI = time2tide(T, pIDX);
 
  307    double ht_off, lt_off;
 
  320      double RH = 1.0, RL = 1.0, HH = 0.0, HL = 0.0;
 
  329      HS = HI * ((RH + RL) / 2 + (RH - RL) * magicnum) + (HH + HL) / 2 +
 
  330           (HH - HL) * magicnum;
 
  384double _time2dt_tide(time_t t, 
int deriv, 
IDX_entry *pIDX) {
 
  385  double dt_tide = 0.0;
 
  389  tempd = M_PI / 2.0 * deriv;
 
  390  for (a = 0; a < pIDX->
num_csts; a++) {
 
  397    for (b = deriv; b > 0; b--) term *= pIDX->
m_cst_speeds[a];
 
  420static double blend_weight(
double x, 
int deriv) {
 
  423  if (x2 >= 1.0) 
return deriv == 0 && x > 0.0 ? 1.0 : 0.0;
 
  427      return ((3.0 * x2 - 10.0) * x2 + 15.0) * x / 16.0 + 0.5;
 
  429      return ((x2 - 2.0) * x2 + 1.0) * (15.0 / 16.0);
 
  431      return (x2 - 1.0) * x * (15.0 / 4.0);
 
  440double blend_tide(time_t t, 
unsigned int deriv, 
int first_year, 
double blend,
 
  442  double fl[TIDE_MAX_DERIV + 1];
 
  443  double fr[TIDE_MAX_DERIV + 1];
 
  445  double w[TIDE_MAX_DERIV + 1];
 
  454  int year = yearoftimet(t);
 
  455  if (year == first_year + 1)
 
  457  else if (year != first_year)
 
  458    happy_new_year(pIDX, first_year);
 
  459  for (n = 0; n <= deriv; n++) fp[n] = _time2dt_tide(t, n, pIDX);
 
  466    happy_new_year(pIDX, first_year + 1);
 
  469    happy_new_year(pIDX, first_year);
 
  472  for (n = 0; n <= deriv; n++) {
 
  473    fp[n] = _time2dt_tide(t, n, pIDX);
 
  474    w[n] = blend_weight(blend, n);
 
  482  for (n = 0; n <= deriv; n++) {
 
  483    f += fact * w[n] * (fr[deriv - n] - fl[deriv - n]);
 
  484    fact *= (double)(deriv - n) / (n + 1) * (1.0 / TIDE_BLEND_TIME);
 
  486  printf(
" %ld  %g     %g %g %g\n", (
long)t, blend, fr[0], fl[0], f);
 
  490double time2dt_tide(time_t t, 
int deriv, 
IDX_entry *pIDX) {
 
  492  int yott = yearoftimet(t);
 
  496  if (new_year != s_this_year) {
 
  498      set_epoch(pIDX, new_year + 1);
 
  499      s_next_epoch = pIDX->
epoch;
 
  501      s_next_epoch = TIDE_BAD_TIME;
 
  503    happy_new_year(pIDX, s_this_year = new_year);
 
  504    s_this_epoch = pIDX->
epoch;
 
  511  if (t - s_this_epoch <= TIDE_BLEND_TIME && s_this_year > pIDX->
first_year)
 
  512    return blend_tide(t, deriv, s_this_year - 1,
 
  513                      (
double)(t - s_this_epoch) / TIDE_BLEND_TIME, pIDX);
 
  514  else if (s_next_epoch - t <= TIDE_BLEND_TIME &&
 
  516    return blend_tide(t, deriv, s_this_year,
 
  517                      -(
double)(s_next_epoch - t) / TIDE_BLEND_TIME, pIDX);
 
  522  if (pIDX->
epoch_year != new_year) happy_new_year(pIDX, new_year);
 
  524  return _time2dt_tide(t, deriv, pIDX);
 
  529void figure_max_amplitude(
IDX_entry *pIDX) {
 
  534      double year_amp = 0.0;
 
  536      for (a = 0; a < pIDX->
num_csts; a++)
 
  544void figure_multipliers(
IDX_entry *pIDX, 
int year) {
 
  547  figure_max_amplitude(pIDX);
 
  548  for (a = 0; a < pIDX->
num_csts; a++) {
 
  556#define compare_int(a, b) (((int)(a)) - ((int)(b))) 
  557int compare_tm(
struct tm *a, 
struct tm *b) {
 
  565  temp = compare_int(a->tm_year, b->tm_year);
 
  566  if (temp) 
return temp;
 
  567  temp = compare_int(a->tm_mon, b->tm_mon);
 
  568  if (temp) 
return temp;
 
  569  temp = compare_int(a->tm_mday, b->tm_mday);
 
  570  if (temp) 
return temp;
 
  571  temp = compare_int(a->tm_hour, b->tm_hour);
 
  572  if (temp) 
return temp;
 
  573  temp = compare_int(a->tm_min, b->tm_min);
 
  574  if (temp) 
return temp;
 
  575  return compare_int(a->tm_sec, b->tm_sec);
 
  581time_t tm2gmt(
struct tm *ht) {
 
  582  time_t guess, newguess, thebit;
 
  583  int loopcounter, compare;
 
  587  loopcounter = (
sizeof(time_t) * 8) - 1;
 
  588  thebit = ((time_t)1) << (loopcounter - 1);
 
  593  if ((
signed long)thebit < (time_t)(0)) {
 
  596    thebit = ((time_t)1) << (loopcounter - 1);
 
  599  for (; loopcounter; loopcounter--) {
 
  600    newguess = guess | thebit;
 
  601    gt = gmtime(&newguess);
 
  603      compare = compare_tm(gt, ht);
 
  604      if (compare <= 0) guess = newguess;
 
  612int yearoftimet(time_t t) { 
return ((gmtime(&t))->tm_year) + 1900; }
 
  615void set_epoch(
IDX_entry *pIDX, 
int year) {
 
  618  ht.tm_year = year - 1900;
 
  619  ht.tm_sec = ht.tm_min = ht.tm_hour = ht.tm_mon = 0;
 
  621  pIDX->
epoch = tm2gmt(&ht);
 
  625void happy_new_year(
IDX_entry *pIDX, 
int new_year) {
 
  627  figure_multipliers(pIDX, new_year);
 
  628  set_epoch(pIDX, new_year);
 
  634TCMgr::~TCMgr() { PurgeData(); }
 
  636void TCMgr::PurgeData() {
 
  637  m_Combined_IDX_array.clear();
 
  640  m_source_array.Clear();
 
  643TC_Error_Code TCMgr::LoadDataSources(std::vector<std::string> &sources) {
 
  647  m_sourcefile_array.clear();
 
  648  m_sourcefile_array = sources;
 
  652  for (
auto src : sources) {
 
  654    TC_Error_Code r = s->LoadData(src);
 
  655    if (r != TC_NO_ERROR) {
 
  657      msg.Printf(_T(
"   Error loading Tide/Currect data source %s "),
 
  659      if (r == TC_FILE_NOT_FOUND)
 
  660        msg += _T(
"Error Code: TC_FILE_NOT_FOUND");
 
  663        msg1.Printf(_T(
"Error code: %d"), r);
 
  669      m_source_array.Add(s);
 
  671      for (
int k = 0; k < s->GetMaxIndex(); k++) {
 
  675        m_Combined_IDX_array.push_back(pIDX);
 
  682  if (m_Combined_IDX_array.empty())
 
  684        NULL, _(
"It seems you have no tide/current harmonic data installed."),
 
  685        _(
"OpenCPN Info"), wxOK | wxCENTER);
 
  687  ScrubCurrentDepths();
 
  691void TCMgr::ScrubCurrentDepths() {
 
  696  WX_DECLARE_STRING_HASH_MAP(
int, currentDepth_index_hash);
 
  698  currentDepth_index_hash hash1;
 
  700  for (
int i = 1; i < Get_max_IDX() + 1; i++) {
 
  715        currentDepth_index_hash::iterator it = hash1.find(key1);
 
  716        if (it == hash1.end()) {
 
  725          if (depth_a < depth_b) {
 
  737const IDX_entry *TCMgr::GetIDX_entry(
int index)
 const {
 
  738  if ((
unsigned int)index < m_Combined_IDX_array.size())
 
  739    return m_Combined_IDX_array[index];
 
  744bool TCMgr::GetTideOrCurrent(time_t t, 
int idx, 
float &tcvalue, 
float &dir) {
 
  750  IDX_entry *pIDX = m_Combined_IDX_array[idx];  
 
  765    if (pIDX->
pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR) 
return false;
 
  769  int yott = yearoftimet(t);
 
  771  happy_new_year(pIDX, yott);  
 
  775  double level = time2asecondary(t + (00 * 60), pIDX);  
 
  786extern wxDateTime gTimeSource;
 
  788bool TCMgr::GetTideOrCurrent15(time_t t_d, 
int idx, 
float &tcvalue, 
float &dir,
 
  791  IDX_entry *pIDX = m_Combined_IDX_array[idx];  
 
  800  wxDateTime this_now = gTimeSource;  
 
  801  if (this_now.IsValid() == 
false) this_now = wxDateTime::Now();
 
  802  wxDateTime this_gmt = this_now.ToGMT();
 
  803  wxTimeSpan diff = this_gmt.Subtract(this_now);
 
  804  int diff_mins = diff.GetMinutes();
 
  807  if (this_now.IsDST()) station_offset += 60;
 
  808  int corr_mins = station_offset - diff_mins;
 
  810  wxDateTime today_00 = this_now;
 
  811  today_00.ResetTime();
 
  812  int t_today_00 = today_00.GetTicks();
 
  813  int t_today_00_at_station = t_today_00 - (corr_mins * 60);
 
  816      this_gmt.GetTicks() - (station_offset * 60) + (corr_mins * 60);
 
  818  int t_mins = (t_at_station - t_today_00_at_station) / 60;
 
  819  int t_15s = t_mins / 15;
 
  823    int tref1 = t_today_00_at_station + t_15s * 15 * 60;
 
  830      int tref = t_today_00_at_station + t_15s * 15 * 60;
 
  831      ret = GetTideOrCurrent(tref, idx, tcvalue, dir);
 
  836      pIDX->
Ret15 = !(ret == 0);
 
  844    int tref = t_today_00_at_station + t_15s * 15 * 60;
 
  845    ret = GetTideOrCurrent(tref, idx, tcvalue, dir);
 
  850    pIDX->
Ret15 = !(ret == 0);
 
  857bool TCMgr::GetTideFlowSens(time_t t, 
int sch_step, 
int idx, 
float &tcvalue_now,
 
  858                            float &tcvalue_prev, 
bool &w_t) {
 
  865  IDX_entry *pIDX = m_Combined_IDX_array[idx];  
 
  867  if (!pIDX) 
return false;
 
  872    if (pIDX->
pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR) 
return false;
 
  876  int yott = yearoftimet(t);
 
  877  happy_new_year(pIDX, yott);  
 
  881  tcvalue_now = time2asecondary(t, pIDX);
 
  882  tcvalue_prev = time2asecondary(t + sch_step, pIDX);
 
  885      tcvalue_now > tcvalue_prev;  
 
  890void TCMgr::GetHightOrLowTide(time_t t, 
int sch_step_1, 
int sch_step_2,
 
  891                              float tide_val, 
bool w_t, 
int idx, 
float &tcvalue,
 
  898  IDX_entry *pIDX = m_Combined_IDX_array[idx];  
 
  905    if (pIDX->
pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR) 
return;
 
  921  int yott = yearoftimet(t);
 
  922  happy_new_year(pIDX, yott);
 
  925  double newval = tide_val;
 
  926  double oldval = (w_t) ? newval - 1 : newval + 1;
 
  930  while ((newval > oldval) == w_t)  
 
  934    ttt = t + (sch_step_1 * j);
 
  935    newval = time2asecondary(ttt, pIDX);
 
  937  oldval = (w_t) ? newval - 1 : newval + 1;
 
  938  while ((newval > oldval) == w_t)  
 
  942    ttt = t + (sch_step_1 * j) - (sch_step_2 * k);
 
  943    newval = time2asecondary(ttt, pIDX);
 
  946  tctime = ttt + sch_step_2;
 
  965int TCMgr::GetNextBigEvent(time_t *tm, 
int idx) {
 
  970  int flags = 0, slope = 0;
 
  971  ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
 
  974  ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
 
  977  if (p < q) slope = 1;
 
  979    if ((slope == 1 && q < p) || (slope == 0 && p < q)) {
 
  981      flags |= (1 << slope);
 
  985      if (flags < 4) *tm -= 60;
 
  989    ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
 
  996std::map<double, const IDX_entry *> TCMgr::GetStationsForLL(
double xlat,
 
  998  std::map<double, const IDX_entry *> x;
 
 1001  for (
int j = 1; j < Get_max_IDX() + 1; j++) {
 
 1002    lpIDX = GetIDX_entry(j);
 
 1006    if (type == 
't' || type == 
'T') {
 
 1008      DistanceBearingMercator(xlat, xlon, lpIDX->
IDX_lat, lpIDX->
IDX_lon, &brg,
 
 1010      x.emplace(std::make_pair(dist, lpIDX));
 
 1017int TCMgr::GetStationIDXbyName(
const wxString &prefix, 
double xlat,
 
 1018                               double xlon)
 const {
 
 1022  double distx = 100000.;
 
 1024  int jmax = Get_max_IDX();
 
 1026  for (
int j = 1; j < Get_max_IDX() + 1; j++) {
 
 1027    lpIDX = GetIDX_entry(j);
 
 1031    if (((type == 
't') || (type == 
'T'))  
 
 1032        && (locnx.StartsWith(prefix))) {
 
 1034      DistanceBearingMercator(xlat, xlon, lpIDX->
IDX_lat, lpIDX->
IDX_lon, &brg,
 
 1046int TCMgr::GetStationIDXbyNameType(
const wxString &prefix, 
double xlat,
 
 1047                                   double xlon, 
char type)
 const {
 
 1051  double distx = 100000.;
 
 1055  int jmax = Get_max_IDX();
 
 1057  for (
int j = 1; j < Get_max_IDX() + 1; j++) {
 
 1058    lpIDX = GetIDX_entry(j);
 
 1062    if ((type == typep) && (locnx.StartsWith(prefix))) {
 
 1064      DistanceBearingMercator(xlat, xlon, lpIDX->
IDX_lat, lpIDX->
IDX_lon, &brg,
 
 1090#define DEFAULT_HEADER_SIZE 4096 
 1091#define DEFAULT_NUMBER_OF_RECORDS 0 
 1092#define DEFAULT_LEVEL_UNIT_TYPES 5 
 1093#define DEFAULT_DIR_UNIT_TYPES 3 
 1094#define DEFAULT_RESTRICTION_TYPES 2 
 1095#define DEFAULT_RESTRICTION_BITS 4 
 1096#define DEFAULT_TZFILES 406 
 1097#define DEFAULT_TZFILE_BITS 10 
 1098#define DEFAULT_COUNTRIES 240 
 1099#define DEFAULT_COUNTRY_BITS 9 
 1100#define DEFAULT_DATUM_TYPES 61 
 1101#define DEFAULT_DATUM_BITS 7 
 1102#define DEFAULT_LEGALESES 1 
 1103#define DEFAULT_LEGALESE_BITS 4 
 1104#define DEFAULT_SPEED_SCALE 10000000 
 1105#define DEFAULT_EQUILIBRIUM_SCALE 100 
 1106#define DEFAULT_NODE_SCALE 10000 
 1107#define DEFAULT_AMPLITUDE_BITS 19 
 1108#define DEFAULT_AMPLITUDE_SCALE 10000 
 1109#define DEFAULT_EPOCH_BITS 16 
 1110#define DEFAULT_EPOCH_SCALE 100 
 1111#define DEFAULT_RECORD_TYPE_BITS 4 
 1112#define DEFAULT_LATITUDE_BITS 25 
 1113#define DEFAULT_LATITUDE_SCALE 100000 
 1114#define DEFAULT_LONGITUDE_BITS 26 
 1115#define DEFAULT_LONGITUDE_SCALE 100000 
 1116#define DEFAULT_RECORD_SIZE_BITS 16 
 1117#define DEFAULT_STATION_BITS 18 
 1118#define DEFAULT_DATUM_OFFSET_BITS 28 
 1119#define DEFAULT_DATUM_OFFSET_SCALE 10000 
 1120#define DEFAULT_DATE_BITS 27 
 1121#define DEFAULT_MONTHS_ON_STATION_BITS 10 
 1122#define DEFAULT_CONFIDENCE_VALUE_BITS 4 
 1123#define DEFAULT_NUMBER_OF_CONSTITUENTS_BITS 8 
 1124#define DEFAULT_TIME_BITS 13 
 1125#define DEFAULT_LEVEL_ADD_BITS 17 
 1126#define DEFAULT_LEVEL_ADD_SCALE 1000 
 1127#define DEFAULT_LEVEL_MULTIPLY_BITS 16 
 1128#define DEFAULT_LEVEL_MULTIPLY_SCALE 1000 
 1129#define DEFAULT_DIRECTION_BITS 9 
 1130#define DEFAULT_CONSTITUENT_SIZE 10 
 1131#define DEFAULT_LEVEL_UNIT_SIZE 15 
 1132#define DEFAULT_DIR_UNIT_SIZE 15 
 1133#define DEFAULT_RESTRICTION_SIZE 30 
 1134#define DEFAULT_DATUM_SIZE 70 
 1135#define DEFAULT_LEGALESE_SIZE 70 
 1136#define DEFAULT_TZFILE_SIZE 30 
 1137#define DEFAULT_COUNTRY_SIZE 50 
 1141#define INFERRED_SEMI_DIURNAL_COUNT 10 
 1142#define INFERRED_DIURNAL_COUNT 10 
 1145#pragma warning(disable : 4305)   
 1148const NV_CHAR *inferred_semi_diurnal[INFERRED_SEMI_DIURNAL_COUNT] = {
 
 1149    "N2", 
"NU2", 
"MU2", 
"2N2", 
"LDA2", 
"T2", 
"R2", 
"L2", 
"K2", 
"KJ2"};
 
 1150const NV_CHAR *inferred_diurnal[INFERRED_DIURNAL_COUNT] = {
 
 1151    "OO1", 
"M1", 
"J1", 
"RHO1", 
"Q1", 
"2Q1", 
"P1", 
"PI1", 
"PHI1", 
"PSI1"};
 
 1152NV_FLOAT32 semi_diurnal_coeff[INFERRED_SEMI_DIURNAL_COUNT] = {
 
 1153    .1759, .0341, .0219, .0235, .0066, .0248, .0035, .0251, .1151, .0064};
 
 1154NV_FLOAT32 diurnal_coeff[INFERRED_DIURNAL_COUNT] = {
 
 1155    .0163, .0209, .0297, .0142, .0730, .0097, .1755, .0103, .0076, .0042};
 
 1159NV_FLOAT32 coeff[2] = {.9085, .3771};
 
 1169NV_CHAR level_unit[DEFAULT_LEVEL_UNIT_TYPES][DEFAULT_LEVEL_UNIT_SIZE] = {
 
 1170    "Unknown", 
"feet", 
"meters", 
"knots", 
"knots^2"};
 
 1174NV_CHAR dir_unit[DEFAULT_DIR_UNIT_TYPES][DEFAULT_DIR_UNIT_SIZE] = {
 
 1175    "Unknown", 
"degrees true", 
"degrees"};
 
 1179NV_CHAR restriction[DEFAULT_RESTRICTION_TYPES][DEFAULT_RESTRICTION_SIZE] = {
 
 1180    "Public Domain", 
"DoD/DoD Contractors Only"};
 
 1184NV_CHAR legalese[DEFAULT_LEGALESES][DEFAULT_LEGALESE_SIZE] = {
"NULL"};
 
 1188NV_CHAR datum[DEFAULT_DATUM_TYPES][DEFAULT_DATUM_SIZE] = {
 
 1192    "Mean Lower Low Water",
 
 1194    "Mean Higher High Water",
 
 1195    "Mean Lower High Water",
 
 1196    "Mean Higher Low Water",
 
 1197    "Mean Low Water Springs",
 
 1198    "Mean Lower Low Water Springs",
 
 1199    "Mean Low Water Neaps",
 
 1200    "Mean High Water Neaps",
 
 1201    "Mean High Water Springs",
 
 1202    "Mean Higher High Water Springs",
 
 1203    "Indian Spring Low Water",
 
 1204    "Equatorial Spring Low Water",
 
 1205    "Lowest Normal Low Water",
 
 1207    "Lowest Possible Low Water",
 
 1208    "Lowest Astronomical Tide",
 
 1209    "International Great Lakes Datum(1955)",
 
 1210    "Lower Low Water, Large Tide",
 
 1211    "Lowest Normal Tide",
 
 1212    "Higher High Water, Large Tide",
 
 1214    "Higher High Water, Mean Tide",
 
 1215    "Lower Low Water, Mean Tide",
 
 1217    "World Geodetic System (1984)",
 
 1218    "National Geodetic Vertical Datum",
 
 1219    "Gulf Coast Low Water Datum",
 
 1220    "Approximate Level of Mean Sea Level",
 
 1221    "Approximate Level of Mean Low Water",
 
 1222    "Approximate Level of Mean Lower Low Water",
 
 1223    "Approximate Level of Mean High Water",
 
 1224    "Approximate Level of Mean Higher High Water",
 
 1225    "Approximate Level of Mean Lower High Water",
 
 1226    "Approximate Level of Mean Higher Low Water",
 
 1227    "Approximate Level of Mean Low Water Springs",
 
 1228    "Approximate Level of Mean Lower Low Water Springs",
 
 1229    "Approximate Level of Mean Low Water Neaps",
 
 1230    "Approximate Level of Mean High Water Neaps",
 
 1231    "Approximate Level of Mean High Water Springs",
 
 1232    "Approximate Level of Mean Higher High Water Springs",
 
 1233    "Approximate Level of Indian Spring Low Water",
 
 1234    "Approximate Level of Equatorial Spring Low Water",
 
 1235    "Approximate Level of Lowest Normal Low Water",
 
 1236    "Approximate Level of Lowest Low Water",
 
 1237    "Approximate Level of Lowest Possible Low Water",
 
 1238    "Approximate Level of Lowest Astronomical Tide",
 
 1239    "Approximate Level of International Great Lakes Datum (1955)",
 
 1240    "Approximate Level of Lower Low Water, Large Tide",
 
 1241    "Approximate Level of Lowest Normal Tide",
 
 1242    "Approximate Level of Higher High Water, Large Tide",
 
 1243    "Approximate Level of Mean Water Level",
 
 1244    "Approximate Level of Higher High Water, Mean Tide",
 
 1245    "Approximate Level of Lower Low Water, Mean Tide",
 
 1246    "Approximate Level of Mean Tide Level",
 
 1247    "Approximate Level of World Geodetic System (1984)",
 
 1248    "Approximate Level of National Geodetic Vertical Datum",
 
 1249    "Approximate Level of Gulf Coast Low Water Datum"};
 
 1253NV_CHAR country[DEFAULT_COUNTRIES][DEFAULT_COUNTRY_SIZE] = {
 
 1262    "Antigua & Barbuda",
 
 1280    "Bosnia & Herzegovina",
 
 1285    "British Indian Ocean Territory",
 
 1295    "Central African Rep.",
 
 1300    "Cocos (Keeling) Islands",
 
 1303    "Congo (Dem. Rep.)",
 
 1315    "Dominican Republic",
 
 1320    "Equatorial Guinea",
 
 1331    "French Southern & Antarctic Lands",
 
 1348    "Heard Island & McDonald Islands",
 
 1405    "Netherlands Antilles",
 
 1413    "Northern Mariana Islands",
 
 1436    "Sao Tome & Principe",
 
 1447    "South Georgia & the South Sandwich Islands",
 
 1453    "St Pierre & Miquelon",
 
 1457    "Svalbard & Jan Mayen",
 
 1469    "Trinidad & Tobago",
 
 1473    "Turks & Caicos Is",
 
 1477    "United Arab Emirates",
 
 1480    "US minor outlying islands",
 
 1486    "Virgin Islands (UK)",
 
 1487    "Virgin Islands (US)",
 
 1497NV_CHAR tzfile[DEFAULT_TZFILES][DEFAULT_TZFILE_SIZE] = {
 
 1501    ":Africa/Addis_Ababa",
 
 1509    ":Africa/Brazzaville",
 
 1510    ":Africa/Bujumbura",
 
 1512    ":Africa/Casablanca",
 
 1516    ":Africa/Dar_es_Salaam",
 
 1523    ":Africa/Johannesburg",
 
 1529    ":Africa/Libreville",
 
 1532    ":Africa/Lubumbashi",
 
 1538    ":Africa/Mogadishu",
 
 1543    ":Africa/Nouakchott",
 
 1544    ":Africa/Ouagadougou",
 
 1545    ":Africa/Porto-Novo",
 
 1552    ":America/Anchorage",
 
 1553    ":America/Anguilla",
 
 1555    ":America/Araguaina",
 
 1557    ":America/Asuncion",
 
 1559    ":America/Barbados",
 
 1562    ":America/Boa_Vista",
 
 1565    ":America/Buenos_Aires",
 
 1566    ":America/Cambridge_Bay",
 
 1569    ":America/Catamarca",
 
 1573    ":America/Chihuahua",
 
 1575    ":America/Costa_Rica",
 
 1578    ":America/Danmarkshavn",
 
 1580    ":America/Dawson_Creek",
 
 1583    ":America/Dominica",
 
 1584    ":America/Edmonton",
 
 1585    ":America/Eirunepe",
 
 1586    ":America/El_Salvador",
 
 1587    ":America/Ensenada",
 
 1588    ":America/Fortaleza",
 
 1589    ":America/Glace_Bay",
 
 1591    ":America/Goose_Bay",
 
 1592    ":America/Grand_Turk",
 
 1594    ":America/Guadeloupe",
 
 1595    ":America/Guatemala",
 
 1596    ":America/Guayaquil",
 
 1600    ":America/Hermosillo",
 
 1601    ":America/Indiana/Knox",
 
 1602    ":America/Indiana/Marengo",
 
 1603    ":America/Indianapolis",
 
 1604    ":America/Indiana/Vevay",
 
 1610    ":America/Kentucky/Monticello",
 
 1613    ":America/Los_Angeles",
 
 1614    ":America/Louisville",
 
 1618    ":America/Martinique",
 
 1619    ":America/Mazatlan",
 
 1621    ":America/Menominee",
 
 1623    ":America/Mexico_City",
 
 1624    ":America/Miquelon",
 
 1625    ":America/Monterrey",
 
 1626    ":America/Montevideo",
 
 1627    ":America/Montreal",
 
 1628    ":America/Montserrat",
 
 1630    ":America/New_York",
 
 1634    ":America/North_Dakota/Center",
 
 1636    ":America/Pangnirtung",
 
 1637    ":America/Paramaribo",
 
 1639    ":America/Port-au-Prince",
 
 1640    ":America/Port_of_Spain",
 
 1641    ":America/Porto_Velho",
 
 1642    ":America/Puerto_Rico",
 
 1643    ":America/Rainy_River",
 
 1644    ":America/Rankin_Inlet",
 
 1647    ":America/Rio_Branco",
 
 1648    ":America/Santiago",
 
 1649    ":America/Santo_Domingo",
 
 1650    ":America/Sao_Paulo",
 
 1651    ":America/Scoresbysund",
 
 1652    ":America/Shiprock",
 
 1653    ":America/St_Johns",
 
 1654    ":America/St_Kitts",
 
 1655    ":America/St_Lucia",
 
 1656    ":America/St_Thomas",
 
 1657    ":America/St_Vincent",
 
 1658    ":America/Swift_Current",
 
 1659    ":America/Tegucigalpa",
 
 1661    ":America/Thunder_Bay",
 
 1664    ":America/Vancouver",
 
 1665    ":America/Whitehorse",
 
 1666    ":America/Winnipeg",
 
 1668    ":America/Yellowknife",
 
 1669    ":Antarctica/Casey",
 
 1670    ":Antarctica/Davis",
 
 1671    ":Antarctica/DumontDUrville",
 
 1672    ":Antarctica/Mawson",
 
 1673    ":Antarctica/McMurdo",
 
 1674    ":Antarctica/Palmer",
 
 1675    ":Antarctica/South_Pole",
 
 1676    ":Antarctica/Syowa",
 
 1677    ":Antarctica/Vostok",
 
 1678    ":Arctic/Longyearbyen",
 
 1715    ":Asia/Krasnoyarsk",
 
 1716    ":Asia/Kuala_Lumpur",
 
 1725    ":Asia/Novosibirsk",
 
 1747    ":Asia/Ulaanbaatar",
 
 1750    ":Asia/Vladivostok",
 
 1752    ":Asia/Yekaterinburg",
 
 1755    ":Atlantic/Bermuda",
 
 1757    ":Atlantic/Cape_Verde",
 
 1759    ":Atlantic/Jan_Mayen",
 
 1760    ":Atlantic/Madeira",
 
 1761    ":Atlantic/Reykjavik",
 
 1762    ":Atlantic/South_Georgia",
 
 1763    ":Atlantic/Stanley",
 
 1764    ":Atlantic/St_Helena",
 
 1765    ":Australia/Adelaide",
 
 1766    ":Australia/Brisbane",
 
 1767    ":Australia/Broken_Hill",
 
 1768    ":Australia/Darwin",
 
 1769    ":Australia/Hobart",
 
 1770    ":Australia/Lindeman",
 
 1771    ":Australia/Lord_Howe",
 
 1772    ":Australia/Melbourne",
 
 1774    ":Australia/Sydney",
 
 1804    ":Europe/Amsterdam",
 
 1810    ":Europe/Bratislava",
 
 1812    ":Europe/Bucharest",
 
 1815    ":Europe/Copenhagen",
 
 1817    ":Europe/Gibraltar",
 
 1820    ":Europe/Kaliningrad",
 
 1823    ":Europe/Ljubljana",
 
 1825    ":Europe/Luxembourg",
 
 1837    ":Europe/San_Marino",
 
 1839    ":Europe/Simferopol",
 
 1842    ":Europe/Stockholm",
 
 1852    ":Europe/Zaporozhye",
 
 1854    ":Indian/Antananarivo",
 
 1856    ":Indian/Christmas",
 
 1859    ":Indian/Kerguelen",
 
 1862    ":Indian/Mauritius",
 
 1866    ":Pacific/Auckland",
 
 1870    ":Pacific/Enderbury",
 
 1873    ":Pacific/Funafuti",
 
 1874    ":Pacific/Galapagos",
 
 1876    ":Pacific/Guadalcanal",
 
 1878    ":Pacific/Honolulu",
 
 1879    ":Pacific/Johnston",
 
 1880    ":Pacific/Kiritimati",
 
 1882    ":Pacific/Kwajalein",
 
 1884    ":Pacific/Marquesas",
 
 1890    ":Pacific/Pago_Pago",
 
 1892    ":Pacific/Pitcairn",
 
 1894    ":Pacific/Port_Moresby",
 
 1895    ":Pacific/Rarotonga",
 
 1899    ":Pacific/Tongatapu",
 
 1914#define require(expr)           \ 
 1917    require_expr = (int)(expr); \ 
 1918    assert(require_expr);       \ 
 2238NV_U_INT32 calculate_bits(NV_U_INT32 value);
 
 2239void bit_pack(NV_U_BYTE *, NV_U_INT32, NV_U_INT32, NV_INT32);
 
 2240NV_U_INT32 bit_unpack(NV_U_BYTE *, NV_U_INT32, NV_U_INT32);
 
 2241NV_INT32 signed_bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
 
 2242                           NV_U_INT32 numbits);
 
 2248  NV_U_INT32 record_size;
 
 2250  NV_INT32 reference_station;
 
 2253  NV_U_BYTE record_type;
 
 
 2257static FILE *fp = NULL;
 
 2259static NV_BOOL modified = NVFalse;
 
 2260static NV_INT32 current_record, current_index;
 
 2261static NV_CHAR filename[MONOLOGUE_LENGTH];
 
 2271static void chk_fread(
void *ptr, 
size_t size, 
size_t nmemb, FILE *stream) {
 
 2273  ret = fread(ptr, size, nmemb, stream);
 
 2281static void chk_fwrite(
const void *ptr, 
size_t size, 
size_t nmemb,
 
 2284  ret = fwrite(ptr, size, nmemb, stream);
 
 2316  LOG_ERROR(
"\n\nRecord number = %d\n", rec->header.record_number);
 
 2317  LOG_ERROR(
"Record size = %u\n", rec->header.record_size);
 
 2318  LOG_ERROR(
"Record type = %u\n", rec->header.record_type);
 
 2319  LOG_ERROR(
"Latitude = %f\n", rec->header.latitude);
 
 2320  LOG_ERROR(
"Longitude = %f\n", rec->header.longitude);
 
 2321  LOG_ERROR(
"Reference station = %d\n", rec->header.reference_station);
 
 2322  LOG_ERROR(
"Tzfile = %s\n", get_tzfile(rec->header.tzfile));
 
 2323  LOG_ERROR(
"Name = %s\n", rec->header.name);
 
 2325  LOG_ERROR(
"Country = %s\n", get_country(rec->country));
 
 2326  LOG_ERROR(
"Source = %s\n", rec->source);
 
 2327  LOG_ERROR(
"Restriction = %s\n", get_restriction(rec->restriction));
 
 2328  LOG_ERROR(
"Comments = %s\n", rec->comments);
 
 2329  LOG_ERROR(
"Notes = %s\n", rec->notes);
 
 2330  LOG_ERROR(
"Legalese = %s\n", get_legalese(rec->legalese));
 
 2331  LOG_ERROR(
"Station ID context = %s\n", rec->station_id_context);
 
 2332  LOG_ERROR(
"Station ID = %s\n", rec->station_id);
 
 2333  LOG_ERROR(
"Date imported = %d\n", rec->date_imported);
 
 2334  LOG_ERROR(
"Xfields = %s\n", rec->xfields);
 
 2336  LOG_ERROR(
"Direction units = %s\n", get_dir_units(rec->direction_units));
 
 2337  LOG_ERROR(
"Min direction = %d\n", rec->min_direction);
 
 2338  LOG_ERROR(
"Max direction = %d\n", rec->max_direction);
 
 2339  LOG_ERROR(
"Level units = %s\n", get_level_units(rec->level_units));
 
 2341  if (rec->header.record_type == REFERENCE_STATION) {
 
 2342    LOG_ERROR(
"Datum offset = %f\n", rec->datum_offset);
 
 2343    LOG_ERROR(
"Datum = %s\n", get_datum(rec->datum));
 
 2344    LOG_ERROR(
"Zone offset = %d\n", rec->zone_offset);
 
 2345    LOG_ERROR(
"Expiration date = %d\n", rec->expiration_date);
 
 2346    LOG_ERROR(
"Months on station = %d\n", rec->months_on_station);
 
 2347    LOG_ERROR(
"Last date on station = %d\n", rec->last_date_on_station);
 
 2348    LOG_ERROR(
"Confidence = %d\n", rec->confidence);
 
 2349    for (i = 0; i < hd.pub.constituents; ++i) {
 
 2350      if (rec->amplitude[i] != 0.0 || rec->epoch[i] != 0.0) {
 
 2351        LOG_ERROR(
"Amplitude[%d] = %f\n", i, rec->amplitude[i]);
 
 2352        LOG_ERROR(
"Epoch[%d] = %f\n", i, rec->epoch[i]);
 
 2357  else if (rec->header.record_type == SUBORDINATE_STATION) {
 
 2358    LOG_ERROR(
"Min time add = %d\n", rec->min_time_add);
 
 2359    LOG_ERROR(
"Min level add = %f\n", rec->min_level_add);
 
 2360    LOG_ERROR(
"Min level multiply = %f\n", rec->min_level_multiply);
 
 2361    LOG_ERROR(
"Max time add = %d\n", rec->max_time_add);
 
 2362    LOG_ERROR(
"Max level add = %f\n", rec->max_level_add);
 
 2363    LOG_ERROR(
"Max level multiply = %f\n", rec->max_level_multiply);
 
 2364    LOG_ERROR(
"Flood begins = %d\n", rec->flood_begins);
 
 2365    LOG_ERROR(
"Ebb begins = %d\n", rec->ebb_begins);
 
 2378static void write_protect() {
 
 2379  if (hd.pub.major_rev < LIBTCD_MAJOR_REV) {
 
 2381        "libtcd error: can't modify TCD files created by earlier version.  " 
 2382        "Use\nrewrite_tide_db to upgrade the TCD file.\n");
 
 2406const NV_CHAR *get_country(NV_INT32 num) {
 
 2409        "libtcd error: attempt to access database when database not open\n");
 
 2412  if (num >= 0 && num < (NV_INT32)hd.pub.countries) 
return (hd.country[num]);
 
 2433const NV_CHAR *get_tzfile(NV_INT32 num) {
 
 2436        "libtcd error: attempt to access database when database not open\n");
 
 2439  if (num >= 0 && num < (NV_INT32)hd.pub.tzfiles) 
return (hd.tzfile[num]);
 
 2460const NV_CHAR *get_station(NV_INT32 num) {
 
 2463        "libtcd error: attempt to access database when database not open\n");
 
 2466  if (num >= 0 && num < (NV_INT32)hd.pub.number_of_records)
 
 2467    return (tindex[num].name);
 
 2489const NV_CHAR *get_constituent(NV_INT32 num) {
 
 2492        "libtcd error: attempt to access database when database not open\n");
 
 2495  if (num >= 0 && num < (NV_INT32)hd.pub.constituents)
 
 2496    return (hd.constituent[num]);
 
 2518const NV_CHAR *get_level_units(NV_INT32 num) {
 
 2521        "libtcd error: attempt to access database when database not open\n");
 
 2524  if (num >= 0 && num < (NV_INT32)hd.pub.level_unit_types)
 
 2525    return (hd.level_unit[num]);
 
 2547const NV_CHAR *get_dir_units(NV_INT32 num) {
 
 2550        "libtcd error: attempt to access database when database not open\n");
 
 2553  if (num >= 0 && num < (NV_INT32)hd.pub.dir_unit_types)
 
 2554    return (hd.dir_unit[num]);
 
 2576const NV_CHAR *get_restriction(NV_INT32 num) {
 
 2579        "libtcd error: attempt to access database when database not open\n");
 
 2582  if (num >= 0 && num < (NV_INT32)hd.pub.restriction_types)
 
 2583    return (hd.restriction[num]);
 
 2606NV_CHAR *get_pedigree(NV_INT32 num) { 
return "Unknown"; }
 
 2626const NV_CHAR *get_datum(NV_INT32 num) {
 
 2629        "libtcd error: attempt to access database when database not open\n");
 
 2632  if (num >= 0 && num < (NV_INT32)hd.pub.datum_types) 
return (hd.datum[num]);
 
 2639const NV_CHAR *get_legalese(NV_INT32 num) {
 
 2642        "libtcd error: attempt to access database when database not open\n");
 
 2645  if (num >= 0 && num < (NV_INT32)hd.pub.legaleses) 
return (hd.legalese[num]);
 
 2667NV_FLOAT64 get_speed(NV_INT32 num) {
 
 2670        "libtcd error: attempt to access database when database not open\n");
 
 2673  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
 
 2674  return hd.speed[num];
 
 2696NV_FLOAT32 get_equilibrium(NV_INT32 num, NV_INT32 year) {
 
 2699        "libtcd error: attempt to access database when database not open\n");
 
 2702  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
 
 2703         year < (NV_INT32)hd.pub.number_of_years);
 
 2704  return hd.equilibrium[num][year];
 
 2710NV_FLOAT32 *get_equilibriums(NV_INT32 num) {
 
 2713        "libtcd error: attempt to access database when database not open\n");
 
 2716  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
 
 2717  return hd.equilibrium[num];
 
 2739NV_FLOAT32 get_node_factor(NV_INT32 num, NV_INT32 year) {
 
 2742        "libtcd error: attempt to access database when database not open\n");
 
 2745  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
 
 2746         year < (NV_INT32)hd.pub.number_of_years);
 
 2747  return hd.node_factor[num][year];
 
 2753NV_FLOAT32 *get_node_factors(NV_INT32 num) {
 
 2756        "libtcd error: attempt to access database when database not open\n");
 
 2759  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
 
 2760  return hd.node_factor[num];
 
 2789        "libtcd error: attempt to access database when database not open\n");
 
 2793  if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records) 
return (NVFalse);
 
 2797  rec->record_number = num;
 
 2798  rec->record_size = tindex[num].record_size;
 
 2799  rec->record_type = tindex[num].record_type;
 
 2800  rec->latitude = (NV_FLOAT64)tindex[num].lat / hd.latitude_scale;
 
 2801  rec->longitude = (NV_FLOAT64)tindex[num].lon / hd.longitude_scale;
 
 2802  rec->reference_station = tindex[num].reference_station;
 
 2803  rec->tzfile = tindex[num].tzfile;
 
 2804  strcpy(rec->name, tindex[num].name);
 
 2806  current_index = num;
 
 2830  if (!get_partial_tide_record(current_index + 1, rec)) 
return (-1);
 
 2832  return (current_index);
 
 2855NV_INT32 get_nearest_partial_tide_record(NV_FLOAT64 lat, NV_FLOAT64 lon,
 
 2857  NV_FLOAT64 diff, min_diff, lt, ln;
 
 2858  NV_U_INT32 i, shortest = 0;
 
 2860  min_diff = 999999999.9;
 
 2861  for (i = 0; i < hd.pub.number_of_records; ++i) {
 
 2862    lt = (NV_FLOAT64)tindex[i].lat / hd.latitude_scale;
 
 2863    ln = (NV_FLOAT64)tindex[i].lon / hd.longitude_scale;
 
 2865    diff = sqrt((lat - lt) * (lat - lt) + (lon - ln) * (lon - ln));
 
 2867    if (diff < min_diff) {
 
 2873  if (!get_partial_tide_record(shortest, rec)) 
return (-1);
 
 2895NV_INT32 get_time(
const NV_CHAR *
string) {
 
 2896  NV_INT32 hour, minute, hhmm;
 
 2899  sscanf(
string, 
"%d:%d", &hour, &minute);
 
 2903  if (
string[0] == 
'-') {
 
 2904    if (hour < 0) hour = -hour;
 
 2906    hhmm = -(hour * 100 + minute);
 
 2908    hhmm = hour * 100 + minute;
 
 2932NV_CHAR *ret_time(NV_INT32 time) {
 
 2933  NV_INT32 hour, minute;
 
 2934  static NV_CHAR tname[16];
 
 2936  hour = abs(time) / 100;
 
 2937  assert(hour <= 99999 && hour >= -99999); 
 
 2938  minute = abs(time) % 100;
 
 2941    sprintf(tname, 
"-%02d:%02d", hour, minute);
 
 2943    sprintf(tname, 
"+%02d:%02d", hour, minute);
 
 2952NV_CHAR *ret_time_neat(NV_INT32 time) {
 
 2953  NV_INT32 hour, minute;
 
 2954  static NV_CHAR tname[16];
 
 2956  hour = abs(time) / 100;
 
 2957  assert(hour <= 99999 && hour >= -99999); 
 
 2958  minute = abs(time) % 100;
 
 2961    sprintf(tname, 
"-%d:%02d", hour, minute);
 
 2963    sprintf(tname, 
"+%d:%02d", hour, minute);
 
 2965    strcpy(tname, 
"0:00");
 
 2973NV_CHAR *ret_date(NV_U_INT32 date) {
 
 2974  static NV_CHAR tname[30];
 
 2976    strcpy(tname, 
"NULL");
 
 2983    sprintf(tname, 
"%4u-%02u-%02u", y, m, d);
 
 3007        "libtcd error: attempt to access database when database not open\n");
 
 3017static void boundscheck_monologue(
const NV_CHAR *
string) {
 
 3019  if (strlen(
string) >= MONOLOGUE_LENGTH) {
 
 3033static void boundscheck_oneliner(
const NV_CHAR *
string) {
 
 3035  if (strlen(
string) >= ONELINER_LENGTH) {
 
 3063static NV_CHAR *clip_string(
const NV_CHAR *
string) {
 
 3064  static NV_CHAR new_string[MONOLOGUE_LENGTH];
 
 3065  NV_INT32 i, l, start = -1, end = -1;
 
 3067  boundscheck_monologue(
string);
 
 3068  new_string[0] = 
'\0';
 
 3070  l = (int)strlen(
string);
 
 3072    for (i = 0; i < l; ++i) {
 
 3073      if (
string[i] != 
' ') {
 
 3078    for (i = l - 1; i >= start; --i) {
 
 3079      if (
string[i] != 
' ' && 
string[i] != 10 && 
string[i] != 13) {
 
 3084    if (start > -1 && end > -1 && end >= start) {
 
 3085      strncpy(new_string, 
string + start, end - start + 1);
 
 3086      new_string[end - start + 1] = 
'\0';
 
 3113NV_INT32 search_station(
const NV_CHAR *
string) {
 
 3114  static NV_CHAR last_search[ONELINER_LENGTH];
 
 3115  static NV_U_INT32 j = 0;
 
 3117  NV_CHAR name[ONELINER_LENGTH], search[ONELINER_LENGTH];
 
 3121        "libtcd error: attempt to access database when database not open\n");
 
 3125  boundscheck_oneliner(
string);
 
 3127  for (i = 0; i < strlen(
string) + 1; ++i) search[i] = 
tolower(
string[i]);
 
 3129  if (strcmp(search, last_search)) j = 0;
 
 3131  strcpy(last_search, search);
 
 3133  while (j < hd.pub.number_of_records) {
 
 3134    for (i = 0; i < strlen(tindex[j].name) + 1; ++i)
 
 3135      name[i] = 
tolower(tindex[j].name[i]);
 
 3138    if (strstr(name, search)) 
return (j - 1);
 
 3163NV_INT32 find_station(
const NV_CHAR *name) {
 
 3168        "libtcd error: attempt to access database when database not open\n");
 
 3173  for (i = 0; i < hd.pub.number_of_records; ++i) {
 
 3174    if (!strcmp(name, tindex[i].name)) 
return (i);
 
 3198NV_INT32 find_tzfile(
const NV_CHAR *name) {
 
 3205        "libtcd error: attempt to access database when database not open\n");
 
 3209  temp = clip_string(name);
 
 3212  for (i = 0; i < hd.pub.tzfiles; ++i) {
 
 3213    if (!strcmp(temp, get_tzfile(i))) {
 
 3240NV_INT32 find_country(
const NV_CHAR *name) {
 
 3247        "libtcd error: attempt to access database when database not open\n");
 
 3251  temp = clip_string(name);
 
 3254  for (i = 0; i < hd.pub.countries; ++i) {
 
 3255    if (!strcmp(temp, get_country(i))) {
 
 3282NV_INT32 find_level_units(
const NV_CHAR *name) {
 
 3289        "libtcd error: attempt to access database when database not open\n");
 
 3293  temp = clip_string(name);
 
 3296  for (i = 0; i < hd.pub.level_unit_types; ++i) {
 
 3297    if (!strcmp(get_level_units(i), temp)) {
 
 3324NV_INT32 find_dir_units(
const NV_CHAR *name) {
 
 3331        "libtcd error: attempt to access database when database not open\n");
 
 3335  temp = clip_string(name);
 
 3338  for (i = 0; i < hd.pub.dir_unit_types; ++i) {
 
 3339    if (!strcmp(get_dir_units(i), temp)) {
 
 3367NV_INT32 find_pedigree(
const NV_CHAR *name) { 
return 0; }
 
 3388NV_INT32 find_datum(
const NV_CHAR *name) {
 
 3395        "libtcd error: attempt to access database when database not open\n");
 
 3399  temp = clip_string(name);
 
 3402  for (i = 0; i < hd.pub.datum_types; ++i) {
 
 3403    if (!strcmp(get_datum(i), temp)) {
 
 3415NV_INT32 find_legalese(
const NV_CHAR *name) {
 
 3422        "libtcd error: attempt to access database when database not open\n");
 
 3426  temp = clip_string(name);
 
 3429  for (i = 0; i < hd.pub.legaleses; ++i) {
 
 3430    if (!strcmp(get_legalese(i), temp)) {
 
 3458NV_INT32 find_constituent(
const NV_CHAR *name) {
 
 3464        "libtcd error: attempt to access database when database not open\n");
 
 3468  temp = clip_string(name);
 
 3470  for (i = 0; i < hd.pub.constituents; ++i) {
 
 3471    if (!strcmp(get_constituent(i), temp)) 
return (i);
 
 3495NV_INT32 find_restriction(
const NV_CHAR *name) {
 
 3502        "libtcd error: attempt to access database when database not open\n");
 
 3506  temp = clip_string(name);
 
 3509  for (i = 0; i < hd.pub.restriction_types; ++i) {
 
 3510    if (!strcmp(get_restriction(i), temp)) {
 
 3536void set_speed(NV_INT32 num, NV_FLOAT64 value) {
 
 3539        "libtcd error: attempt to access database when database not open\n");
 
 3543  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
 
 3545    LOG_ERROR(
"libtcd set_speed: somebody tried to set a negative speed (%f)\n",
 
 3549  hd.speed[num] = value;
 
 3573void set_equilibrium(NV_INT32 num, NV_INT32 year, NV_FLOAT32 value) {
 
 3576        "libtcd error: attempt to access database when database not open\n");
 
 3580  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
 
 3581         year < (NV_INT32)hd.pub.number_of_years);
 
 3582  hd.equilibrium[num][year] = value;
 
 3606void set_node_factor(NV_INT32 num, NV_INT32 year, NV_FLOAT32 value) {
 
 3609        "libtcd error: attempt to access database when database not open\n");
 
 3613  assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
 
 3614         year < (NV_INT32)hd.pub.number_of_years);
 
 3617        "libtcd set_node_factor: somebody tried to set a negative or zero node " 
 3622  hd.node_factor[num][year] = value;
 
 3673        "libtcd error: attempt to access database when database not open\n");
 
 3679  if (strlen(name) + 1 > hd.tzfile_size) {
 
 3680    LOG_ERROR(
"libtcd error: tzfile exceeds size limit (%u).\n",
 
 3682    LOG_ERROR(
"The offending input is: %s\n", name);
 
 3686  if (hd.pub.tzfiles == hd.max_tzfiles) {
 
 3687    LOG_ERROR(
"You have exceeded the maximum number of tzfile types!\n");
 
 3688    LOG_ERROR(
"You cannot add any new tzfile types.\n");
 
 3689    LOG_ERROR(
"Modify the DEFAULT_TZFILE_BITS and rebuild the database.\n");
 
 3693  c_name = clip_string(name);
 
 3695  hd.tzfile[hd.pub.tzfiles] =
 
 3696      (NV_CHAR *)calloc(strlen(c_name) + 1, 
sizeof(NV_CHAR));
 
 3698  if (hd.tzfile[hd.pub.tzfiles] == NULL) {
 
 3699    perror(
"Allocating new tzfile string");
 
 3703  strcpy(hd.tzfile[hd.pub.tzfiles++], c_name);
 
 3704  if (db) *db = hd.pub;
 
 3706  return (hd.pub.tzfiles - 1);
 
 3732        "libtcd error: attempt to access database when database not open\n");
 
 3738  if (strlen(name) + 1 > hd.country_size) {
 
 3739    LOG_ERROR(
"libtcd error: country exceeds size limit (%u).\n",
 
 3741    LOG_ERROR(
"The offending input is: %s\n", name);
 
 3745  if (hd.pub.countries == hd.max_countries) {
 
 3746    LOG_ERROR(
"You have exceeded the maximum number of country names!\n");
 
 3747    LOG_ERROR(
"You cannot add any new country names.\n");
 
 3748    LOG_ERROR(
"Modify the DEFAULT_COUNTRY_BITS and rebuild the database.\n");
 
 3752  c_name = clip_string(name);
 
 3754  hd.country[hd.pub.countries] =
 
 3755      (NV_CHAR *)calloc(strlen(c_name) + 1, 
sizeof(NV_CHAR));
 
 3757  if (hd.country[hd.pub.countries] == NULL) {
 
 3758    perror(
"Allocating new country string");
 
 3762  strcpy(hd.country[hd.pub.countries++], c_name);
 
 3763  if (db) *db = hd.pub;
 
 3765  return (hd.pub.countries - 1);
 
 3791        "libtcd error: attempt to access database when database not open\n");
 
 3797  if (strlen(name) + 1 > hd.datum_size) {
 
 3798    LOG_ERROR(
"libtcd error: datum exceeds size limit (%u).\n", hd.datum_size);
 
 3799    LOG_ERROR(
"The offending input is: %s\n", name);
 
 3803  if (hd.pub.datum_types == hd.max_datum_types) {
 
 3804    LOG_ERROR(
"You have exceeded the maximum number of datum types!\n");
 
 3805    LOG_ERROR(
"You cannot add any new datum types.\n");
 
 3806    LOG_ERROR(
"Modify the DEFAULT_DATUM_BITS and rebuild the database.\n");
 
 3810  c_name = clip_string(name);
 
 3812  hd.datum[hd.pub.datum_types] =
 
 3813      (NV_CHAR *)calloc(strlen(c_name) + 1, 
sizeof(NV_CHAR));
 
 3815  if (hd.datum[hd.pub.datum_types] == NULL) {
 
 3816    perror(
"Allocating new datum string");
 
 3820  strcpy(hd.datum[hd.pub.datum_types++], c_name);
 
 3821  if (db) *db = hd.pub;
 
 3823  return (hd.pub.datum_types - 1);
 
 3834        "libtcd error: attempt to access database when database not open\n");
 
 3840  if (strlen(name) + 1 > hd.legalese_size) {
 
 3841    LOG_ERROR(
"libtcd error: legalese exceeds size limit (%u).\n",
 
 3843    LOG_ERROR(
"The offending input is: %s\n", name);
 
 3847  if (hd.pub.legaleses == hd.max_legaleses) {
 
 3848    LOG_ERROR(
"You have exceeded the maximum number of legaleses!\n");
 
 3849    LOG_ERROR(
"You cannot add any new legaleses.\n");
 
 3850    LOG_ERROR(
"Modify the DEFAULT_LEGALESE_BITS and rebuild the database.\n");
 
 3854  c_name = clip_string(name);
 
 3856  hd.legalese[hd.pub.legaleses] =
 
 3857      (NV_CHAR *)calloc(strlen(c_name) + 1, 
sizeof(NV_CHAR));
 
 3859  if (hd.legalese[hd.pub.legaleses] == NULL) {
 
 3860    perror(
"Allocating new legalese string");
 
 3864  strcpy(hd.legalese[hd.pub.legaleses++], c_name);
 
 3865  if (db) *db = hd.pub;
 
 3867  return (hd.pub.legaleses - 1);
 
 3893        "libtcd error: attempt to access database when database not open\n");
 
 3899  if (strlen(name) + 1 > hd.restriction_size) {
 
 3900    LOG_ERROR(
"libtcd error: restriction exceeds size limit (%u).\n",
 
 3901              hd.restriction_size);
 
 3902    LOG_ERROR(
"The offending input is: %s\n", name);
 
 3906  if (hd.pub.restriction_types == hd.max_restriction_types) {
 
 3907    LOG_ERROR(
"You have exceeded the maximum number of restriction types!\n");
 
 3908    LOG_ERROR(
"You cannot add any new restriction types.\n");
 
 3910        "Modify the DEFAULT_RESTRICTION_BITS and rebuild the database.\n");
 
 3914  c_name = clip_string(name);
 
 3916  hd.restriction[hd.pub.restriction_types] =
 
 3917      (NV_CHAR *)calloc(strlen(c_name) + 1, 
sizeof(NV_CHAR));
 
 3919  if (hd.restriction[hd.pub.restriction_types] == NULL) {
 
 3920    perror(
"Allocating new restriction string");
 
 3924  strcpy(hd.restriction[hd.pub.restriction_types++], c_name);
 
 3925  if (db) *db = hd.pub;
 
 3927  return (hd.pub.restriction_types - 1);
 
 3933NV_INT32 find_or_add_restriction(
const NV_CHAR *name, 
DB_HEADER_PUBLIC *db) {
 
 3935  ret = find_restriction(name);
 
 3936  if (ret < 0) ret = add_restriction(name, db);
 
 3946  ret = find_tzfile(name);
 
 3947  if (ret < 0) ret = add_tzfile(name, db);
 
 3957  ret = find_country(name);
 
 3958  if (ret < 0) ret = add_country(name, db);
 
 3968  ret = find_datum(name);
 
 3969  if (ret < 0) ret = add_datum(name, db);
 
 3979  ret = find_legalese(name);
 
 3980  if (ret < 0) ret = add_legalese(name, db);
 
 4011  if (rec.max_time_add == rec.min_time_add &&
 
 4012      rec.max_level_add == rec.min_level_add &&
 
 4013      rec.max_level_multiply == rec.min_level_multiply &&
 
 4014      rec.max_avg_level == 0 && rec.min_avg_level == 0 &&
 
 4015      rec.max_direction == 361 && rec.min_direction == 361 &&
 
 4016      rec.flood_begins == NULLSLACKOFFSET && rec.ebb_begins == NULLSLACKOFFSET)
 
 4039static NV_U_INT32 header_checksum() {
 
 4040  NV_U_INT32 checksum, i, save_pos;
 
 4042  NV_U_INT32 crc_table[256] = {
 
 4043      0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
 
 4044      0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
 
 4045      0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
 
 4046      0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
 
 4047      0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
 
 4048      0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
 
 4049      0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
 
 4050      0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
 
 4051      0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
 
 4052      0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
 
 4053      0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
 
 4054      0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
 
 4055      0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
 
 4056      0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
 
 4057      0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
 
 4058      0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
 
 4059      0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
 
 4060      0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
 
 4061      0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
 
 4062      0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
 
 4063      0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
 
 4064      0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
 
 4065      0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
 
 4066      0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
 
 4067      0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
 
 4068      0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
 
 4069      0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
 
 4070      0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
 
 4071      0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
 
 4072      0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
 
 4073      0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
 
 4074      0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
 
 4075      0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
 
 4076      0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
 
 4077      0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
 
 4078      0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
 
 4079      0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
 
 4080      0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
 
 4081      0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
 
 4082      0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
 
 4083      0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
 
 4084      0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
 
 4085      0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
 
 4089        "libtcd error: attempt to access database when database not open\n");
 
 4093  save_pos = ftell(fp);
 
 4095  fseek(fp, 0, SEEK_SET);
 
 4097  if ((buf = (NV_U_BYTE *)calloc(hd.header_size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4098    perror(
"Allocating checksum buffer");
 
 4104  assert(hd.header_size > 0);
 
 4105  chk_fread(buf, hd.header_size, 1, fp);
 
 4106  for (i = 0; i < (NV_U_INT32)hd.header_size; ++i) {
 
 4107    checksum = crc_table[(checksum ^ buf[i]) & 0xff] ^ (checksum >> 8);
 
 4113  fseek(fp, save_pos, SEEK_SET);
 
 4134static NV_U_INT32 old_header_checksum() {
 
 4135  NV_U_INT32 checksum, i, save_pos;
 
 4140        "libtcd error: attempt to access database when database not open\n");
 
 4144  save_pos = ftell(fp);
 
 4148  fseek(fp, 0, SEEK_SET);
 
 4150  if ((buf = (NV_U_BYTE *)calloc(hd.header_size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4151    perror(
"Allocating checksum buffer");
 
 4155  chk_fread(buf, hd.header_size, 1, fp);
 
 4157  for (i = 0; i < hd.header_size; ++i) checksum += buf[i];
 
 4161  fseek(fp, save_pos, SEEK_SET);
 
 4171static NV_CHAR *curtime() {
 
 4172  static NV_CHAR buf[ONELINER_LENGTH];
 
 4173  time_t t = time(NULL);
 
 4174  require(strftime(buf, ONELINER_LENGTH, 
"%Y-%m-%d %H:%M %Z", localtime(&t)) >
 
 4183static NV_U_INT32 bits2bytes(NV_U_INT32 nbits) {
 
 4184  if (nbits % 8) 
return nbits / 8 + 1;
 
 4204static void write_tide_db_header() {
 
 4205  NV_U_INT32 i, size, pos;
 
 4206  NV_INT32 start, temp_int;
 
 4207  static NV_CHAR zero = 0;
 
 4208  NV_U_BYTE *buf, checksum_c[4];
 
 4212        "libtcd error: attempt to access database when database not open\n");
 
 4217  fseek(fp, 0, SEEK_SET);
 
 4219  fprintf(fp, 
"[VERSION] = %s\n", LIBTCD_VERSION);
 
 4220  fprintf(fp, 
"[MAJOR REV] = %u\n", LIBTCD_MAJOR_REV);
 
 4221  fprintf(fp, 
"[MINOR REV] = %u\n", LIBTCD_MINOR_REV);
 
 4223  fprintf(fp, 
"[LAST MODIFIED] = %s\n", curtime());
 
 4225  fprintf(fp, 
"[HEADER SIZE] = %u\n", hd.header_size);
 
 4226  fprintf(fp, 
"[NUMBER OF RECORDS] = %u\n", hd.pub.number_of_records);
 
 4228  fprintf(fp, 
"[START YEAR] = %d\n", hd.pub.start_year);
 
 4229  fprintf(fp, 
"[NUMBER OF YEARS] = %u\n", hd.pub.number_of_years);
 
 4231  fprintf(fp, 
"[SPEED BITS] = %u\n", hd.speed_bits);
 
 4232  fprintf(fp, 
"[SPEED SCALE] = %u\n", hd.speed_scale);
 
 4233  fprintf(fp, 
"[SPEED OFFSET] = %d\n", hd.speed_offset);
 
 4234  fprintf(fp, 
"[EQUILIBRIUM BITS] = %u\n", hd.equilibrium_bits);
 
 4235  fprintf(fp, 
"[EQUILIBRIUM SCALE] = %u\n", hd.equilibrium_scale);
 
 4236  fprintf(fp, 
"[EQUILIBRIUM OFFSET] = %d\n", hd.equilibrium_offset);
 
 4237  fprintf(fp, 
"[NODE BITS] = %u\n", hd.node_bits);
 
 4238  fprintf(fp, 
"[NODE SCALE] = %u\n", hd.node_scale);
 
 4239  fprintf(fp, 
"[NODE OFFSET] = %d\n", hd.node_offset);
 
 4240  fprintf(fp, 
"[AMPLITUDE BITS] = %u\n", hd.amplitude_bits);
 
 4241  fprintf(fp, 
"[AMPLITUDE SCALE] = %u\n", hd.amplitude_scale);
 
 4242  fprintf(fp, 
"[EPOCH BITS] = %u\n", hd.epoch_bits);
 
 4243  fprintf(fp, 
"[EPOCH SCALE] = %u\n", hd.epoch_scale);
 
 4245  fprintf(fp, 
"[RECORD TYPE BITS] = %u\n", hd.record_type_bits);
 
 4246  fprintf(fp, 
"[LATITUDE BITS] = %u\n", hd.latitude_bits);
 
 4247  fprintf(fp, 
"[LATITUDE SCALE] = %u\n", hd.latitude_scale);
 
 4248  fprintf(fp, 
"[LONGITUDE BITS] = %u\n", hd.longitude_bits);
 
 4249  fprintf(fp, 
"[LONGITUDE SCALE] = %u\n", hd.longitude_scale);
 
 4250  fprintf(fp, 
"[RECORD SIZE BITS] = %u\n", hd.record_size_bits);
 
 4252  fprintf(fp, 
"[STATION BITS] = %u\n", hd.station_bits);
 
 4254  fprintf(fp, 
"[DATUM OFFSET BITS] = %u\n", hd.datum_offset_bits);
 
 4255  fprintf(fp, 
"[DATUM OFFSET SCALE] = %u\n", hd.datum_offset_scale);
 
 4256  fprintf(fp, 
"[DATE BITS] = %u\n", hd.date_bits);
 
 4257  fprintf(fp, 
"[MONTHS ON STATION BITS] = %u\n", hd.months_on_station_bits);
 
 4258  fprintf(fp, 
"[CONFIDENCE VALUE BITS] = %u\n", hd.confidence_value_bits);
 
 4260  fprintf(fp, 
"[TIME BITS] = %u\n", hd.time_bits);
 
 4261  fprintf(fp, 
"[LEVEL ADD BITS] = %u\n", hd.level_add_bits);
 
 4262  fprintf(fp, 
"[LEVEL ADD SCALE] = %u\n", hd.level_add_scale);
 
 4263  fprintf(fp, 
"[LEVEL MULTIPLY BITS] = %u\n", hd.level_multiply_bits);
 
 4264  fprintf(fp, 
"[LEVEL MULTIPLY SCALE] = %u\n", hd.level_multiply_scale);
 
 4265  fprintf(fp, 
"[DIRECTION BITS] = %u\n", hd.direction_bits);
 
 4267  fprintf(fp, 
"[LEVEL UNIT BITS] = %u\n", hd.level_unit_bits);
 
 4268  fprintf(fp, 
"[LEVEL UNIT TYPES] = %u\n", hd.pub.level_unit_types);
 
 4269  fprintf(fp, 
"[LEVEL UNIT SIZE] = %u\n", hd.level_unit_size);
 
 4271  fprintf(fp, 
"[DIRECTION UNIT BITS] = %u\n", hd.dir_unit_bits);
 
 4272  fprintf(fp, 
"[DIRECTION UNIT TYPES] = %u\n", hd.pub.dir_unit_types);
 
 4273  fprintf(fp, 
"[DIRECTION UNIT SIZE] = %u\n", hd.dir_unit_size);
 
 4275  fprintf(fp, 
"[RESTRICTION BITS] = %u\n", hd.restriction_bits);
 
 4276  fprintf(fp, 
"[RESTRICTION TYPES] = %u\n", hd.pub.restriction_types);
 
 4277  fprintf(fp, 
"[RESTRICTION SIZE] = %u\n", hd.restriction_size);
 
 4279  fprintf(fp, 
"[DATUM BITS] = %u\n", hd.datum_bits);
 
 4280  fprintf(fp, 
"[DATUM TYPES] = %u\n", hd.pub.datum_types);
 
 4281  fprintf(fp, 
"[DATUM SIZE] = %u\n", hd.datum_size);
 
 4283  fprintf(fp, 
"[LEGALESE BITS] = %u\n", hd.legalese_bits);
 
 4284  fprintf(fp, 
"[LEGALESE TYPES] = %u\n", hd.pub.legaleses);
 
 4285  fprintf(fp, 
"[LEGALESE SIZE] = %u\n", hd.legalese_size);
 
 4287  fprintf(fp, 
"[CONSTITUENT BITS] = %u\n", hd.constituent_bits);
 
 4288  fprintf(fp, 
"[CONSTITUENTS] = %u\n", hd.pub.constituents);
 
 4289  fprintf(fp, 
"[CONSTITUENT SIZE] = %u\n", hd.constituent_size);
 
 4291  fprintf(fp, 
"[TZFILE BITS] = %u\n", hd.tzfile_bits);
 
 4292  fprintf(fp, 
"[TZFILES] = %u\n", hd.pub.tzfiles);
 
 4293  fprintf(fp, 
"[TZFILE SIZE] = %u\n", hd.tzfile_size);
 
 4295  fprintf(fp, 
"[COUNTRY BITS] = %u\n", hd.country_bits);
 
 4296  fprintf(fp, 
"[COUNTRIES] = %u\n", hd.pub.countries);
 
 4297  fprintf(fp, 
"[COUNTRY SIZE] = %u\n", hd.country_size);
 
 4299  fprintf(fp, 
"[END OF FILE] = %u\n", hd.end_of_file);
 
 4300  fprintf(fp, 
"[END OF ASCII HEADER DATA]\n");
 
 4306  for (i = start; i < hd.header_size; ++i) chk_fwrite(&zero, 1, 1, fp);
 
 4311  bit_pack(checksum_c, 0, 32, header_checksum());
 
 4312  chk_fwrite(checksum_c, 4, 1, fp);
 
 4319  size = hd.pub.level_unit_types * hd.level_unit_size;
 
 4321  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4322    perror(
"Allocating unit write buffer");
 
 4325  memset(buf, 0, size);
 
 4327  for (i = 0; i < hd.pub.level_unit_types; ++i) {
 
 4328    assert(strlen(hd.level_unit[i]) + 1 <= hd.level_unit_size);
 
 4329    strcpy((NV_CHAR *)&buf[pos], hd.level_unit[i]);
 
 4330    pos += hd.level_unit_size;
 
 4333  chk_fwrite(buf, pos, 1, fp);
 
 4339  size = hd.pub.dir_unit_types * hd.dir_unit_size;
 
 4341  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4342    perror(
"Allocating unit write buffer");
 
 4345  memset(buf, 0, size);
 
 4347  for (i = 0; i < hd.pub.dir_unit_types; ++i) {
 
 4348    assert(strlen(hd.dir_unit[i]) + 1 <= hd.dir_unit_size);
 
 4349    strcpy((NV_CHAR *)&buf[pos], hd.dir_unit[i]);
 
 4350    pos += hd.dir_unit_size;
 
 4353  chk_fwrite(buf, pos, 1, fp);
 
 4359  size = hd.max_restriction_types * hd.restriction_size;
 
 4361  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4362    perror(
"Allocating restriction write buffer");
 
 4365  memset(buf, 0, size);
 
 4367  for (i = 0; i < hd.max_restriction_types; ++i) {
 
 4368    if (i == hd.pub.restriction_types) 
break;
 
 4369    assert(strlen(hd.restriction[i]) + 1 <= hd.restriction_size);
 
 4370    strcpy((NV_CHAR *)&buf[pos], hd.restriction[i]);
 
 4371    pos += hd.restriction_size;
 
 4373  memcpy(&buf[pos], 
"__END__", 7);
 
 4375  chk_fwrite(buf, size, 1, fp);
 
 4381  size = hd.max_tzfiles * hd.tzfile_size;
 
 4383  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4384    perror(
"Allocating tzfile write buffer");
 
 4387  memset(buf, 0, size);
 
 4389  for (i = 0; i < hd.max_tzfiles; ++i) {
 
 4390    if (i == hd.pub.tzfiles) 
break;
 
 4391    assert(strlen(hd.tzfile[i]) + 1 <= hd.tzfile_size);
 
 4392    strcpy((NV_CHAR *)&buf[pos], hd.tzfile[i]);
 
 4393    pos += hd.tzfile_size;
 
 4395  memcpy(&buf[pos], 
"__END__", 7);
 
 4397  chk_fwrite(buf, size, 1, fp);
 
 4403  size = hd.max_countries * hd.country_size;
 
 4405  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4406    perror(
"Allocating country write buffer");
 
 4409  memset(buf, 0, size);
 
 4411  for (i = 0; i < hd.max_countries; ++i) {
 
 4412    if (i == hd.pub.countries) 
break;
 
 4413    assert(strlen(hd.country[i]) + 1 <= hd.country_size);
 
 4414    strcpy((NV_CHAR *)&buf[pos], hd.country[i]);
 
 4415    pos += hd.country_size;
 
 4417  memcpy(&buf[pos], 
"__END__", 7);
 
 4419  chk_fwrite(buf, size, 1, fp);
 
 4425  size = hd.max_datum_types * hd.datum_size;
 
 4427  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4428    perror(
"Allocating datum write buffer");
 
 4431  memset(buf, 0, size);
 
 4433  for (i = 0; i < hd.max_datum_types; ++i) {
 
 4434    if (i == hd.pub.datum_types) 
break;
 
 4435    assert(strlen(hd.datum[i]) + 1 <= hd.datum_size);
 
 4436    strcpy((NV_CHAR *)&buf[pos], hd.datum[i]);
 
 4437    pos += hd.datum_size;
 
 4439  memcpy(&buf[pos], 
"__END__", 7);
 
 4441  chk_fwrite(buf, size, 1, fp);
 
 4447  size = hd.max_legaleses * hd.legalese_size;
 
 4449  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4450    perror(
"Allocating legalese write buffer");
 
 4453  memset(buf, 0, size);
 
 4455  for (i = 0; i < hd.max_legaleses; ++i) {
 
 4456    if (i == hd.pub.legaleses) 
break;
 
 4457    assert(strlen(hd.legalese[i]) + 1 <= hd.legalese_size);
 
 4458    strcpy((NV_CHAR *)&buf[pos], hd.legalese[i]);
 
 4459    pos += hd.legalese_size;
 
 4461  memcpy(&buf[pos], 
"__END__", 7);
 
 4463  chk_fwrite(buf, size, 1, fp);
 
 4469  size = hd.pub.constituents * hd.constituent_size;
 
 4471  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4472    perror(
"Allocating constituent write buffer");
 
 4475  memset(buf, 0, size);
 
 4477  for (i = 0; i < hd.pub.constituents; ++i) {
 
 4478    assert(strlen(hd.constituent[i]) + 1 <= hd.constituent_size);
 
 4479    strcpy((NV_CHAR *)&buf[pos], hd.constituent[i]);
 
 4480    pos += hd.constituent_size;
 
 4483  chk_fwrite(buf, pos, 1, fp);
 
 4491  size = bits2bytes(hd.pub.constituents * hd.speed_bits);
 
 4493  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4494    perror(
"Allocating speed write buffer");
 
 4497  memset(buf, 0, size);
 
 4499  for (i = 0; i < hd.pub.constituents; ++i) {
 
 4500    temp_int = NINT(hd.speed[i] * hd.speed_scale) - hd.speed_offset;
 
 4501    assert(temp_int >= 0);
 
 4502    bit_pack(buf, pos, hd.speed_bits, temp_int);
 
 4503    pos += hd.speed_bits;
 
 4506  chk_fwrite(buf, size, 1, fp);
 
 4512  size = bits2bytes(hd.pub.constituents * hd.pub.number_of_years *
 
 4513                    hd.equilibrium_bits);
 
 4515  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4516    perror(
"Allocating equilibrium write buffer");
 
 4519  memset(buf, 0, size);
 
 4521  for (i = 0; i < hd.pub.constituents; ++i) {
 
 4523    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 4524      temp_int = NINT(hd.equilibrium[i][j] * hd.equilibrium_scale) -
 
 4525                 hd.equilibrium_offset;
 
 4526      assert(temp_int >= 0);
 
 4527      bit_pack(buf, pos, hd.equilibrium_bits, temp_int);
 
 4528      pos += hd.equilibrium_bits;
 
 4532  chk_fwrite(buf, size, 1, fp);
 
 4539      bits2bytes(hd.pub.constituents * hd.pub.number_of_years * hd.node_bits);
 
 4541  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4542    perror(
"Allocating node write buffer");
 
 4545  memset(buf, 0, size);
 
 4547  for (i = 0; i < hd.pub.constituents; ++i) {
 
 4549    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 4550      temp_int = NINT(hd.node_factor[i][j] * hd.node_scale) - hd.node_offset;
 
 4551      assert(temp_int >= 0);
 
 4552      bit_pack(buf, pos, hd.node_bits, temp_int);
 
 4553      pos += hd.node_bits;
 
 4557  chk_fwrite(buf, size, 1, fp);
 
 4588static void unpack_string(NV_U_BYTE *buf, NV_U_INT32 bufsize, NV_U_INT32 *pos,
 
 4589                          NV_CHAR *outbuf, NV_U_INT32 outbuflen,
 
 4590                          const NV_CHAR *desc) {
 
 4600  for (i = 0; c; ++i) {
 
 4601    assert(*pos < bufsize); 
 
 4602    c = bit_unpack(buf, *pos, 8);
 
 4604    if (i < outbuflen) {
 
 4606    } 
else if (i == outbuflen) {
 
 4609        LOG_ERROR(
"libtcd warning: truncating overlong %s\n", desc);
 
 4610        LOG_ERROR(
"The offending string starts with:\n%s\n", outbuf);
 
 4638static void unpack_partial_tide_record(NV_U_BYTE *buf, NV_U_INT32 bufsize,
 
 4648  rec->header.record_size = bit_unpack(buf, *pos, hd.record_size_bits);
 
 4649  *pos += hd.record_size_bits;
 
 4651  rec->header.record_type = bit_unpack(buf, *pos, hd.record_type_bits);
 
 4652  *pos += hd.record_type_bits;
 
 4654  temp_int = signed_bit_unpack(buf, *pos, hd.latitude_bits);
 
 4655  rec->header.latitude = (NV_FLOAT64)temp_int / hd.latitude_scale;
 
 4656  *pos += hd.latitude_bits;
 
 4658  temp_int = signed_bit_unpack(buf, *pos, hd.longitude_bits);
 
 4659  rec->header.longitude = (NV_FLOAT64)temp_int / hd.longitude_scale;
 
 4660  *pos += hd.longitude_bits;
 
 4665  rec->header.tzfile = bit_unpack(buf, *pos, hd.tzfile_bits);
 
 4666  *pos += hd.tzfile_bits;
 
 4668  unpack_string(buf, bufsize, pos, rec->header.name, ONELINER_LENGTH,
 
 4671  rec->header.reference_station = signed_bit_unpack(buf, *pos, hd.station_bits);
 
 4672  *pos += hd.station_bits;
 
 4674  assert(*pos <= bufsize * 8);
 
 4697static NV_INT32 read_partial_tide_record(NV_INT32 num, 
TIDE_RECORD *rec) {
 
 4699  NV_U_INT32 maximum_possible_size, pos;
 
 4703        "libtcd error: attempt to access database when database not open\n");
 
 4712  maximum_possible_size = hd.record_size_bits + hd.record_type_bits +
 
 4713                          hd.latitude_bits + hd.longitude_bits +
 
 4714                          hd.tzfile_bits + (ONELINER_LENGTH * 8) +
 
 4716  maximum_possible_size = bits2bytes(maximum_possible_size);
 
 4718  if ((buf = (NV_U_BYTE *)calloc(maximum_possible_size, 
sizeof(NV_U_BYTE))) ==
 
 4720    perror(
"Allocating partial tide record buffer");
 
 4724  current_record = num;
 
 4725  fseek(fp, tindex[num].address, SEEK_SET);
 
 4730  size_t size = fread(buf, 1, maximum_possible_size, fp);
 
 4731  unpack_partial_tide_record(buf, size, rec, &pos);
 
 4751static NV_BOOL read_tide_db_header() {
 
 4753  NV_CHAR varin[ONELINER_LENGTH], *info;
 
 4754  NV_U_INT32 utemp, i, j, pos, size, key_count;
 
 4755  NV_U_BYTE *buf, checksum_c[5];
 
 4760        "libtcd error: attempt to access database when database not open\n");
 
 4764  strcpy(hd.pub.version, 
"NO VERSION");
 
 4767  key_count = 
sizeof(keys) / 
sizeof(
KEY);
 
 4770  memset(&hd, 0, 
sizeof(hd));
 
 4773  while (fgets(varin, 
sizeof(varin), fp) != NULL) {
 
 4774    if (strlen(varin) == ONELINER_LENGTH - 1) {
 
 4775      if (varin[ONELINER_LENGTH - 2] != 
'\n') {
 
 4776        LOG_ERROR(
"libtcd error:  header line too long, begins with:\n");
 
 4777        LOG_ERROR(
"%s\n", varin);
 
 4778        LOG_ERROR(
"in file %s\n", filename);
 
 4779        LOG_ERROR(
"Configured limit is %u\n", ONELINER_LENGTH - 1);
 
 4785    if (strstr(varin, 
"[END OF ASCII HEADER DATA]")) 
break;
 
 4788    info = strchr(varin, 
'=');
 
 4790      LOG_ERROR(
"libtcd error:  invalid tide db header line:\n");
 
 4791      LOG_ERROR(
"%s", varin);
 
 4792      LOG_ERROR(
"in file %s\n", filename);
 
 4799    for (i = 0; i < key_count; ++i) {
 
 4800      if (strstr(varin, keys[i].keyphrase)) {
 
 4801        if (!strcmp(keys[i].datatype, 
"cstr"))
 
 4802          strcpy((
char *)keys[i].address.cstr, clip_string(info));
 
 4803        else if (!strcmp(keys[i].datatype, 
"i32")) {
 
 4804          if (sscanf(info, 
"%d", keys[i].address.i32) != 1) {
 
 4805            LOG_ERROR(
"libtcd error:  invalid tide db header line:\n");
 
 4806            LOG_ERROR(
"%s", varin);
 
 4807            LOG_ERROR(
"in file %s\n", filename);
 
 4811        } 
else if (!strcmp(keys[i].datatype, 
"ui32")) {
 
 4812          if (sscanf(info, 
"%u", keys[i].address.ui32) != 1) {
 
 4813            LOG_ERROR(
"libtcd error:  invalid tide db header line:\n");
 
 4814            LOG_ERROR(
"%s", varin);
 
 4815            LOG_ERROR(
"in file %s\n", filename);
 
 4827  if (!strcmp(hd.pub.version, 
"NO VERSION")) {
 
 4828    LOG_ERROR(
"libtcd error:  no version found in tide db header\n");
 
 4829    LOG_ERROR(
"in file %s\n", filename);
 
 4835  if (hd.pub.major_rev > LIBTCD_MAJOR_REV) {
 
 4837        "libtcd error:  major revision in TCD file (%u) exceeds major revision " 
 4840    LOG_ERROR(
"libtcd (%u).  You must upgrade libtcd to read this file.\n",
 
 4847  fseek(fp, hd.header_size, SEEK_SET);
 
 4851  chk_fread(checksum_c, 4, 1, fp);
 
 4852  utemp = bit_unpack(checksum_c, 0, 32);
 
 4854  if (utemp != header_checksum()) {
 
 4856    if (utemp != old_header_checksum()) {
 
 4857      LOG_ERROR(
"libtcd error:  header checksum error in file %s\n", filename);
 
 4859          "Someone may have modified the ASCII portion of the header (don't do that),\n\ 
 4860or it may just be corrupt.\n");
 
 4865    LOG_ERROR(
"libtcd error:  header checksum error in file %s\n", filename);
 
 4867        "Someone may have modified the ASCII portion of the header (don't do that),\n\ 
 4868or it may be an ancient pre-version-1.02 TCD file, or it may just be corrupt.\n\ 
 4869Pre-version-1.02 TCD files can be read by building libtcd with COMPAT114\n\ 
 4875  fseek(fp, hd.header_size + 4, SEEK_SET);
 
 4880  hd.max_restriction_types = NINT(pow(2.0, (NV_FLOAT64)hd.restriction_bits));
 
 4884  hd.max_tzfiles = NINT(pow(2.0, (NV_FLOAT64)hd.tzfile_bits));
 
 4888  hd.max_countries = NINT(pow(2.0, (NV_FLOAT64)hd.country_bits));
 
 4893  hd.max_datum_types = NINT(pow(2.0, (NV_FLOAT64)hd.datum_bits));
 
 4898  if (hd.pub.major_rev < 2)
 
 4899    hd.max_legaleses = 1;
 
 4901    hd.max_legaleses = NINT(pow(2.0, (NV_FLOAT64)hd.legalese_bits));
 
 4908      (NV_CHAR **)calloc(hd.pub.level_unit_types, 
sizeof(NV_CHAR *));
 
 4910  if ((buf = (NV_U_BYTE *)calloc(hd.level_unit_size, 
sizeof(NV_U_BYTE))) ==
 
 4912    perror(
"Allocating level unit read buffer");
 
 4916  for (i = 0; i < hd.pub.level_unit_types; ++i) {
 
 4917    chk_fread(buf, hd.level_unit_size, 1, fp);
 
 4919        (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 4920    strcpy(hd.level_unit[i], (NV_CHAR *)buf);
 
 4926  hd.dir_unit = (NV_CHAR **)calloc(hd.pub.dir_unit_types, 
sizeof(NV_CHAR *));
 
 4928  if ((buf = (NV_U_BYTE *)calloc(hd.dir_unit_size, 
sizeof(NV_U_BYTE))) ==
 
 4930    perror(
"Allocating dir unit read buffer");
 
 4934  for (i = 0; i < hd.pub.dir_unit_types; ++i) {
 
 4935    chk_fread(buf, hd.dir_unit_size, 1, fp);
 
 4937        (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 4938    strcpy(hd.dir_unit[i], (NV_CHAR *)buf);
 
 4946      (NV_CHAR **)calloc(hd.max_restriction_types, 
sizeof(NV_CHAR *));
 
 4948  if ((buf = (NV_U_BYTE *)calloc(hd.restriction_size, 
sizeof(NV_U_BYTE))) ==
 
 4950    perror(
"Allocating restriction read buffer");
 
 4954  hd.pub.restriction_types = 0;
 
 4955  for (i = 0; i < hd.max_restriction_types; ++i) {
 
 4956    chk_fread(buf, hd.restriction_size, 1, fp);
 
 4957    if (!strcmp((
char *)buf, 
"__END__")) {
 
 4958      hd.pub.restriction_types = i;
 
 4962        (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 4963    strcpy(hd.restriction[i], (NV_CHAR *)buf);
 
 4966  fseek(fp, utemp + hd.max_restriction_types * hd.restriction_size, SEEK_SET);
 
 4969  if (hd.pub.major_rev < 2)
 
 4970    fseek(fp, hd.pedigree_size * NINT(pow(2.0, (NV_FLOAT64)hd.pedigree_bits)),
 
 4972  hd.pub.pedigree_types = 1;
 
 4977  hd.tzfile = (NV_CHAR **)calloc(hd.max_tzfiles, 
sizeof(NV_CHAR *));
 
 4979  if ((buf = (NV_U_BYTE *)calloc(hd.tzfile_size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 4980    perror(
"Allocating tzfile read buffer");
 
 4985  for (i = 0; i < hd.max_tzfiles; ++i) {
 
 4986    chk_fread(buf, hd.tzfile_size, 1, fp);
 
 4987    if (!strcmp((
char *)buf, 
"__END__")) {
 
 4991    hd.tzfile[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 4992    strcpy(hd.tzfile[i], (NV_CHAR *)buf);
 
 4995  fseek(fp, utemp + hd.max_tzfiles * hd.tzfile_size, SEEK_SET);
 
 5000  hd.country = (NV_CHAR **)calloc(hd.max_countries, 
sizeof(NV_CHAR *));
 
 5002  if ((buf = (NV_U_BYTE *)calloc(hd.country_size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 5003    perror(
"Allocating country read buffer");
 
 5007  hd.pub.countries = 0;
 
 5008  for (i = 0; i < hd.max_countries; ++i) {
 
 5009    chk_fread(buf, hd.country_size, 1, fp);
 
 5010    if (!strcmp((
char *)buf, 
"__END__")) {
 
 5011      hd.pub.countries = i;
 
 5014    hd.country[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 5015    strcpy(hd.country[i], (NV_CHAR *)buf);
 
 5018  fseek(fp, utemp + hd.max_countries * hd.country_size, SEEK_SET);
 
 5023  hd.datum = (NV_CHAR **)calloc(hd.max_datum_types, 
sizeof(NV_CHAR *));
 
 5025  if ((buf = (NV_U_BYTE *)calloc(hd.datum_size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 5026    perror(
"Allocating datum read buffer");
 
 5030  hd.pub.datum_types = 0;
 
 5031  for (i = 0; i < hd.max_datum_types; ++i) {
 
 5032    chk_fread(buf, hd.datum_size, 1, fp);
 
 5033    if (!strcmp((
char *)buf, 
"__END__")) {
 
 5034      hd.pub.datum_types = i;
 
 5037    hd.datum[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 5038    strcpy(hd.datum[i], (NV_CHAR *)buf);
 
 5041  fseek(fp, utemp + hd.max_datum_types * hd.datum_size, SEEK_SET);
 
 5045  if (hd.pub.major_rev < 2) {
 
 5046    hd.legalese = (NV_CHAR **)malloc(
sizeof(NV_CHAR *));
 
 5047    assert(hd.legalese != NULL);
 
 5048    hd.legalese[0] = (NV_CHAR *)malloc(5 * 
sizeof(NV_CHAR));
 
 5049    assert(hd.legalese[0] != NULL);
 
 5050    strcpy(hd.legalese[0], 
"NULL");
 
 5051    hd.pub.legaleses = 1;
 
 5054    hd.legalese = (NV_CHAR **)calloc(hd.max_legaleses, 
sizeof(NV_CHAR *));
 
 5056    if ((buf = (NV_U_BYTE *)calloc(hd.legalese_size, 
sizeof(NV_U_BYTE))) ==
 
 5058      perror(
"Allocating legalese read buffer");
 
 5062    hd.pub.legaleses = 0;
 
 5063    for (i = 0; i < hd.max_legaleses; ++i) {
 
 5064      chk_fread(buf, hd.legalese_size, 1, fp);
 
 5065      if (!strcmp((
char *)buf, 
"__END__")) {
 
 5066        hd.pub.legaleses = i;
 
 5070          (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 5071      strcpy(hd.legalese[i], (NV_CHAR *)buf);
 
 5074    fseek(fp, utemp + hd.max_legaleses * hd.legalese_size, SEEK_SET);
 
 5079  hd.constituent = (NV_CHAR **)calloc(hd.pub.constituents, 
sizeof(NV_CHAR *));
 
 5081  if ((buf = (NV_U_BYTE *)calloc(hd.constituent_size, 
sizeof(NV_U_BYTE))) ==
 
 5083    perror(
"Allocating constituent read buffer");
 
 5087  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5088    chk_fread(buf, hd.constituent_size, 1, fp);
 
 5090        (NV_CHAR *)calloc(strlen((
char *)buf) + 1, 
sizeof(NV_CHAR));
 
 5091    strcpy(hd.constituent[i], (NV_CHAR *)buf);
 
 5095  if (hd.speed_offset < 0 || hd.equilibrium_offset < 0 || hd.node_offset < 0) {
 
 5096    LOG_ERROR(
"libtcd WARNING:  File: %s\n", filename);
 
 5098        "WARNING:  This TCD file was created by a pre-version-1.11 libtcd.\n\ 
 5099Versions of libtcd prior to 1.11 contained a serious bug that can result\n\ 
 5100in overflows in the speeds, equilibrium arguments, or node factors.  This\n\ 
 5101database should be rebuilt from the original data if possible.\n");
 
 5108  hd.speed = (NV_FLOAT64 *)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT64));
 
 5112  if (hd.pub.major_rev < 2)
 
 5113    size = ((hd.pub.constituents * hd.speed_bits) / 8) + 1;
 
 5115    size = bits2bytes(hd.pub.constituents * hd.speed_bits);
 
 5117  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 5118    perror(
"Allocating speed read buffer");
 
 5122  chk_fread(buf, size, 1, fp);
 
 5124  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5125    temp_int = bit_unpack(buf, pos, hd.speed_bits);
 
 5126    hd.speed[i] = (NV_FLOAT64)(temp_int + hd.speed_offset) / hd.speed_scale;
 
 5127    pos += hd.speed_bits;
 
 5128    assert(hd.speed[i] >= 0.0);
 
 5135      (NV_FLOAT32 **)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT32 *));
 
 5137  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5139        (NV_FLOAT32 *)calloc(hd.pub.number_of_years, 
sizeof(NV_FLOAT32));
 
 5144  if (hd.pub.major_rev < 2)
 
 5146        ((hd.pub.constituents * hd.pub.number_of_years * hd.equilibrium_bits) /
 
 5150    size = bits2bytes(hd.pub.constituents * hd.pub.number_of_years *
 
 5151                      hd.equilibrium_bits);
 
 5153  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 5154    perror(
"Allocating equilibrium read buffer");
 
 5158  chk_fread(buf, size, 1, fp);
 
 5160  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5161    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 5162      temp_int = bit_unpack(buf, pos, hd.equilibrium_bits);
 
 5163      hd.equilibrium[i][j] =
 
 5164          (NV_FLOAT32)(temp_int + hd.equilibrium_offset) / hd.equilibrium_scale;
 
 5165      pos += hd.equilibrium_bits;
 
 5173      (NV_FLOAT32 **)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT32 *));
 
 5175  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5177        (NV_FLOAT32 *)calloc(hd.pub.number_of_years, 
sizeof(NV_FLOAT32));
 
 5182  if (hd.pub.major_rev < 2)
 
 5184        ((hd.pub.constituents * hd.pub.number_of_years * hd.node_bits) / 8) + 1;
 
 5187        bits2bytes(hd.pub.constituents * hd.pub.number_of_years * hd.node_bits);
 
 5189  if ((buf = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 5190    perror(
"Allocating node read buffer");
 
 5194  chk_fread(buf, size, 1, fp);
 
 5196  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5197    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 5198      temp_int = bit_unpack(buf, pos, hd.node_bits);
 
 5199      hd.node_factor[i][j] =
 
 5200          (NV_FLOAT32)(temp_int + hd.node_offset) / hd.node_scale;
 
 5201      pos += hd.node_bits;
 
 5202      assert(hd.node_factor[i][j] > 0.0);
 
 5211  if (hd.pub.number_of_records) {
 
 5212    if ((tindex = (
TIDE_INDEX *)calloc(hd.pub.number_of_records,
 
 5214      perror(
"Allocating tide index");
 
 5218    tindex[0].address = ftell(fp);
 
 5222  for (i = 0; i < hd.pub.number_of_records; ++i) {
 
 5226    if (i) tindex[i].address = tindex[i - 1].address + rec.header.record_size;
 
 5228    read_partial_tide_record(i, &rec);
 
 5232    tindex[i].record_size = rec.header.record_size;
 
 5233    tindex[i].record_type = rec.header.record_type;
 
 5234    tindex[i].reference_station = rec.header.reference_station;
 
 5235    assert(rec.header.tzfile >= 0);
 
 5236    tindex[i].tzfile = rec.header.tzfile;
 
 5237    tindex[i].lat = NINT(rec.header.latitude * hd.latitude_scale);
 
 5238    tindex[i].lon = NINT(rec.header.longitude * hd.longitude_scale);
 
 5240    if ((tindex[i].name = (NV_CHAR *)calloc(strlen(rec.header.name) + 1,
 
 5241                                            sizeof(NV_CHAR))) == NULL) {
 
 5242      perror(
"Allocating index name memory");
 
 5246    strcpy(tindex[i].name, rec.header.name);
 
 5249  current_record = -1;
 
 5272NV_BOOL open_tide_db(
const NV_CHAR *file) {
 
 5274  current_record = -1;
 
 5277    if (!strcmp(file, filename) && !modified)
 
 5282  if ((fp = fopen(file, 
"rb+")) == NULL) {
 
 5283    if ((fp = fopen(file, 
"rb")) == NULL) 
return (NVFalse);
 
 5285  boundscheck_monologue(file);
 
 5286  strcpy(filename, file);
 
 5287  return (read_tide_db_header());
 
 5308void close_tide_db() {
 
 5312    LOG_ERROR(
"libtcd warning: close_tide_db called when no database open\n");
 
 5319  if (modified) write_tide_db_header();
 
 5323  assert(hd.constituent);
 
 5324  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5325    if (hd.constituent[i] != NULL) free(hd.constituent[i]);
 
 5327  free(hd.constituent);
 
 5328  hd.constituent = NULL;
 
 5330  if (hd.speed != NULL) free(hd.speed);
 
 5332  assert(hd.equilibrium);
 
 5333  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5334    if (hd.equilibrium[i] != NULL) free(hd.equilibrium[i]);
 
 5336  free(hd.equilibrium);
 
 5337  hd.equilibrium = NULL;
 
 5339  assert(hd.node_factor);
 
 5340  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5341    if (hd.node_factor[i] != NULL) free(hd.node_factor[i]);
 
 5343  free(hd.node_factor);
 
 5344  hd.node_factor = NULL;
 
 5346  assert(hd.level_unit);
 
 5347  for (i = 0; i < hd.pub.level_unit_types; ++i) {
 
 5348    if (hd.level_unit[i] != NULL) free(hd.level_unit[i]);
 
 5350  free(hd.level_unit);
 
 5351  hd.level_unit = NULL;
 
 5353  assert(hd.dir_unit);
 
 5354  for (i = 0; i < hd.pub.dir_unit_types; ++i) {
 
 5355    if (hd.dir_unit[i] != NULL) free(hd.dir_unit[i]);
 
 5360  assert(hd.restriction);
 
 5361  for (i = 0; i < hd.max_restriction_types; ++i) {
 
 5362    if (hd.restriction[i] != NULL) free(hd.restriction[i]);
 
 5364  free(hd.restriction);
 
 5365  hd.restriction = NULL;
 
 5367  assert(hd.legalese);
 
 5368  for (i = 0; i < hd.max_legaleses; ++i) {
 
 5369    if (hd.legalese[i] != NULL) free(hd.legalese[i]);
 
 5375  for (i = 0; i < hd.max_tzfiles; ++i) {
 
 5376    if (hd.tzfile[i] != NULL) free(hd.tzfile[i]);
 
 5382  for (i = 0; i < hd.max_countries; ++i) {
 
 5383    if (hd.country[i] != NULL) free(hd.country[i]);
 
 5389  for (i = 0; i < hd.max_datum_types; ++i) {
 
 5390    if (hd.datum[i] != NULL) free(hd.datum[i]);
 
 5397    for (i = 0; i < hd.pub.number_of_records; ++i) {
 
 5398      if (tindex[i].name) free(tindex[i].name);
 
 5439NV_BOOL create_tide_db(
const NV_CHAR *file, NV_U_INT32 constituents,
 
 5440                       NV_CHAR 
const *
const constituent[],
 
 5441                       const NV_FLOAT64 *speed, NV_INT32 start_year,
 
 5442                       NV_U_INT32 num_years,
 
 5443                       NV_FLOAT32 
const *
const equilibrium[],
 
 5444                       NV_FLOAT32 
const *
const node_factor[]) {
 
 5446  NV_FLOAT64 min_value, max_value;
 
 5451  assert(constituent);
 
 5453  assert(equilibrium);
 
 5454  assert(node_factor);
 
 5455  for (i = 0; i < constituents; ++i) {
 
 5456    if (speed[i] < 0.0) {
 
 5458          "libtcd create_tide_db: somebody tried to set a negative speed " 
 5463    for (j = 0; j < num_years; ++j) {
 
 5464      if (node_factor[i][j] <= 0.0) {
 
 5466            "libtcd create_tide_db: somebody tried to set a negative or zero " 
 5467            "node factor (%f)\n",
 
 5474  if (fp) close_tide_db();
 
 5476  if ((fp = fopen(file, 
"wb+")) == NULL) {
 
 5483  memset(&hd, 0, 
sizeof(hd));
 
 5485  hd.pub.major_rev = LIBTCD_MAJOR_REV;
 
 5486  hd.pub.minor_rev = LIBTCD_MINOR_REV;
 
 5488  hd.header_size = DEFAULT_HEADER_SIZE;
 
 5489  hd.pub.number_of_records = DEFAULT_NUMBER_OF_RECORDS;
 
 5491  hd.pub.start_year = start_year;
 
 5492  hd.pub.number_of_years = num_years;
 
 5494  hd.pub.constituents = constituents;
 
 5498  hd.constituent = (NV_CHAR **)calloc(hd.pub.constituents, 
sizeof(NV_CHAR *));
 
 5499  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5501        (NV_CHAR *)calloc(strlen(constituent[i]) + 1, 
sizeof(NV_CHAR));
 
 5502    strcpy(hd.constituent[i], constituent[i]);
 
 5508  hd.constituent_bits = calculate_bits(hd.pub.constituents);
 
 5512  hd.speed = (NV_FLOAT64 *)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT64));
 
 5514  hd.speed_scale = DEFAULT_SPEED_SCALE;
 
 5515  min_value = 99999999.0;
 
 5516  max_value = -99999999.0;
 
 5517  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5518    if (speed[i] < min_value) min_value = speed[i];
 
 5519    if (speed[i] > max_value) max_value = speed[i];
 
 5521    hd.speed[i] = speed[i];
 
 5527  hd.speed_offset = (NINT(min_value * hd.speed_scale));
 
 5528  temp_int = NINT(max_value * hd.speed_scale) - hd.speed_offset;
 
 5529  assert(temp_int >= 0);
 
 5530  hd.speed_bits = calculate_bits((NV_U_INT32)temp_int);
 
 5532  assert(hd.speed_bits < 32);
 
 5537      (NV_FLOAT32 **)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT32 *));
 
 5539  hd.equilibrium_scale = DEFAULT_EQUILIBRIUM_SCALE;
 
 5540  min_value = 99999999.0;
 
 5541  max_value = -99999999.0;
 
 5542  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5544        (NV_FLOAT32 *)calloc(hd.pub.number_of_years, 
sizeof(NV_FLOAT32));
 
 5545    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 5546      if (equilibrium[i][j] < min_value) min_value = equilibrium[i][j];
 
 5547      if (equilibrium[i][j] > max_value) max_value = equilibrium[i][j];
 
 5549      hd.equilibrium[i][j] = equilibrium[i][j];
 
 5556  hd.equilibrium_offset = (NINT(min_value * hd.equilibrium_scale));
 
 5557  temp_int = NINT(max_value * hd.equilibrium_scale) - hd.equilibrium_offset;
 
 5558  assert(temp_int >= 0);
 
 5559  hd.equilibrium_bits = calculate_bits((NV_U_INT32)temp_int);
 
 5564      (NV_FLOAT32 **)calloc(hd.pub.constituents, 
sizeof(NV_FLOAT32 *));
 
 5566  hd.node_scale = DEFAULT_NODE_SCALE;
 
 5567  min_value = 99999999.0;
 
 5568  max_value = -99999999.0;
 
 5569  for (i = 0; i < hd.pub.constituents; ++i) {
 
 5571        (NV_FLOAT32 *)calloc(hd.pub.number_of_years, 
sizeof(NV_FLOAT32));
 
 5572    for (j = 0; j < hd.pub.number_of_years; ++j) {
 
 5573      if (node_factor[i][j] < min_value) min_value = node_factor[i][j];
 
 5574      if (node_factor[i][j] > max_value) max_value = node_factor[i][j];
 
 5576      hd.node_factor[i][j] = node_factor[i][j];
 
 5583  hd.node_offset = (NINT(min_value * hd.node_scale));
 
 5584  temp_int = NINT(max_value * hd.node_scale) - hd.node_offset;
 
 5585  assert(temp_int >= 0);
 
 5586  hd.node_bits = calculate_bits((NV_U_INT32)temp_int);
 
 5590  hd.amplitude_bits = DEFAULT_AMPLITUDE_BITS;
 
 5591  hd.amplitude_scale = DEFAULT_AMPLITUDE_SCALE;
 
 5592  hd.epoch_bits = DEFAULT_EPOCH_BITS;
 
 5593  hd.epoch_scale = DEFAULT_EPOCH_SCALE;
 
 5595  hd.record_type_bits = DEFAULT_RECORD_TYPE_BITS;
 
 5596  hd.latitude_bits = DEFAULT_LATITUDE_BITS;
 
 5597  hd.latitude_scale = DEFAULT_LATITUDE_SCALE;
 
 5598  hd.longitude_bits = DEFAULT_LONGITUDE_BITS;
 
 5599  hd.longitude_scale = DEFAULT_LONGITUDE_SCALE;
 
 5600  hd.record_size_bits = DEFAULT_RECORD_SIZE_BITS;
 
 5602  hd.station_bits = DEFAULT_STATION_BITS;
 
 5604  hd.datum_offset_bits = DEFAULT_DATUM_OFFSET_BITS;
 
 5605  hd.datum_offset_scale = DEFAULT_DATUM_OFFSET_SCALE;
 
 5606  hd.date_bits = DEFAULT_DATE_BITS;
 
 5607  hd.months_on_station_bits = DEFAULT_MONTHS_ON_STATION_BITS;
 
 5608  hd.confidence_value_bits = DEFAULT_CONFIDENCE_VALUE_BITS;
 
 5610  hd.time_bits = DEFAULT_TIME_BITS;
 
 5611  hd.level_add_bits = DEFAULT_LEVEL_ADD_BITS;
 
 5612  hd.level_add_scale = DEFAULT_LEVEL_ADD_SCALE;
 
 5613  hd.level_multiply_bits = DEFAULT_LEVEL_MULTIPLY_BITS;
 
 5614  hd.level_multiply_scale = DEFAULT_LEVEL_MULTIPLY_SCALE;
 
 5615  hd.direction_bits = DEFAULT_DIRECTION_BITS;
 
 5617  hd.constituent_size = DEFAULT_CONSTITUENT_SIZE;
 
 5618  hd.level_unit_size = DEFAULT_LEVEL_UNIT_SIZE;
 
 5619  hd.dir_unit_size = DEFAULT_DIR_UNIT_SIZE;
 
 5620  hd.restriction_size = DEFAULT_RESTRICTION_SIZE;
 
 5621  hd.tzfile_size = DEFAULT_TZFILE_SIZE;
 
 5622  hd.country_size = DEFAULT_COUNTRY_SIZE;
 
 5623  hd.datum_size = DEFAULT_DATUM_SIZE;
 
 5624  hd.legalese_size = DEFAULT_LEGALESE_SIZE;
 
 5628  hd.pub.level_unit_types = DEFAULT_LEVEL_UNIT_TYPES;
 
 5629  hd.level_unit_bits = calculate_bits(hd.pub.level_unit_types - 1);
 
 5632      (NV_CHAR **)calloc(hd.pub.level_unit_types, 
sizeof(NV_CHAR *));
 
 5633  for (i = 0; i < hd.pub.level_unit_types; ++i) {
 
 5635        (NV_CHAR *)calloc(strlen(level_unit[i]) + 1, 
sizeof(NV_CHAR));
 
 5636    strcpy(hd.level_unit[i], level_unit[i]);
 
 5641  hd.pub.dir_unit_types = DEFAULT_DIR_UNIT_TYPES;
 
 5642  hd.dir_unit_bits = calculate_bits(hd.pub.dir_unit_types - 1);
 
 5644  hd.dir_unit = (NV_CHAR **)calloc(hd.pub.dir_unit_types, 
sizeof(NV_CHAR *));
 
 5645  for (i = 0; i < hd.pub.dir_unit_types; ++i) {
 
 5647        (NV_CHAR *)calloc(strlen(dir_unit[i]) + 1, 
sizeof(NV_CHAR));
 
 5648    strcpy(hd.dir_unit[i], dir_unit[i]);
 
 5653  hd.restriction_bits = DEFAULT_RESTRICTION_BITS;
 
 5654  hd.max_restriction_types = NINT(pow(2.0, (NV_FLOAT64)hd.restriction_bits));
 
 5655  hd.pub.restriction_types = DEFAULT_RESTRICTION_TYPES;
 
 5658      (NV_CHAR **)calloc(hd.max_restriction_types, 
sizeof(NV_CHAR *));
 
 5659  for (i = 0; i < hd.max_restriction_types; ++i) {
 
 5660    if (i == hd.pub.restriction_types) 
break;
 
 5663        (NV_CHAR *)calloc(strlen(restriction[i]) + 1, 
sizeof(NV_CHAR));
 
 5664    strcpy(hd.restriction[i], restriction[i]);
 
 5669  hd.legalese_bits = DEFAULT_LEGALESE_BITS;
 
 5670  hd.max_legaleses = NINT(pow(2.0, (NV_FLOAT64)hd.legalese_bits));
 
 5671  hd.pub.legaleses = DEFAULT_LEGALESES;
 
 5673  hd.legalese = (NV_CHAR **)calloc(hd.max_legaleses, 
sizeof(NV_CHAR *));
 
 5674  for (i = 0; i < hd.max_legaleses; ++i) {
 
 5675    if (i == hd.pub.legaleses) 
break;
 
 5678        (NV_CHAR *)calloc(strlen(legalese[i]) + 1, 
sizeof(NV_CHAR));
 
 5679    strcpy(hd.legalese[i], legalese[i]);
 
 5684  hd.tzfile_bits = DEFAULT_TZFILE_BITS;
 
 5685  hd.max_tzfiles = NINT(pow(2.0, (NV_FLOAT64)hd.tzfile_bits));
 
 5686  hd.pub.tzfiles = DEFAULT_TZFILES;
 
 5688  hd.tzfile = (NV_CHAR **)calloc(hd.max_tzfiles, 
sizeof(NV_CHAR *));
 
 5689  for (i = 0; i < hd.max_tzfiles; ++i) {
 
 5690    if (i == hd.pub.tzfiles) 
break;
 
 5692    hd.tzfile[i] = (NV_CHAR *)calloc(strlen(tzfile[i]) + 1, 
sizeof(NV_CHAR));
 
 5693    strcpy(hd.tzfile[i], tzfile[i]);
 
 5698  hd.country_bits = DEFAULT_COUNTRY_BITS;
 
 5699  hd.max_countries = NINT(pow(2.0, (NV_FLOAT64)hd.country_bits));
 
 5700  hd.pub.countries = DEFAULT_COUNTRIES;
 
 5702  hd.country = (NV_CHAR **)calloc(hd.max_countries, 
sizeof(NV_CHAR *));
 
 5703  for (i = 0; i < hd.max_countries; ++i) {
 
 5704    if (i == hd.pub.countries) 
break;
 
 5706    hd.country[i] = (NV_CHAR *)calloc(strlen(country[i]) + 1, 
sizeof(NV_CHAR));
 
 5707    strcpy(hd.country[i], country[i]);
 
 5712  hd.datum_bits = DEFAULT_DATUM_BITS;
 
 5713  hd.max_datum_types = NINT(pow(2.0, (NV_FLOAT64)hd.datum_bits));
 
 5714  hd.pub.datum_types = DEFAULT_DATUM_TYPES;
 
 5716  hd.datum = (NV_CHAR **)calloc(hd.max_datum_types, 
sizeof(NV_CHAR *));
 
 5717  for (i = 0; i < hd.max_datum_types; ++i) {
 
 5718    if (i == hd.pub.datum_types) 
break;
 
 5720    hd.datum[i] = (NV_CHAR *)calloc(strlen(datum[i]) + 1, 
sizeof(NV_CHAR));
 
 5721    strcpy(hd.datum[i], datum[i]);
 
 5731  i = (open_tide_db(file));
 
 5735  hd.end_of_file = ftell(fp);
 
 5739  write_tide_db_header();
 
 5748static NV_BOOL check_date(NV_U_INT32 date) {
 
 5754    if (m < 1 || m > 12 || d < 1 || d > 31) 
return NVFalse;
 
 5768static NV_BOOL check_tide_record(
TIDE_RECORD *rec) {
 
 5770  NV_BOOL ret = NVTrue;
 
 5773    LOG_ERROR(
"libtcd error: null pointer passed to check_tide_record\n");
 
 5779  boundscheck_oneliner(rec->header.name);
 
 5780  boundscheck_oneliner(rec->source);
 
 5781  boundscheck_monologue(rec->comments);
 
 5782  boundscheck_monologue(rec->notes);
 
 5783  boundscheck_oneliner(rec->station_id_context);
 
 5784  boundscheck_oneliner(rec->station_id);
 
 5785  boundscheck_monologue(rec->xfields);
 
 5788  if (rec->header.record_type == REFERENCE_STATION && rec->units > 0)
 
 5789    rec->level_units = rec->units;
 
 5792  if (rec->header.latitude < -90.0 || rec->header.latitude > 90.0 ||
 
 5793      rec->header.longitude < -180.0 || rec->header.longitude > 180.0) {
 
 5794    LOG_ERROR(
"libtcd error: bad coordinates in tide record\n");
 
 5798  if (rec->header.tzfile < 0 ||
 
 5799      rec->header.tzfile >= (NV_INT32)hd.pub.tzfiles) {
 
 5800    LOG_ERROR(
"libtcd error: bad tzfile in tide record\n");
 
 5804  if (rec->header.name[0] == 
'\0') {
 
 5805    LOG_ERROR(
"libtcd error: null name in tide record\n");
 
 5809  if (rec->country < 0 || rec->country >= (NV_INT32)hd.pub.countries) {
 
 5810    LOG_ERROR(
"libtcd error: bad country in tide record\n");
 
 5814  if (rec->restriction >= hd.pub.restriction_types) {
 
 5815    LOG_ERROR(
"libtcd error: bad restriction in tide record\n");
 
 5819  if (rec->legalese >= hd.pub.legaleses) {
 
 5820    LOG_ERROR(
"libtcd error: bad legalese in tide record\n");
 
 5824  if (!check_date(rec->date_imported)) {
 
 5825    LOG_ERROR(
"libtcd error: bad date_imported in tide record\n");
 
 5829  if (rec->direction_units >= hd.pub.dir_unit_types) {
 
 5830    LOG_ERROR(
"libtcd error: bad direction_units in tide record\n");
 
 5834  if (rec->min_direction < 0 || rec->min_direction > 361) {
 
 5835    LOG_ERROR(
"libtcd error: min_direction out of range in tide record\n");
 
 5839  if (rec->max_direction < 0 || rec->max_direction > 361) {
 
 5840    LOG_ERROR(
"libtcd error: max_direction out of range in tide record\n");
 
 5844  if (rec->level_units >= hd.pub.level_unit_types) {
 
 5845    LOG_ERROR(
"libtcd error: bad units in tide record\n");
 
 5849  switch (rec->header.record_type) {
 
 5850    case REFERENCE_STATION:
 
 5851      if (rec->header.reference_station != -1) {
 
 5852        LOG_ERROR(
"libtcd error: type 1 record, reference_station != -1\n");
 
 5856      if (rec->datum_offset < -13421.7728 || rec->datum_offset > 13421.7727) {
 
 5857        LOG_ERROR(
"libtcd error: datum_offset out of range in tide record\n");
 
 5861      if (rec->datum < 0 || rec->datum >= (NV_INT32)hd.pub.datum_types) {
 
 5862        LOG_ERROR(
"libtcd error: bad datum in tide record\n");
 
 5866      if (rec->zone_offset < -4096 || rec->zone_offset > 4095 ||
 
 5867          rec->zone_offset % 100 >= 60) {
 
 5868        LOG_ERROR(
"libtcd error: bad zone_offset in tide record\n");
 
 5872      if (!check_date(rec->expiration_date)) {
 
 5873        LOG_ERROR(
"libtcd error: bad expiration_date in tide record\n");
 
 5877      if (rec->months_on_station > 1023) {
 
 5879            "libtcd error: months_on_station out of range in tide record\n");
 
 5883      if (!check_date(rec->last_date_on_station)) {
 
 5884        LOG_ERROR(
"libtcd error: bad last_date_on_station in tide record\n");
 
 5888      if (rec->confidence > 15) {
 
 5889        LOG_ERROR(
"libtcd error: confidence out of range in tide record\n");
 
 5894      for (i = 0; i < hd.pub.constituents; ++i) {
 
 5895        if (rec->amplitude[i] < 0.0 || rec->amplitude[i] > 52.4287) {
 
 5897              "libtcd error: constituent amplitude out of range in tide " 
 5903      for (i = 0; i < hd.pub.constituents; ++i) {
 
 5904        if (rec->epoch[i] < 0.0 || rec->epoch[i] > 360.0) {
 
 5906              "libtcd error: constituent epoch out of range in tide record\n");
 
 5914    case SUBORDINATE_STATION:
 
 5915      if (rec->header.reference_station < 0 ||
 
 5916          rec->header.reference_station >= (NV_INT32)hd.pub.number_of_records) {
 
 5917        LOG_ERROR(
"libtcd error: bad reference_station in tide record\n");
 
 5921      if (rec->min_time_add < -4096 || rec->min_time_add > 4095 ||
 
 5922          rec->min_time_add % 100 >= 60) {
 
 5923        LOG_ERROR(
"libtcd error: bad min_time_add in tide record\n");
 
 5927      if (rec->min_level_add < -65.536 || rec->min_level_add > 65.535) {
 
 5928        LOG_ERROR(
"libtcd error: min_level_add out of range in tide record\n");
 
 5932      if (rec->min_level_multiply < 0.0 || rec->min_level_multiply > 65.535) {
 
 5934            "libtcd error: min_level_multiply out of range in tide record\n");
 
 5938      if (rec->max_time_add < -4096 || rec->max_time_add > 4095 ||
 
 5939          rec->max_time_add % 100 >= 60) {
 
 5940        LOG_ERROR(
"libtcd error: bad max_time_add in tide record\n");
 
 5944      if (rec->max_level_add < -65.536 || rec->max_level_add > 65.535) {
 
 5945        LOG_ERROR(
"libtcd error: max_level_add out of range in tide record\n");
 
 5949      if (rec->max_level_multiply < 0.0 || rec->max_level_multiply > 65.535) {
 
 5951            "libtcd error: max_level_multiply out of range in tide record\n");
 
 5955      if (rec->flood_begins != NULLSLACKOFFSET &&
 
 5956          (rec->flood_begins < -4096 || rec->flood_begins > 4095 ||
 
 5957           rec->flood_begins % 100 >= 60)) {
 
 5958        LOG_ERROR(
"libtcd error: bad flood_begins in tide record\n");
 
 5962      if (rec->ebb_begins != NULLSLACKOFFSET &&
 
 5963          (rec->ebb_begins < -4096 || rec->ebb_begins > 4095 ||
 
 5964           rec->ebb_begins % 100 >= 60)) {
 
 5965        LOG_ERROR(
"libtcd error: bad ebb_begins in tide record\n");
 
 5972      LOG_ERROR(
"libtcd error: invalid record_type in tide record\n");
 
 5976  if (ret == NVFalse) dump_tide_record(rec);
 
 5987  NV_U_INT32 i, count = 0, name_size, source_size, comments_size, notes_size,
 
 5988                station_id_context_size, station_id_size, xfields_size;
 
 5994  name_size = strlen(clip_string(rec->header.name)) + 1;
 
 5995  source_size = strlen(clip_string(rec->source)) + 1;
 
 5996  comments_size = strlen(clip_string(rec->comments)) + 1;
 
 5997  notes_size = strlen(clip_string(rec->notes)) + 1;
 
 5998  station_id_context_size = strlen(clip_string(rec->station_id_context)) + 1;
 
 5999  station_id_size = strlen(clip_string(rec->station_id)) + 1;
 
 6001  xfields_size = strlen(rec->xfields) + 1;
 
 6003  rec->header.record_size =
 
 6004      hd.record_size_bits + hd.record_type_bits + hd.latitude_bits +
 
 6005      hd.longitude_bits + hd.station_bits + hd.tzfile_bits + (name_size * 8) +
 
 6007      hd.country_bits + (source_size * 8) + hd.restriction_bits +
 
 6008      (comments_size * 8) + (notes_size * 8) + hd.legalese_bits +
 
 6009      (station_id_context_size * 8) + (station_id_size * 8) + hd.date_bits +
 
 6010      (xfields_size * 8) + hd.dir_unit_bits + hd.direction_bits +
 
 6011      hd.direction_bits + hd.level_unit_bits;
 
 6013  switch (rec->header.record_type) {
 
 6014    case REFERENCE_STATION:
 
 6015      rec->header.record_size += hd.datum_offset_bits + hd.datum_bits +
 
 6016                                 hd.time_bits + hd.date_bits +
 
 6017                                 hd.months_on_station_bits + hd.date_bits +
 
 6018                                 hd.confidence_value_bits + hd.constituent_bits;
 
 6020      for (i = 0; i < hd.pub.constituents; ++i) {
 
 6021        assert(rec->amplitude[i] >= 0.0);
 
 6022        if (rec->amplitude[i] >= AMPLITUDE_EPSILON) ++count;
 
 6025      rec->header.record_size +=
 
 6026          (count * hd.constituent_bits + count * hd.amplitude_bits +
 
 6027           count * hd.epoch_bits);
 
 6031    case SUBORDINATE_STATION:
 
 6032      rec->header.record_size += hd.time_bits + hd.level_add_bits +
 
 6033                                 hd.level_multiply_bits + hd.time_bits +
 
 6034                                 hd.level_add_bits + hd.level_multiply_bits +
 
 6035                                 hd.time_bits + hd.time_bits;
 
 6042  rec->header.record_size = bits2bytes(rec->header.record_size);
 
 6049static void pack_string(NV_U_BYTE *buf, NV_U_INT32 *pos, NV_CHAR *s) {
 
 6050  NV_U_INT32 i, temp_size;
 
 6054  temp_size = strlen(s) + 1;
 
 6055  for (i = 0; i < temp_size; ++i) {
 
 6056    bit_pack(buf, *pos, 8, s[i]);
 
 6081static void pack_tide_record(
TIDE_RECORD *rec, NV_U_BYTE **bufptr,
 
 6082                             NV_U_INT32 *bufsize) {
 
 6083  NV_U_INT32 i, pos, constituent_count;
 
 6092  boundscheck_oneliner(rec->header.name);
 
 6093  boundscheck_oneliner(rec->source);
 
 6094  boundscheck_monologue(rec->comments);
 
 6095  boundscheck_monologue(rec->notes);
 
 6096  boundscheck_oneliner(rec->station_id_context);
 
 6097  boundscheck_oneliner(rec->station_id);
 
 6098  boundscheck_monologue(rec->xfields);
 
 6100  constituent_count = figure_size(rec);
 
 6103            (NV_U_BYTE *)calloc(rec->header.record_size, 
sizeof(NV_U_BYTE)))) {
 
 6104    perror(
"libtcd can't allocate memory in pack_tide_record");
 
 6114  bit_pack(buf, pos, hd.record_size_bits, rec->header.record_size);
 
 6115  pos += hd.record_size_bits;
 
 6117  bit_pack(buf, pos, hd.record_type_bits, rec->header.record_type);
 
 6118  pos += hd.record_type_bits;
 
 6120  temp_int = NINT(rec->header.latitude * hd.latitude_scale);
 
 6121  bit_pack(buf, pos, hd.latitude_bits, temp_int);
 
 6122  pos += hd.latitude_bits;
 
 6124  temp_int = NINT(rec->header.longitude * hd.longitude_scale);
 
 6125  bit_pack(buf, pos, hd.longitude_bits, temp_int);
 
 6126  pos += hd.longitude_bits;
 
 6132  bit_pack(buf, pos, hd.tzfile_bits, rec->header.tzfile);
 
 6133  pos += hd.tzfile_bits;
 
 6135  pack_string(buf, &pos, clip_string(rec->header.name));
 
 6137  bit_pack(buf, pos, hd.station_bits, rec->header.reference_station);
 
 6138  pos += hd.station_bits;
 
 6140  bit_pack(buf, pos, hd.country_bits, rec->country);
 
 6141  pos += hd.country_bits;
 
 6143  pack_string(buf, &pos, clip_string(rec->source));
 
 6145  bit_pack(buf, pos, hd.restriction_bits, rec->restriction);
 
 6146  pos += hd.restriction_bits;
 
 6148  pack_string(buf, &pos, clip_string(rec->comments));
 
 6149  pack_string(buf, &pos, clip_string(rec->notes));
 
 6151  bit_pack(buf, pos, hd.legalese_bits, rec->legalese);
 
 6152  pos += hd.legalese_bits;
 
 6154  pack_string(buf, &pos, clip_string(rec->station_id_context));
 
 6155  pack_string(buf, &pos, clip_string(rec->station_id));
 
 6157  bit_pack(buf, pos, hd.date_bits, rec->date_imported);
 
 6158  pos += hd.date_bits;
 
 6161  pack_string(buf, &pos, rec->xfields);
 
 6163  bit_pack(buf, pos, hd.dir_unit_bits, rec->direction_units);
 
 6164  pos += hd.dir_unit_bits;
 
 6166  bit_pack(buf, pos, hd.direction_bits, rec->min_direction);
 
 6167  pos += hd.direction_bits;
 
 6169  bit_pack(buf, pos, hd.direction_bits, rec->max_direction);
 
 6170  pos += hd.direction_bits;
 
 6173  bit_pack(buf, pos, hd.level_unit_bits, rec->level_units);
 
 6174  pos += hd.level_unit_bits;
 
 6178  if (rec->header.record_type == REFERENCE_STATION) {
 
 6179    temp_int = NINT(rec->datum_offset * hd.datum_offset_scale);
 
 6180    bit_pack(buf, pos, hd.datum_offset_bits, temp_int);
 
 6181    pos += hd.datum_offset_bits;
 
 6183    bit_pack(buf, pos, hd.datum_bits, rec->datum);
 
 6184    pos += hd.datum_bits;
 
 6186    bit_pack(buf, pos, hd.time_bits, rec->zone_offset);
 
 6187    pos += hd.time_bits;
 
 6189    bit_pack(buf, pos, hd.date_bits, rec->expiration_date);
 
 6190    pos += hd.date_bits;
 
 6192    bit_pack(buf, pos, hd.months_on_station_bits, rec->months_on_station);
 
 6193    pos += hd.months_on_station_bits;
 
 6195    bit_pack(buf, pos, hd.date_bits, rec->last_date_on_station);
 
 6196    pos += hd.date_bits;
 
 6198    bit_pack(buf, pos, hd.confidence_value_bits, rec->confidence);
 
 6199    pos += hd.confidence_value_bits;
 
 6201    bit_pack(buf, pos, hd.constituent_bits, constituent_count);
 
 6202    pos += hd.constituent_bits;
 
 6204    for (i = 0; i < hd.pub.constituents; ++i) {
 
 6205      if (rec->amplitude[i] >= AMPLITUDE_EPSILON) {
 
 6206        bit_pack(buf, pos, hd.constituent_bits, i);
 
 6207        pos += hd.constituent_bits;
 
 6209        temp_int = NINT(rec->amplitude[i] * hd.amplitude_scale);
 
 6211        bit_pack(buf, pos, hd.amplitude_bits, temp_int);
 
 6212        pos += hd.amplitude_bits;
 
 6214        temp_int = NINT(rec->epoch[i] * hd.epoch_scale);
 
 6215        bit_pack(buf, pos, hd.epoch_bits, temp_int);
 
 6216        pos += hd.epoch_bits;
 
 6222  else if (rec->header.record_type == SUBORDINATE_STATION) {
 
 6223    bit_pack(buf, pos, hd.time_bits, rec->min_time_add);
 
 6224    pos += hd.time_bits;
 
 6226    temp_int = NINT(rec->min_level_add * hd.level_add_scale);
 
 6227    bit_pack(buf, pos, hd.level_add_bits, temp_int);
 
 6228    pos += hd.level_add_bits;
 
 6230    temp_int = NINT(rec->min_level_multiply * hd.level_multiply_scale);
 
 6231    bit_pack(buf, pos, hd.level_multiply_bits, temp_int);
 
 6232    pos += hd.level_multiply_bits;
 
 6234    bit_pack(buf, pos, hd.time_bits, rec->max_time_add);
 
 6235    pos += hd.time_bits;
 
 6237    temp_int = NINT(rec->max_level_add * hd.level_add_scale);
 
 6238    bit_pack(buf, pos, hd.level_add_bits, temp_int);
 
 6239    pos += hd.level_add_bits;
 
 6241    temp_int = NINT(rec->max_level_multiply * hd.level_multiply_scale);
 
 6242    bit_pack(buf, pos, hd.level_multiply_bits, temp_int);
 
 6243    pos += hd.level_multiply_bits;
 
 6245    bit_pack(buf, pos, hd.time_bits, rec->flood_begins);
 
 6246    pos += hd.time_bits;
 
 6248    bit_pack(buf, pos, hd.time_bits, rec->ebb_begins);
 
 6249    pos += hd.time_bits;
 
 6253    LOG_ERROR(
"libtcd error:  Record type %d is undefined\n",
 
 6254              rec->header.record_type);
 
 6258  *bufsize = rec->header.record_size;
 
 6259  assert(*bufsize == bits2bytes(pos));
 
 6284static NV_BOOL write_tide_record(NV_INT32 num, 
TIDE_RECORD *rec) {
 
 6285  NV_U_BYTE *buf = NULL;
 
 6286  NV_U_INT32 bufsize = 0;
 
 6290        "libtcd error: attempt to access database when database not open\n");
 
 6295  pack_tide_record(rec, &buf, &bufsize);
 
 6300    fseek(fp, tindex[num].address, SEEK_SET);
 
 6304  chk_fwrite(buf, bufsize, 1, fp);
 
 6329  return (read_tide_record(current_record + 1, rec));
 
 6353static void unpack_tide_record(NV_U_BYTE *buf, NV_U_INT32 bufsize,
 
 6356  NV_U_INT32 i, j, pos, count;
 
 6363    int r = find_dir_units(
"degrees true");
 
 6365    rec->direction_units = (NV_U_BYTE)r;
 
 6367  rec->min_direction = rec->max_direction = 361;
 
 6368  rec->flood_begins = rec->ebb_begins = NULLSLACKOFFSET;
 
 6369  rec->header.record_number = current_record;
 
 6371  unpack_partial_tide_record(buf, bufsize, rec, &pos);
 
 6373  switch (rec->header.record_type) {
 
 6374    case REFERENCE_STATION:
 
 6375    case SUBORDINATE_STATION:
 
 6378      LOG_ERROR(
"libtcd fatal error: tried to read type %d tide record.\n",
 
 6379                rec->header.record_type);
 
 6381          "This version of libtcd only supports types 1 and 2.  Perhaps you " 
 6382          "should\nupgrade.\n");
 
 6386  switch (hd.pub.major_rev) {
 
 6393      rec->country = bit_unpack(buf, pos, hd.country_bits);
 
 6394      pos += hd.country_bits;
 
 6397      pos += hd.pedigree_bits;
 
 6399      unpack_string(buf, bufsize, &pos, rec->source, ONELINER_LENGTH,
 
 6402      rec->restriction = bit_unpack(buf, pos, hd.restriction_bits);
 
 6403      pos += hd.restriction_bits;
 
 6405      unpack_string(buf, bufsize, &pos, rec->comments, MONOLOGUE_LENGTH,
 
 6408      if (rec->header.record_type == REFERENCE_STATION) {
 
 6409        rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
 
 6411        rec->units = rec->level_units;
 
 6413        pos += hd.level_unit_bits;
 
 6415        temp_int = signed_bit_unpack(buf, pos, hd.datum_offset_bits);
 
 6416        rec->datum_offset = (NV_FLOAT32)temp_int / hd.datum_offset_scale;
 
 6417        pos += hd.datum_offset_bits;
 
 6419        rec->datum = bit_unpack(buf, pos, hd.datum_bits);
 
 6420        pos += hd.datum_bits;
 
 6422        rec->zone_offset = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6423        pos += hd.time_bits;
 
 6425        rec->expiration_date = bit_unpack(buf, pos, hd.date_bits);
 
 6426        pos += hd.date_bits;
 
 6428        rec->months_on_station =
 
 6429            bit_unpack(buf, pos, hd.months_on_station_bits);
 
 6430        pos += hd.months_on_station_bits;
 
 6432        rec->last_date_on_station = bit_unpack(buf, pos, hd.date_bits);
 
 6433        pos += hd.date_bits;
 
 6435        rec->confidence = bit_unpack(buf, pos, hd.confidence_value_bits);
 
 6436        pos += hd.confidence_value_bits;
 
 6438        for (i = 0; i < hd.pub.constituents; ++i) {
 
 6439          rec->amplitude[i] = 0.0;
 
 6440          rec->epoch[i] = 0.0;
 
 6443        count = bit_unpack(buf, pos, hd.constituent_bits);
 
 6444        pos += hd.constituent_bits;
 
 6446        for (i = 0; i < count; ++i) {
 
 6447          j = bit_unpack(buf, pos, hd.constituent_bits);
 
 6448          pos += hd.constituent_bits;
 
 6451              (NV_FLOAT32)bit_unpack(buf, pos, hd.amplitude_bits) /
 
 6453          pos += hd.amplitude_bits;
 
 6456              (NV_FLOAT32)bit_unpack(buf, pos, hd.epoch_bits) / hd.epoch_scale;
 
 6457          pos += hd.epoch_bits;
 
 6459      } 
else if (rec->header.record_type == SUBORDINATE_STATION) {
 
 6460        rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
 
 6461        pos += hd.level_unit_bits;
 
 6463        rec->direction_units = bit_unpack(buf, pos, hd.dir_unit_bits);
 
 6464        pos += hd.dir_unit_bits;
 
 6467        pos += hd.level_unit_bits;
 
 6469        rec->min_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6470        pos += hd.time_bits;
 
 6472        temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
 
 6473        rec->min_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
 
 6474        pos += hd.level_add_bits;
 
 6477        temp_int = signed_bit_unpack(buf, pos, hd.level_multiply_bits);
 
 6478        rec->min_level_multiply =
 
 6479            (NV_FLOAT32)temp_int / hd.level_multiply_scale;
 
 6480        pos += hd.level_multiply_bits;
 
 6483        pos += hd.level_add_bits;
 
 6485        rec->min_direction = bit_unpack(buf, pos, hd.direction_bits);
 
 6486        pos += hd.direction_bits;
 
 6488        rec->max_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6489        pos += hd.time_bits;
 
 6491        temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
 
 6492        rec->max_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
 
 6493        pos += hd.level_add_bits;
 
 6496        temp_int = signed_bit_unpack(buf, pos, hd.level_multiply_bits);
 
 6497        rec->max_level_multiply =
 
 6498            (NV_FLOAT32)temp_int / hd.level_multiply_scale;
 
 6499        pos += hd.level_multiply_bits;
 
 6502        pos += hd.level_add_bits;
 
 6504        rec->max_direction = bit_unpack(buf, pos, hd.direction_bits);
 
 6505        pos += hd.direction_bits;
 
 6507        rec->flood_begins = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6508        pos += hd.time_bits;
 
 6510        rec->ebb_begins = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6511        pos += hd.time_bits;
 
 6519      rec->country = bit_unpack(buf, pos, hd.country_bits);
 
 6520      pos += hd.country_bits;
 
 6522      unpack_string(buf, bufsize, &pos, rec->source, ONELINER_LENGTH,
 
 6525      rec->restriction = bit_unpack(buf, pos, hd.restriction_bits);
 
 6526      pos += hd.restriction_bits;
 
 6528      unpack_string(buf, bufsize, &pos, rec->comments, MONOLOGUE_LENGTH,
 
 6530      unpack_string(buf, bufsize, &pos, rec->notes, MONOLOGUE_LENGTH,
 
 6533      rec->legalese = bit_unpack(buf, pos, hd.legalese_bits);
 
 6534      pos += hd.legalese_bits;
 
 6536      unpack_string(buf, bufsize, &pos, rec->station_id_context,
 
 6537                    ONELINER_LENGTH, 
"station_id_context field");
 
 6538      unpack_string(buf, bufsize, &pos, rec->station_id, ONELINER_LENGTH,
 
 6539                    "station_id field");
 
 6541      rec->date_imported = bit_unpack(buf, pos, hd.date_bits);
 
 6542      pos += hd.date_bits;
 
 6544      unpack_string(buf, bufsize, &pos, rec->xfields, MONOLOGUE_LENGTH,
 
 6547      rec->direction_units = bit_unpack(buf, pos, hd.dir_unit_bits);
 
 6548      pos += hd.dir_unit_bits;
 
 6550      rec->min_direction = bit_unpack(buf, pos, hd.direction_bits);
 
 6551      pos += hd.direction_bits;
 
 6553      rec->max_direction = bit_unpack(buf, pos, hd.direction_bits);
 
 6554      pos += hd.direction_bits;
 
 6556      rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
 
 6558      rec->units = rec->level_units;
 
 6560      pos += hd.level_unit_bits;
 
 6562      if (rec->header.record_type == REFERENCE_STATION) {
 
 6563        temp_int = signed_bit_unpack(buf, pos, hd.datum_offset_bits);
 
 6564        rec->datum_offset = (NV_FLOAT32)temp_int / hd.datum_offset_scale;
 
 6565        pos += hd.datum_offset_bits;
 
 6567        rec->datum = bit_unpack(buf, pos, hd.datum_bits);
 
 6568        pos += hd.datum_bits;
 
 6570        rec->zone_offset = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6571        pos += hd.time_bits;
 
 6573        rec->expiration_date = bit_unpack(buf, pos, hd.date_bits);
 
 6574        pos += hd.date_bits;
 
 6576        rec->months_on_station =
 
 6577            bit_unpack(buf, pos, hd.months_on_station_bits);
 
 6578        pos += hd.months_on_station_bits;
 
 6580        rec->last_date_on_station = bit_unpack(buf, pos, hd.date_bits);
 
 6581        pos += hd.date_bits;
 
 6583        rec->confidence = bit_unpack(buf, pos, hd.confidence_value_bits);
 
 6584        pos += hd.confidence_value_bits;
 
 6586        for (i = 0; i < hd.pub.constituents; ++i) {
 
 6587          rec->amplitude[i] = 0.0;
 
 6588          rec->epoch[i] = 0.0;
 
 6591        count = bit_unpack(buf, pos, hd.constituent_bits);
 
 6592        pos += hd.constituent_bits;
 
 6594        for (i = 0; i < count; ++i) {
 
 6595          j = bit_unpack(buf, pos, hd.constituent_bits);
 
 6596          pos += hd.constituent_bits;
 
 6599              (NV_FLOAT32)bit_unpack(buf, pos, hd.amplitude_bits) /
 
 6601          pos += hd.amplitude_bits;
 
 6604              (NV_FLOAT32)bit_unpack(buf, pos, hd.epoch_bits) / hd.epoch_scale;
 
 6605          pos += hd.epoch_bits;
 
 6607      } 
else if (rec->header.record_type == SUBORDINATE_STATION) {
 
 6608        rec->min_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6609        pos += hd.time_bits;
 
 6611        temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
 
 6612        rec->min_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
 
 6613        pos += hd.level_add_bits;
 
 6616        temp_int = bit_unpack(buf, pos, hd.level_multiply_bits);
 
 6617        rec->min_level_multiply =
 
 6618            (NV_FLOAT32)temp_int / hd.level_multiply_scale;
 
 6619        pos += hd.level_multiply_bits;
 
 6621        rec->max_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6622        pos += hd.time_bits;
 
 6624        temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
 
 6625        rec->max_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
 
 6626        pos += hd.level_add_bits;
 
 6629        temp_int = bit_unpack(buf, pos, hd.level_multiply_bits);
 
 6630        rec->max_level_multiply =
 
 6631            (NV_FLOAT32)temp_int / hd.level_multiply_scale;
 
 6632        pos += hd.level_multiply_bits;
 
 6634        rec->flood_begins = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6635        pos += hd.time_bits;
 
 6637        rec->ebb_begins = signed_bit_unpack(buf, pos, hd.time_bits);
 
 6638        pos += hd.time_bits;
 
 6648  assert(pos <= bufsize * 8);
 
 6672NV_INT32 read_tide_record(NV_INT32 num, 
TIDE_RECORD *rec) {
 
 6678        "libtcd error: attempt to access database when database not open\n");
 
 6682  if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records) 
return -1;
 
 6685  bufsize = tindex[num].record_size;
 
 6686  if ((buf = (NV_U_BYTE *)calloc(bufsize, 
sizeof(NV_U_BYTE))) == NULL) {
 
 6687    perror(
"Allocating read_tide_record buffer");
 
 6691  current_record = num;
 
 6692  require(fseek(fp, tindex[num].address, SEEK_SET) == 0);
 
 6693  chk_fread(buf, tindex[num].record_size, 1, fp);
 
 6694  unpack_tide_record(buf, bufsize, rec);
 
 6721        "libtcd error: attempt to access database when database not open\n");
 
 6726  if (!check_tide_record(rec)) 
return NVFalse;
 
 6728  fseek(fp, hd.end_of_file, SEEK_SET);
 
 6732  rec->header.record_number = hd.pub.number_of_records++;
 
 6734  if (write_tide_record(-1, rec)) {
 
 6736             tindex, hd.pub.number_of_records * 
sizeof(
TIDE_INDEX))) == NULL) {
 
 6737      perror(
"Allocating more index records");
 
 6741    tindex[rec->header.record_number].address = pos;
 
 6742    tindex[rec->header.record_number].record_size = rec->header.record_size;
 
 6743    tindex[rec->header.record_number].record_type = rec->header.record_type;
 
 6744    tindex[rec->header.record_number].reference_station =
 
 6745        rec->header.reference_station;
 
 6746    assert(rec->header.tzfile >= 0);
 
 6747    tindex[rec->header.record_number].tzfile = rec->header.tzfile;
 
 6748    tindex[rec->header.record_number].lat =
 
 6749        NINT(rec->header.latitude * hd.latitude_scale);
 
 6750    tindex[rec->header.record_number].lon =
 
 6751        NINT(rec->header.longitude * hd.longitude_scale);
 
 6753    if ((tindex[rec->header.record_number].name = (NV_CHAR *)calloc(
 
 6754             strlen(rec->header.name) + 1, 
sizeof(NV_CHAR))) == NULL) {
 
 6755      perror(
"Allocating index name memory");
 
 6759    strcpy(tindex[rec->header.record_number].name, rec->header.name);
 
 6762    hd.end_of_file = pos;
 
 6766    if (db) *db = hd.pub;
 
 6795    NV_INT32          i, newrecnum, *map;
 
 6796    NV_U_BYTE         **allrecs_packed;
 
 6799        LOG_ERROR (
"libtcd error: attempt to access database when database not open\n");
 
 6804    if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records) 
return NVFalse;
 
 6808    if (!(map = (NV_INT32 *) malloc (hd.pub.number_of_records * 
sizeof(NV_INT32)))) {
 
 6809        perror (
"libtcd: delete_tide_record: can't malloc");
 
 6812    if (!(allrecs_packed = (NV_U_BYTE **) malloc (hd.pub.number_of_records * 
sizeof(NV_U_BYTE*)))) {
 
 6813        perror (
"libtcd: delete_tide_record: can't malloc");
 
 6821    require (fseek (fp, tindex[0].address, SEEK_SET) == 0);
 
 6822    for (newrecnum=0,i=0; i<(NV_INT32)hd.pub.number_of_records; ++i) {
 
 6823        assert (ftell(fp) == tindex[i].address);
 
 6824        if (i == num || (tindex[i].record_type == SUBORDINATE_STATION && tindex[i].reference_station == num)) {
 
 6826            allrecs_packed[i] = NULL;
 
 6827            require (fseek (fp, tindex[i].record_size, SEEK_CUR) == 0);
 
 6829            map[i] = newrecnum++;
 
 6830            if (!(allrecs_packed[i] = (NV_U_BYTE *) malloc (tindex[i].record_size))) {
 
 6831                perror (
"libtcd: delete_tide_record: can't malloc");
 
 6832                for (--i; i>=0; --i)
 
 6833                    free (allrecs_packed[i]);
 
 6834                free (allrecs_packed);
 
 6838            chk_fread (allrecs_packed[i], tindex[i].record_size, 1, fp);
 
 6844    require (fseek (fp, tindex[0].address, SEEK_SET) == 0);
 
 6845    require (ftruncate (fileno(fp), tindex[0].address) == 0);
 
 6847    for (i=0; i<(NV_INT32)hd.pub.number_of_records; ++i)
 
 6849            if (tindex[i].record_type == SUBORDINATE_STATION) {
 
 6850                assert (tindex[i].reference_station >= 0);
 
 6851                assert (tindex[i].reference_station <= (NV_INT32)hd.pub.number_of_records);
 
 6852                if (map[tindex[i].reference_station] != tindex[i].reference_station) {
 
 6855                    unpack_tide_record (allrecs_packed[i], tindex[i].record_size, &rec);
 
 6856                    free (allrecs_packed[i]);
 
 6857                    rec.header.reference_station = map[tindex[i].reference_station];
 
 6858                    pack_tide_record (&rec, &(allrecs_packed[i]), &(tindex[i].record_size));
 
 6861            chk_fwrite (allrecs_packed[i], tindex[i].record_size, 1, fp);
 
 6862            free (allrecs_packed[i]);
 
 6867    free (allrecs_packed);
 
 6873    hd.end_of_file = ftell(fp);
 
 6874    hd.pub.number_of_records = newrecnum;
 
 6877    open_tide_db (filename);
 
 6906NV_BOOL update_tide_record(NV_INT32 num, 
TIDE_RECORD *rec)
 
 6913  NV_U_BYTE *
block = NULL;
 
 6917        "libtcd error: attempt to access database when database not open\n");
 
 6922  if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records) 
return NVFalse;
 
 6924  if (!check_tide_record(rec)) 
return NVFalse;
 
 6927  read_tide_record(num, &tmp_rec);
 
 6928  if (rec->header.record_size != tmp_rec.header.record_size) {
 
 6936    size = hd.end_of_file - pos;
 
 6941      if ((
block = (NV_U_BYTE *)calloc(size, 
sizeof(NV_U_BYTE))) == NULL) {
 
 6942        perror(
"Allocating block");
 
 6945      chk_fread(
block, size, 1, fp);
 
 6949    write_tide_record(num, rec);
 
 6953      chk_fwrite(
block, size, 1, fp);
 
 6957    hd.end_of_file = ftell(fp);
 
 6961    open_tide_db(filename);
 
 6966    write_tide_record(num, rec);
 
 6969    tindex[num].record_size = rec->header.record_size;
 
 6970    tindex[num].record_type = rec->header.record_type;
 
 6971    tindex[num].reference_station = rec->header.reference_station;
 
 6972    tindex[num].tzfile = rec->header.tzfile;
 
 6973    tindex[num].lat = NINT(rec->header.latitude * hd.latitude_scale);
 
 6974    tindex[num].lon = NINT(rec->header.longitude * hd.longitude_scale);
 
 6979    if (strcmp(tindex[num].name, rec->header.name) != 0) {
 
 6980      free(tindex[num].name);
 
 6982          (NV_CHAR *)calloc(strlen(rec->header.name) + 1, 
sizeof(NV_CHAR));
 
 6983      strcpy(tindex[num].name, rec->header.name);
 
 6988  if (db) *db = hd.pub;
 
 7025  NV_INT32 m2, s2, k1, o1;
 
 7026  NV_FLOAT32 epoch_m2, epoch_s2, epoch_k1, epoch_o1;
 
 7029  require((m2 = find_constituent(
"M2")) >= 0);
 
 7030  require((s2 = find_constituent(
"S2")) >= 0);
 
 7031  require((k1 = find_constituent(
"K1")) >= 0);
 
 7032  require((o1 = find_constituent(
"O1")) >= 0);
 
 7034  if (rec->amplitude[m2] == 0.0 || rec->amplitude[s2] == 0.0 ||
 
 7035      rec->amplitude[k1] == 0.0 || rec->amplitude[o1] == 0.0)
 
 7038  epoch_m2 = rec->epoch[m2];
 
 7039  epoch_s2 = rec->epoch[s2];
 
 7040  epoch_k1 = rec->epoch[k1];
 
 7041  epoch_o1 = rec->epoch[o1];
 
 7043  for (i = 0; i < hd.pub.constituents; ++i) {
 
 7044    if (rec->amplitude[i] == 0.0 && rec->epoch[i] == 0.0) {
 
 7045      for (j = 0; j < INFERRED_SEMI_DIURNAL_COUNT; ++j) {
 
 7046        if (!strcmp(inferred_semi_diurnal[j], get_constituent(i))) {
 
 7050              (semi_diurnal_coeff[j] / coeff[0]) * rec->amplitude[m2];
 
 7052          if (fabs((NV_FLOAT64)(epoch_s2 - epoch_m2)) > 180.0) {
 
 7053            if (epoch_s2 < epoch_m2) {
 
 7059          rec->epoch[i] = epoch_m2 + ((hd.speed[i] - hd.speed[m2]) /
 
 7060                                      (hd.speed[s2] - hd.speed[m2])) *
 
 7061                                         (epoch_s2 - epoch_m2);
 
 7065      for (j = 0; j < INFERRED_DIURNAL_COUNT; ++j) {
 
 7066        if (!strcmp(inferred_diurnal[j], get_constituent(i))) {
 
 7070              (diurnal_coeff[j] / coeff[1]) * rec->amplitude[o1];
 
 7072          if (fabs((NV_FLOAT64)(epoch_k1 - epoch_o1)) > 180.0) {
 
 7073            if (epoch_k1 < epoch_o1) {
 
 7079          rec->epoch[i] = epoch_o1 + ((hd.speed[i] - hd.speed[o1]) /
 
 7080                                      (hd.speed[k1] - hd.speed[o1])) *
 
 7081                                         (epoch_k1 - epoch_o1);
 
 7096static NV_U_BYTE mask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe},
 
 7097                 notmask[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
 
 7136NV_U_INT32 calculate_bits(NV_U_INT32 value) {
 
 7137  NV_U_INT32 bits = 32;
 
 7138  NV_U_INT32 theBit = 0x80000000;
 
 7140  while (value < theBit) {
 
 7175void bit_pack(NV_U_BYTE buffer[], NV_U_INT32 start, NV_U_INT32 numbits,
 
 7177  NV_INT32 start_byte, end_byte, start_bit, end_bit, i;
 
 7179  i = start + numbits;
 
 7185  start_byte = start >> 3;
 
 7192  start_bit = start & 7;
 
 7197  i = end_byte - start_byte - 1;
 
 7201  if (start_byte == end_byte) {
 
 7206    buffer[start_byte] &= mask[start_bit] | notmask[end_bit];
 
 7212    buffer[start_byte] |=
 
 7213        (value << (8 - end_bit)) & (notmask[start_bit] & mask[end_bit]);
 
 7221    buffer[start_byte] &= mask[start_bit];
 
 7229    buffer[start_byte++] |=
 
 7230        (value >> (numbits - (8 - start_bit))) & notmask[start_bit];
 
 7237      buffer[start_byte] &= 0;
 
 7241      buffer[start_byte++] |= (value >> ((i << 3) + end_bit)) & 255;
 
 7246    buffer[start_byte] &= notmask[end_bit];
 
 7252    buffer[start_byte] |= (value << (8 - end_bit));
 
 7282NV_U_INT32 bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
 
 7283                      NV_U_INT32 numbits) {
 
 7284  NV_INT32 start_byte, end_byte, start_bit, end_bit, i;
 
 7287  i = start + numbits;
 
 7293  start_byte = start >> 3;
 
 7300  start_bit = start & 7;
 
 7305  i = end_byte - start_byte - 1;
 
 7309  if (start_byte == end_byte) {
 
 7313        (NV_U_INT32)buffer[start_byte] & (notmask[start_bit] & mask[end_bit]);
 
 7317    value >>= (8 - end_bit);
 
 7326    value = (NV_U_INT32)(buffer[start_byte++] & notmask[start_bit])
 
 7327            << (numbits - (8 - start_bit));
 
 7334      value += (NV_U_INT32)buffer[start_byte++] << ((i << 3) + end_bit);
 
 7339    if (mask[end_bit]) {
 
 7341          (NV_U_INT32)(buffer[start_byte] & mask[end_bit]) >> (8 - end_bit);
 
 7374NV_INT32 signed_bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
 
 7375                           NV_U_INT32 numbits) {
 
 7376  static NV_INT32 extend_mask = 0x7fffffff;
 
 7380  assert(numbits > 0);
 
 7382  value = bit_unpack(buffer, start, numbits);
 
 7384  if (value & (1 << (numbits - 1))) value |= (extend_mask << numbits);
 
Represents an index entry for tidal and current data.
int have_offsets
Flag indicating presence of time/height offsets.
time_t epoch
Epoch time for the station.
int IDX_time_zone
Station timezone offset from UTC (in minutes)
char IDX_type
Entry type identifier "TCtcIUu".
int num_nodes
Number of nodes in harmonic analysis.
float IDX_lt_off
Low tide height offset.
TCDataSource * pDataSource
Pointer to the associated data source.
float IDX_lt_mpy
Low tide height multiplier.
int Valid15
Validity flag for 15-minute interval data.
time_t recent_high_time
Time of the most recent high tide.
int epoch_year
Year of the epoch.
int IDX_flood_dir
Flood current direction (in degrees)
int IDX_Useable
Flag indicating if the entry is usable.
char IDX_station_name[MAXNAMELEN]
Name of the tidal or current station.
float recent_low_level
Most recently calculated low tide level.
int station_tz_offset
Offset in seconds to convert from harmonic data (epochs) to the station time zone.
double max_amplitude
Maximum tidal amplitude.
int first_year
First year of valid data.
double * m_work_buffer
Work buffer for calculations.
int IDX_ht_time_off
High tide time offset (in minutes)
float Dir15
Direction for 15-minute interval data.
float recent_high_level
Most recently calculated high tide level.
double ** m_cst_nodes
2D array of constituent nodes
int IDX_ebb_dir
Ebb current direction (in degrees)
double ** m_cst_epochs
2D array of constituent epochs
float IDX_ht_mpy
High tide height multiplier.
int current_depth
Depth for current stations.
double IDX_lat
Latitude of the station (in degrees, +North)
double IDX_lon
Longitude of the station (in degrees, +East)
bool Ret15
Return flag for 15-minute interval data.
bool b_skipTooDeep
Flag to skip processing if depth exceeds limit.
int num_epochs
Number of epochs in harmonic data.
double * m_cst_speeds
Array of constituent speeds.
Station_Data * pref_sta_data
Pointer to the reference station data.
int IDX_lt_time_off
Low tide time offset (in minutes)
time_t recent_highlow_calc_time
Timestamp of the most recent high/low calculation.
int num_csts
Number of harmonic constituents.
time_t recent_low_time
Time of the most recent low tide.
float IDX_ht_off
High tide height offset.
int IDX_rec_num
Record number for multiple entries with same name.
float Value15
Value for 15-minute interval data.
General purpose GUI support.
Enhanced logging interface on top of wx/log.h.
std::string tolower(const std::string &input)
Return copy of s with all characters converted to lower case.
Runtime representation of a plugin block.