30#include <wx/datetime.h>
31#include <wx/hashmap.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)
68 return (mpy * pIDX->max_amplitude);
71 return (sqrt(mpy * pIDX->max_amplitude));
73 return (-sqrt(-mpy * pIDX->max_amplitude));
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++) {
166 if (pIDX->m_cst_speeds[a] < 6e-6) {
167 tide += pIDX->m_work_buffer[a] *
168 cos(pIDX->m_cst_speeds[a] * ((
long)(t - pIDX->epoch) +
169 pIDX->pref_sta_data->meridian) +
170 pIDX->m_cst_epochs[a][pIDX->epoch_year - pIDX->first_year] -
171 pIDX->pref_sta_data->epoch[a]);
182double time2asecondary(time_t t,
IDX_entry *pIDX) {
183 time_t tadj = t + pIDX->station_tz_offset;
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;
209 T = tadj - (pIDX->IDX_ht_time_off * 60 + pIDX->IDX_lt_time_off * 60) / 2;
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);
302 T = T - (time_t)(magicnum * ((pIDX->IDX_ht_time_off * 60) -
303 (pIDX->IDX_lt_time_off * 60)));
304 HI = time2tide(T, pIDX);
307 double ht_off, lt_off;
308 if (pIDX->pref_sta_data->have_BOGUS) {
309 ht_off = pIDX->IDX_ht_off *
311 lt_off = pIDX->IDX_lt_off * pIDX->IDX_lt_off;
313 ht_off = pIDX->IDX_ht_off;
314 lt_off = pIDX->IDX_lt_off;
318 HI = BOGUS_amplitude(HI, pIDX) + pIDX->pref_sta_data->DATUM;
320 double RH = 1.0, RL = 1.0, HH = 0.0, HL = 0.0;
321 RH = pIDX->IDX_ht_mpy;
323 RL = pIDX->IDX_lt_mpy;
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++) {
391 term = pIDX->m_work_buffer[a] *
393 pIDX->m_cst_speeds[a] *
394 ((
long)(t - pIDX->epoch) + pIDX->pref_sta_data->meridian) +
395 pIDX->m_cst_epochs[a][pIDX->epoch_year - pIDX->first_year] -
396 pIDX->pref_sta_data->epoch[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) {
497 if (new_year + 1 < pIDX->first_year + pIDX->num_epochs) {
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 &&
515 s_this_year + 1 < pIDX->first_year + pIDX->num_epochs)
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) {
532 if (pIDX->max_amplitude == 0.0) {
533 for (i = 0; i < pIDX->num_nodes; i++) {
534 double year_amp = 0.0;
536 for (a = 0; a < pIDX->num_csts; a++)
537 year_amp += pIDX->pref_sta_data->amplitude[a] * pIDX->m_cst_nodes[a][i];
538 if (year_amp > pIDX->max_amplitude) pIDX->max_amplitude = year_amp;
544void figure_multipliers(
IDX_entry *pIDX,
int year) {
547 figure_max_amplitude(pIDX);
548 for (a = 0; a < pIDX->num_csts; a++) {
549 pIDX->m_work_buffer[a] = pIDX->pref_sta_data->amplitude[a] *
550 pIDX->m_cst_nodes[a][year - pIDX->first_year] /
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) {
626 pIDX->epoch_year = new_year;
627 figure_multipliers(pIDX, new_year);
628 set_epoch(pIDX, new_year);
634TCMgr::~TCMgr() { PurgeData(); }
636void TCMgr::PurgeData() {
640 while (m_Combined_IDX_array.GetCount()) {
641 m_Combined_IDX_array.Detach(0);
645 m_source_array.Clear();
648TC_Error_Code TCMgr::LoadDataSources(wxArrayString &sources) {
652 m_sourcefile_array.Clear();
653 m_sourcefile_array = sources;
656 m_Combined_IDX_array.Add((
IDX_entry *)(NULL));
659 for (
unsigned int i = 0; i < sources.GetCount(); i++) {
661 TC_Error_Code r = s->LoadData(sources[i]);
662 if (r != TC_NO_ERROR) {
664 msg.Printf(_T(
" Error loading Tide/Currect data source %s "),
666 if (r == TC_FILE_NOT_FOUND)
667 msg += _T(
"Error Code: TC_FILE_NOT_FOUND");
670 msg1.Printf(_T(
"Error code: %d"), r);
676 m_source_array.Add(s);
678 for (
int k = 0; k < s->GetMaxIndex(); k++) {
680 pIDX->IDX_rec_num = num_IDX;
682 m_Combined_IDX_array.Add(pIDX);
689 if (m_Combined_IDX_array.Count() <= 1)
691 NULL, _(
"It seems you have no tide/current harmonic data installed."),
692 _(
"OpenCPN Info"), wxOK | wxCENTER);
694 ScrubCurrentDepths();
698void TCMgr::ScrubCurrentDepths() {
703 WX_DECLARE_STRING_HASH_MAP(
int, currentDepth_index_hash);
705 currentDepth_index_hash hash1;
707 for (
unsigned int i = 1; i < m_Combined_IDX_array.Count(); i++) {
710 if (a->IDX_type ==
'C') {
711 if (a->current_depth > 0) {
712 int depth_a = a->current_depth;
721 key1.Printf(
"%10.6f %10.6f", a->IDX_lat, a->IDX_lon);
723 currentDepth_index_hash::iterator it = hash1.find(key1);
724 if (it == hash1.end()) {
731 std::string bName(b->IDX_station_name);
732 int depth_b = b->current_depth;
733 if (depth_a < depth_b) {
735 b->b_skipTooDeep = 1;
737 a->b_skipTooDeep = 1;
745const IDX_entry *TCMgr::GetIDX_entry(
int index)
const {
746 if ((
unsigned int)index < m_Combined_IDX_array.GetCount())
747 return &m_Combined_IDX_array[index];
752bool TCMgr::GetTideOrCurrent(time_t t,
int idx,
float &tcvalue,
float &dir) {
758 IDX_entry *pIDX = &m_Combined_IDX_array[idx];
766 if (!pIDX->IDX_Useable) {
772 if (pIDX->pDataSource) {
773 if (pIDX->pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR)
return false;
776 pIDX->max_amplitude = 0.0;
777 int yott = yearoftimet(t);
779 happy_new_year(pIDX, yott);
783 double level = time2asecondary(t + (00 * 60), pIDX);
785 dir = pIDX->IDX_flood_dir;
787 dir = pIDX->IDX_ebb_dir;
794extern wxDateTime gTimeSource;
796bool TCMgr::GetTideOrCurrent15(time_t t_d,
int idx,
float &tcvalue,
float &dir,
799 IDX_entry *pIDX = &m_Combined_IDX_array[idx];
808 wxDateTime this_now = gTimeSource;
809 if (this_now.IsValid() ==
false) this_now = wxDateTime::Now();
810 wxDateTime this_gmt = this_now.ToGMT();
811 wxTimeSpan diff = this_gmt.Subtract(this_now);
812 int diff_mins = diff.GetMinutes();
814 int station_offset = pIDX->IDX_time_zone;
815 if (this_now.IsDST()) station_offset += 60;
816 int corr_mins = station_offset - diff_mins;
818 wxDateTime today_00 = this_now;
819 today_00.ResetTime();
820 int t_today_00 = today_00.GetTicks();
821 int t_today_00_at_station = t_today_00 - (corr_mins * 60);
824 this_gmt.GetTicks() - (station_offset * 60) + (corr_mins * 60);
826 int t_mins = (t_at_station - t_today_00_at_station) / 60;
827 int t_15s = t_mins / 15;
831 int tref1 = t_today_00_at_station + t_15s * 15 * 60;
832 if (tref1 == pIDX->Valid15) {
833 tcvalue = pIDX->Value15;
838 int tref = t_today_00_at_station + t_15s * 15 * 60;
839 ret = GetTideOrCurrent(tref, idx, tcvalue, dir);
841 pIDX->Valid15 = tref;
842 pIDX->Value15 = tcvalue;
844 pIDX->Ret15 = !(ret == 0);
852 int tref = t_today_00_at_station + t_15s * 15 * 60;
853 ret = GetTideOrCurrent(tref, idx, tcvalue, dir);
855 pIDX->Valid15 = tref;
856 pIDX->Value15 = tcvalue;
858 pIDX->Ret15 = !(ret == 0);
865bool TCMgr::GetTideFlowSens(time_t t,
int sch_step,
int idx,
float &tcvalue_now,
866 float &tcvalue_prev,
bool &w_t) {
873 IDX_entry *pIDX = &m_Combined_IDX_array[idx];
875 if (!pIDX)
return false;
877 if (!pIDX->IDX_Useable)
return false;
879 if (pIDX->pDataSource) {
880 if (pIDX->pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR)
return false;
883 pIDX->max_amplitude = 0.0;
884 int yott = yearoftimet(t);
885 happy_new_year(pIDX, yott);
889 tcvalue_now = time2asecondary(t, pIDX);
890 tcvalue_prev = time2asecondary(t + sch_step, pIDX);
893 tcvalue_now > tcvalue_prev;
898void TCMgr::GetHightOrLowTide(time_t t,
int sch_step_1,
int sch_step_2,
899 float tide_val,
bool w_t,
int idx,
float &tcvalue,
906 IDX_entry *pIDX = &m_Combined_IDX_array[idx];
910 if (!pIDX->IDX_Useable)
return;
912 if (pIDX->pDataSource) {
913 if (pIDX->pDataSource->LoadHarmonicData(pIDX) != TC_NO_ERROR)
return;
917 if (abs(t - pIDX->recent_highlow_calc_time) < 60) {
919 tcvalue = pIDX->recent_high_level;
920 tctime = pIDX->recent_high_time;
922 tcvalue = pIDX->recent_low_level;
923 tctime = pIDX->recent_low_time;
928 pIDX->max_amplitude = 0.0;
929 int yott = yearoftimet(t);
930 happy_new_year(pIDX, yott);
933 double newval = tide_val;
934 double oldval = (w_t) ? newval - 1 : newval + 1;
938 while ((newval > oldval) == w_t)
942 ttt = t + (sch_step_1 * j);
943 newval = time2asecondary(ttt, pIDX);
945 oldval = (w_t) ? newval - 1 : newval + 1;
946 while ((newval > oldval) == w_t)
950 ttt = t + (sch_step_1 * j) - (sch_step_2 * k);
951 newval = time2asecondary(ttt, pIDX);
954 tctime = ttt + sch_step_2;
957 pIDX->recent_highlow_calc_time = t;
959 pIDX->recent_high_level = newval;
960 pIDX->recent_high_time = tctime;
962 pIDX->recent_low_level = newval;
963 pIDX->recent_low_time = tctime;
967int TCMgr::GetStationTimeOffset(
IDX_entry *pIDX) {
return pIDX->IDX_time_zone; }
969double TCMgr::GetStationLat(
IDX_entry *pIDX) {
return pIDX->IDX_lat; }
971double TCMgr::GetStationLon(
IDX_entry *pIDX) {
return pIDX->IDX_lon; }
973int TCMgr::GetNextBigEvent(time_t *tm,
int idx) {
978 int flags = 0, slope = 0;
979 ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
982 ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
985 if (p < q) slope = 1;
987 if ((slope == 1 && q < p) || (slope == 0 && p < q)) {
989 flags |= (1 << slope);
993 if (flags < 4) *tm -= 60;
997 ret = GetTideOrCurrent(*tm, idx, tcvalue[0], dir);
1005std::map<double, const IDX_entry *> TCMgr::GetStationsForLL(
double xlat,
1006 double xlon)
const {
1007 std::map<double, const IDX_entry *> x;
1010 for (
int j = 1; j < Get_max_IDX() + 1; j++) {
1011 lpIDX = GetIDX_entry(j);
1012 char type = lpIDX->IDX_type;
1013 wxString locnx(lpIDX->IDX_station_name, wxConvUTF8);
1015 if (type ==
't' || type ==
'T') {
1017 DistanceBearingMercator(xlat, xlon, lpIDX->IDX_lat, lpIDX->IDX_lon, &brg,
1019 x.emplace(std::make_pair(dist, lpIDX));
1026int TCMgr::GetStationIDXbyName(
const wxString &prefix,
double xlat,
1027 double xlon)
const {
1031 double distx = 100000.;
1033 int jmax = Get_max_IDX();
1035 for (
int j = 1; j < Get_max_IDX() + 1; j++) {
1036 lpIDX = GetIDX_entry(j);
1037 char type = lpIDX->IDX_type;
1038 wxString locnx(lpIDX->IDX_station_name, wxConvUTF8);
1040 if (((type ==
't') || (type ==
'T'))
1041 && (locnx.StartsWith(prefix))) {
1043 DistanceBearingMercator(xlat, xlon, lpIDX->IDX_lat, lpIDX->IDX_lon, &brg,
1055int TCMgr::GetStationIDXbyNameType(
const wxString &prefix,
double xlat,
1056 double xlon,
char type)
const {
1060 double distx = 100000.;
1064 int jmax = Get_max_IDX();
1066 for (
int j = 1; j < Get_max_IDX() + 1; j++) {
1067 lpIDX = GetIDX_entry(j);
1068 char typep = lpIDX->IDX_type;
1069 wxString locnx(lpIDX->IDX_station_name, wxConvUTF8);
1071 if ((type == typep) && (locnx.StartsWith(prefix))) {
1073 DistanceBearingMercator(xlat, xlon, lpIDX->IDX_lat, lpIDX->IDX_lon, &brg,
1099#define DEFAULT_HEADER_SIZE 4096
1100#define DEFAULT_NUMBER_OF_RECORDS 0
1101#define DEFAULT_LEVEL_UNIT_TYPES 5
1102#define DEFAULT_DIR_UNIT_TYPES 3
1103#define DEFAULT_RESTRICTION_TYPES 2
1104#define DEFAULT_RESTRICTION_BITS 4
1105#define DEFAULT_TZFILES 406
1106#define DEFAULT_TZFILE_BITS 10
1107#define DEFAULT_COUNTRIES 240
1108#define DEFAULT_COUNTRY_BITS 9
1109#define DEFAULT_DATUM_TYPES 61
1110#define DEFAULT_DATUM_BITS 7
1111#define DEFAULT_LEGALESES 1
1112#define DEFAULT_LEGALESE_BITS 4
1113#define DEFAULT_SPEED_SCALE 10000000
1114#define DEFAULT_EQUILIBRIUM_SCALE 100
1115#define DEFAULT_NODE_SCALE 10000
1116#define DEFAULT_AMPLITUDE_BITS 19
1117#define DEFAULT_AMPLITUDE_SCALE 10000
1118#define DEFAULT_EPOCH_BITS 16
1119#define DEFAULT_EPOCH_SCALE 100
1120#define DEFAULT_RECORD_TYPE_BITS 4
1121#define DEFAULT_LATITUDE_BITS 25
1122#define DEFAULT_LATITUDE_SCALE 100000
1123#define DEFAULT_LONGITUDE_BITS 26
1124#define DEFAULT_LONGITUDE_SCALE 100000
1125#define DEFAULT_RECORD_SIZE_BITS 16
1126#define DEFAULT_STATION_BITS 18
1127#define DEFAULT_DATUM_OFFSET_BITS 28
1128#define DEFAULT_DATUM_OFFSET_SCALE 10000
1129#define DEFAULT_DATE_BITS 27
1130#define DEFAULT_MONTHS_ON_STATION_BITS 10
1131#define DEFAULT_CONFIDENCE_VALUE_BITS 4
1132#define DEFAULT_NUMBER_OF_CONSTITUENTS_BITS 8
1133#define DEFAULT_TIME_BITS 13
1134#define DEFAULT_LEVEL_ADD_BITS 17
1135#define DEFAULT_LEVEL_ADD_SCALE 1000
1136#define DEFAULT_LEVEL_MULTIPLY_BITS 16
1137#define DEFAULT_LEVEL_MULTIPLY_SCALE 1000
1138#define DEFAULT_DIRECTION_BITS 9
1139#define DEFAULT_CONSTITUENT_SIZE 10
1140#define DEFAULT_LEVEL_UNIT_SIZE 15
1141#define DEFAULT_DIR_UNIT_SIZE 15
1142#define DEFAULT_RESTRICTION_SIZE 30
1143#define DEFAULT_DATUM_SIZE 70
1144#define DEFAULT_LEGALESE_SIZE 70
1145#define DEFAULT_TZFILE_SIZE 30
1146#define DEFAULT_COUNTRY_SIZE 50
1150#define INFERRED_SEMI_DIURNAL_COUNT 10
1151#define INFERRED_DIURNAL_COUNT 10
1154#pragma warning(disable : 4305)
1157const NV_CHAR *inferred_semi_diurnal[INFERRED_SEMI_DIURNAL_COUNT] = {
1158 "N2",
"NU2",
"MU2",
"2N2",
"LDA2",
"T2",
"R2",
"L2",
"K2",
"KJ2"};
1159const NV_CHAR *inferred_diurnal[INFERRED_DIURNAL_COUNT] = {
1160 "OO1",
"M1",
"J1",
"RHO1",
"Q1",
"2Q1",
"P1",
"PI1",
"PHI1",
"PSI1"};
1161NV_FLOAT32 semi_diurnal_coeff[INFERRED_SEMI_DIURNAL_COUNT] = {
1162 .1759, .0341, .0219, .0235, .0066, .0248, .0035, .0251, .1151, .0064};
1163NV_FLOAT32 diurnal_coeff[INFERRED_DIURNAL_COUNT] = {
1164 .0163, .0209, .0297, .0142, .0730, .0097, .1755, .0103, .0076, .0042};
1168NV_FLOAT32 coeff[2] = {.9085, .3771};
1178NV_CHAR level_unit[DEFAULT_LEVEL_UNIT_TYPES][DEFAULT_LEVEL_UNIT_SIZE] = {
1179 "Unknown",
"feet",
"meters",
"knots",
"knots^2"};
1183NV_CHAR dir_unit[DEFAULT_DIR_UNIT_TYPES][DEFAULT_DIR_UNIT_SIZE] = {
1184 "Unknown",
"degrees true",
"degrees"};
1188NV_CHAR restriction[DEFAULT_RESTRICTION_TYPES][DEFAULT_RESTRICTION_SIZE] = {
1189 "Public Domain",
"DoD/DoD Contractors Only"};
1193NV_CHAR legalese[DEFAULT_LEGALESES][DEFAULT_LEGALESE_SIZE] = {
"NULL"};
1197NV_CHAR datum[DEFAULT_DATUM_TYPES][DEFAULT_DATUM_SIZE] = {
1201 "Mean Lower Low Water",
1203 "Mean Higher High Water",
1204 "Mean Lower High Water",
1205 "Mean Higher Low Water",
1206 "Mean Low Water Springs",
1207 "Mean Lower Low Water Springs",
1208 "Mean Low Water Neaps",
1209 "Mean High Water Neaps",
1210 "Mean High Water Springs",
1211 "Mean Higher High Water Springs",
1212 "Indian Spring Low Water",
1213 "Equatorial Spring Low Water",
1214 "Lowest Normal Low Water",
1216 "Lowest Possible Low Water",
1217 "Lowest Astronomical Tide",
1218 "International Great Lakes Datum(1955)",
1219 "Lower Low Water, Large Tide",
1220 "Lowest Normal Tide",
1221 "Higher High Water, Large Tide",
1223 "Higher High Water, Mean Tide",
1224 "Lower Low Water, Mean Tide",
1226 "World Geodetic System (1984)",
1227 "National Geodetic Vertical Datum",
1228 "Gulf Coast Low Water Datum",
1229 "Approximate Level of Mean Sea Level",
1230 "Approximate Level of Mean Low Water",
1231 "Approximate Level of Mean Lower Low Water",
1232 "Approximate Level of Mean High Water",
1233 "Approximate Level of Mean Higher High Water",
1234 "Approximate Level of Mean Lower High Water",
1235 "Approximate Level of Mean Higher Low Water",
1236 "Approximate Level of Mean Low Water Springs",
1237 "Approximate Level of Mean Lower Low Water Springs",
1238 "Approximate Level of Mean Low Water Neaps",
1239 "Approximate Level of Mean High Water Neaps",
1240 "Approximate Level of Mean High Water Springs",
1241 "Approximate Level of Mean Higher High Water Springs",
1242 "Approximate Level of Indian Spring Low Water",
1243 "Approximate Level of Equatorial Spring Low Water",
1244 "Approximate Level of Lowest Normal Low Water",
1245 "Approximate Level of Lowest Low Water",
1246 "Approximate Level of Lowest Possible Low Water",
1247 "Approximate Level of Lowest Astronomical Tide",
1248 "Approximate Level of International Great Lakes Datum (1955)",
1249 "Approximate Level of Lower Low Water, Large Tide",
1250 "Approximate Level of Lowest Normal Tide",
1251 "Approximate Level of Higher High Water, Large Tide",
1252 "Approximate Level of Mean Water Level",
1253 "Approximate Level of Higher High Water, Mean Tide",
1254 "Approximate Level of Lower Low Water, Mean Tide",
1255 "Approximate Level of Mean Tide Level",
1256 "Approximate Level of World Geodetic System (1984)",
1257 "Approximate Level of National Geodetic Vertical Datum",
1258 "Approximate Level of Gulf Coast Low Water Datum"};
1262NV_CHAR country[DEFAULT_COUNTRIES][DEFAULT_COUNTRY_SIZE] = {
1271 "Antigua & Barbuda",
1289 "Bosnia & Herzegovina",
1294 "British Indian Ocean Territory",
1304 "Central African Rep.",
1309 "Cocos (Keeling) Islands",
1312 "Congo (Dem. Rep.)",
1324 "Dominican Republic",
1329 "Equatorial Guinea",
1340 "French Southern & Antarctic Lands",
1357 "Heard Island & McDonald Islands",
1414 "Netherlands Antilles",
1422 "Northern Mariana Islands",
1445 "Sao Tome & Principe",
1456 "South Georgia & the South Sandwich Islands",
1462 "St Pierre & Miquelon",
1466 "Svalbard & Jan Mayen",
1478 "Trinidad & Tobago",
1482 "Turks & Caicos Is",
1486 "United Arab Emirates",
1489 "US minor outlying islands",
1495 "Virgin Islands (UK)",
1496 "Virgin Islands (US)",
1506NV_CHAR tzfile[DEFAULT_TZFILES][DEFAULT_TZFILE_SIZE] = {
1510 ":Africa/Addis_Ababa",
1518 ":Africa/Brazzaville",
1519 ":Africa/Bujumbura",
1521 ":Africa/Casablanca",
1525 ":Africa/Dar_es_Salaam",
1532 ":Africa/Johannesburg",
1538 ":Africa/Libreville",
1541 ":Africa/Lubumbashi",
1547 ":Africa/Mogadishu",
1552 ":Africa/Nouakchott",
1553 ":Africa/Ouagadougou",
1554 ":Africa/Porto-Novo",
1561 ":America/Anchorage",
1562 ":America/Anguilla",
1564 ":America/Araguaina",
1566 ":America/Asuncion",
1568 ":America/Barbados",
1571 ":America/Boa_Vista",
1574 ":America/Buenos_Aires",
1575 ":America/Cambridge_Bay",
1578 ":America/Catamarca",
1582 ":America/Chihuahua",
1584 ":America/Costa_Rica",
1587 ":America/Danmarkshavn",
1589 ":America/Dawson_Creek",
1592 ":America/Dominica",
1593 ":America/Edmonton",
1594 ":America/Eirunepe",
1595 ":America/El_Salvador",
1596 ":America/Ensenada",
1597 ":America/Fortaleza",
1598 ":America/Glace_Bay",
1600 ":America/Goose_Bay",
1601 ":America/Grand_Turk",
1603 ":America/Guadeloupe",
1604 ":America/Guatemala",
1605 ":America/Guayaquil",
1609 ":America/Hermosillo",
1610 ":America/Indiana/Knox",
1611 ":America/Indiana/Marengo",
1612 ":America/Indianapolis",
1613 ":America/Indiana/Vevay",
1619 ":America/Kentucky/Monticello",
1622 ":America/Los_Angeles",
1623 ":America/Louisville",
1627 ":America/Martinique",
1628 ":America/Mazatlan",
1630 ":America/Menominee",
1632 ":America/Mexico_City",
1633 ":America/Miquelon",
1634 ":America/Monterrey",
1635 ":America/Montevideo",
1636 ":America/Montreal",
1637 ":America/Montserrat",
1639 ":America/New_York",
1643 ":America/North_Dakota/Center",
1645 ":America/Pangnirtung",
1646 ":America/Paramaribo",
1648 ":America/Port-au-Prince",
1649 ":America/Port_of_Spain",
1650 ":America/Porto_Velho",
1651 ":America/Puerto_Rico",
1652 ":America/Rainy_River",
1653 ":America/Rankin_Inlet",
1656 ":America/Rio_Branco",
1657 ":America/Santiago",
1658 ":America/Santo_Domingo",
1659 ":America/Sao_Paulo",
1660 ":America/Scoresbysund",
1661 ":America/Shiprock",
1662 ":America/St_Johns",
1663 ":America/St_Kitts",
1664 ":America/St_Lucia",
1665 ":America/St_Thomas",
1666 ":America/St_Vincent",
1667 ":America/Swift_Current",
1668 ":America/Tegucigalpa",
1670 ":America/Thunder_Bay",
1673 ":America/Vancouver",
1674 ":America/Whitehorse",
1675 ":America/Winnipeg",
1677 ":America/Yellowknife",
1678 ":Antarctica/Casey",
1679 ":Antarctica/Davis",
1680 ":Antarctica/DumontDUrville",
1681 ":Antarctica/Mawson",
1682 ":Antarctica/McMurdo",
1683 ":Antarctica/Palmer",
1684 ":Antarctica/South_Pole",
1685 ":Antarctica/Syowa",
1686 ":Antarctica/Vostok",
1687 ":Arctic/Longyearbyen",
1724 ":Asia/Krasnoyarsk",
1725 ":Asia/Kuala_Lumpur",
1734 ":Asia/Novosibirsk",
1756 ":Asia/Ulaanbaatar",
1759 ":Asia/Vladivostok",
1761 ":Asia/Yekaterinburg",
1764 ":Atlantic/Bermuda",
1766 ":Atlantic/Cape_Verde",
1768 ":Atlantic/Jan_Mayen",
1769 ":Atlantic/Madeira",
1770 ":Atlantic/Reykjavik",
1771 ":Atlantic/South_Georgia",
1772 ":Atlantic/Stanley",
1773 ":Atlantic/St_Helena",
1774 ":Australia/Adelaide",
1775 ":Australia/Brisbane",
1776 ":Australia/Broken_Hill",
1777 ":Australia/Darwin",
1778 ":Australia/Hobart",
1779 ":Australia/Lindeman",
1780 ":Australia/Lord_Howe",
1781 ":Australia/Melbourne",
1783 ":Australia/Sydney",
1813 ":Europe/Amsterdam",
1819 ":Europe/Bratislava",
1821 ":Europe/Bucharest",
1824 ":Europe/Copenhagen",
1826 ":Europe/Gibraltar",
1829 ":Europe/Kaliningrad",
1832 ":Europe/Ljubljana",
1834 ":Europe/Luxembourg",
1846 ":Europe/San_Marino",
1848 ":Europe/Simferopol",
1851 ":Europe/Stockholm",
1861 ":Europe/Zaporozhye",
1863 ":Indian/Antananarivo",
1865 ":Indian/Christmas",
1868 ":Indian/Kerguelen",
1871 ":Indian/Mauritius",
1875 ":Pacific/Auckland",
1879 ":Pacific/Enderbury",
1882 ":Pacific/Funafuti",
1883 ":Pacific/Galapagos",
1885 ":Pacific/Guadalcanal",
1887 ":Pacific/Honolulu",
1888 ":Pacific/Johnston",
1889 ":Pacific/Kiritimati",
1891 ":Pacific/Kwajalein",
1893 ":Pacific/Marquesas",
1899 ":Pacific/Pago_Pago",
1901 ":Pacific/Pitcairn",
1903 ":Pacific/Port_Moresby",
1904 ":Pacific/Rarotonga",
1908 ":Pacific/Tongatapu",
1923#define require(expr) \
1926 require_expr = (int)(expr); \
1927 assert(require_expr); \
2247NV_U_INT32 calculate_bits(NV_U_INT32 value);
2248void bit_pack(NV_U_BYTE *, NV_U_INT32, NV_U_INT32, NV_INT32);
2249NV_U_INT32 bit_unpack(NV_U_BYTE *, NV_U_INT32, NV_U_INT32);
2250NV_INT32 signed_bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
2251 NV_U_INT32 numbits);
2257 NV_U_INT32 record_size;
2259 NV_INT32 reference_station;
2262 NV_U_BYTE record_type;
2266static FILE *fp = NULL;
2268static NV_BOOL modified = NVFalse;
2269static NV_INT32 current_record, current_index;
2270static NV_CHAR filename[MONOLOGUE_LENGTH];
2280static void chk_fread(
void *ptr,
size_t size,
size_t nmemb, FILE *stream) {
2282 ret = fread(ptr, size, nmemb, stream);
2290static void chk_fwrite(
const void *ptr,
size_t size,
size_t nmemb,
2293 ret = fwrite(ptr, size, nmemb, stream);
2325 LOG_ERROR(
"\n\nRecord number = %d\n", rec->header.record_number);
2326 LOG_ERROR(
"Record size = %u\n", rec->header.record_size);
2327 LOG_ERROR(
"Record type = %u\n", rec->header.record_type);
2328 LOG_ERROR(
"Latitude = %f\n", rec->header.latitude);
2329 LOG_ERROR(
"Longitude = %f\n", rec->header.longitude);
2330 LOG_ERROR(
"Reference station = %d\n", rec->header.reference_station);
2331 LOG_ERROR(
"Tzfile = %s\n", get_tzfile(rec->header.tzfile));
2332 LOG_ERROR(
"Name = %s\n", rec->header.name);
2334 LOG_ERROR(
"Country = %s\n", get_country(rec->country));
2335 LOG_ERROR(
"Source = %s\n", rec->source);
2336 LOG_ERROR(
"Restriction = %s\n", get_restriction(rec->restriction));
2337 LOG_ERROR(
"Comments = %s\n", rec->comments);
2338 LOG_ERROR(
"Notes = %s\n", rec->notes);
2339 LOG_ERROR(
"Legalese = %s\n", get_legalese(rec->legalese));
2340 LOG_ERROR(
"Station ID context = %s\n", rec->station_id_context);
2341 LOG_ERROR(
"Station ID = %s\n", rec->station_id);
2342 LOG_ERROR(
"Date imported = %d\n", rec->date_imported);
2343 LOG_ERROR(
"Xfields = %s\n", rec->xfields);
2345 LOG_ERROR(
"Direction units = %s\n", get_dir_units(rec->direction_units));
2346 LOG_ERROR(
"Min direction = %d\n", rec->min_direction);
2347 LOG_ERROR(
"Max direction = %d\n", rec->max_direction);
2348 LOG_ERROR(
"Level units = %s\n", get_level_units(rec->level_units));
2350 if (rec->header.record_type == REFERENCE_STATION) {
2351 LOG_ERROR(
"Datum offset = %f\n", rec->datum_offset);
2352 LOG_ERROR(
"Datum = %s\n", get_datum(rec->datum));
2353 LOG_ERROR(
"Zone offset = %d\n", rec->zone_offset);
2354 LOG_ERROR(
"Expiration date = %d\n", rec->expiration_date);
2355 LOG_ERROR(
"Months on station = %d\n", rec->months_on_station);
2356 LOG_ERROR(
"Last date on station = %d\n", rec->last_date_on_station);
2357 LOG_ERROR(
"Confidence = %d\n", rec->confidence);
2358 for (i = 0; i < hd.pub.constituents; ++i) {
2359 if (rec->amplitude[i] != 0.0 || rec->epoch[i] != 0.0) {
2360 LOG_ERROR(
"Amplitude[%d] = %f\n", i, rec->amplitude[i]);
2361 LOG_ERROR(
"Epoch[%d] = %f\n", i, rec->epoch[i]);
2366 else if (rec->header.record_type == SUBORDINATE_STATION) {
2367 LOG_ERROR(
"Min time add = %d\n", rec->min_time_add);
2368 LOG_ERROR(
"Min level add = %f\n", rec->min_level_add);
2369 LOG_ERROR(
"Min level multiply = %f\n", rec->min_level_multiply);
2370 LOG_ERROR(
"Max time add = %d\n", rec->max_time_add);
2371 LOG_ERROR(
"Max level add = %f\n", rec->max_level_add);
2372 LOG_ERROR(
"Max level multiply = %f\n", rec->max_level_multiply);
2373 LOG_ERROR(
"Flood begins = %d\n", rec->flood_begins);
2374 LOG_ERROR(
"Ebb begins = %d\n", rec->ebb_begins);
2387static void write_protect() {
2388 if (hd.pub.major_rev < LIBTCD_MAJOR_REV) {
2390 "libtcd error: can't modify TCD files created by earlier version. "
2391 "Use\nrewrite_tide_db to upgrade the TCD file.\n");
2415const NV_CHAR *get_country(NV_INT32 num) {
2418 "libtcd error: attempt to access database when database not open\n");
2421 if (num >= 0 && num < (NV_INT32)hd.pub.countries)
return (hd.country[num]);
2442const NV_CHAR *get_tzfile(NV_INT32 num) {
2445 "libtcd error: attempt to access database when database not open\n");
2448 if (num >= 0 && num < (NV_INT32)hd.pub.tzfiles)
return (hd.tzfile[num]);
2469const NV_CHAR *get_station(NV_INT32 num) {
2472 "libtcd error: attempt to access database when database not open\n");
2475 if (num >= 0 && num < (NV_INT32)hd.pub.number_of_records)
2476 return (tindex[num].name);
2498const NV_CHAR *get_constituent(NV_INT32 num) {
2501 "libtcd error: attempt to access database when database not open\n");
2504 if (num >= 0 && num < (NV_INT32)hd.pub.constituents)
2505 return (hd.constituent[num]);
2527const NV_CHAR *get_level_units(NV_INT32 num) {
2530 "libtcd error: attempt to access database when database not open\n");
2533 if (num >= 0 && num < (NV_INT32)hd.pub.level_unit_types)
2534 return (hd.level_unit[num]);
2556const NV_CHAR *get_dir_units(NV_INT32 num) {
2559 "libtcd error: attempt to access database when database not open\n");
2562 if (num >= 0 && num < (NV_INT32)hd.pub.dir_unit_types)
2563 return (hd.dir_unit[num]);
2585const NV_CHAR *get_restriction(NV_INT32 num) {
2588 "libtcd error: attempt to access database when database not open\n");
2591 if (num >= 0 && num < (NV_INT32)hd.pub.restriction_types)
2592 return (hd.restriction[num]);
2615NV_CHAR *get_pedigree(NV_INT32 num) {
return "Unknown"; }
2635const NV_CHAR *get_datum(NV_INT32 num) {
2638 "libtcd error: attempt to access database when database not open\n");
2641 if (num >= 0 && num < (NV_INT32)hd.pub.datum_types)
return (hd.datum[num]);
2648const NV_CHAR *get_legalese(NV_INT32 num) {
2651 "libtcd error: attempt to access database when database not open\n");
2654 if (num >= 0 && num < (NV_INT32)hd.pub.legaleses)
return (hd.legalese[num]);
2676NV_FLOAT64 get_speed(NV_INT32 num) {
2679 "libtcd error: attempt to access database when database not open\n");
2682 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
2683 return hd.speed[num];
2705NV_FLOAT32 get_equilibrium(NV_INT32 num, NV_INT32 year) {
2708 "libtcd error: attempt to access database when database not open\n");
2711 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
2712 year < (NV_INT32)hd.pub.number_of_years);
2713 return hd.equilibrium[num][year];
2719NV_FLOAT32 *get_equilibriums(NV_INT32 num) {
2722 "libtcd error: attempt to access database when database not open\n");
2725 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
2726 return hd.equilibrium[num];
2748NV_FLOAT32 get_node_factor(NV_INT32 num, NV_INT32 year) {
2751 "libtcd error: attempt to access database when database not open\n");
2754 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
2755 year < (NV_INT32)hd.pub.number_of_years);
2756 return hd.node_factor[num][year];
2762NV_FLOAT32 *get_node_factors(NV_INT32 num) {
2765 "libtcd error: attempt to access database when database not open\n");
2768 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
2769 return hd.node_factor[num];
2798 "libtcd error: attempt to access database when database not open\n");
2802 if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records)
return (NVFalse);
2806 rec->record_number = num;
2807 rec->record_size = tindex[num].record_size;
2808 rec->record_type = tindex[num].record_type;
2809 rec->latitude = (NV_FLOAT64)tindex[num].lat / hd.latitude_scale;
2810 rec->longitude = (NV_FLOAT64)tindex[num].lon / hd.longitude_scale;
2811 rec->reference_station = tindex[num].reference_station;
2812 rec->tzfile = tindex[num].tzfile;
2813 strcpy(rec->name, tindex[num].name);
2815 current_index = num;
2839 if (!get_partial_tide_record(current_index + 1, rec))
return (-1);
2841 return (current_index);
2864NV_INT32 get_nearest_partial_tide_record(NV_FLOAT64 lat, NV_FLOAT64 lon,
2866 NV_FLOAT64 diff, min_diff, lt, ln;
2867 NV_U_INT32 i, shortest = 0;
2869 min_diff = 999999999.9;
2870 for (i = 0; i < hd.pub.number_of_records; ++i) {
2871 lt = (NV_FLOAT64)tindex[i].lat / hd.latitude_scale;
2872 ln = (NV_FLOAT64)tindex[i].lon / hd.longitude_scale;
2874 diff = sqrt((lat - lt) * (lat - lt) + (lon - ln) * (lon - ln));
2876 if (diff < min_diff) {
2882 if (!get_partial_tide_record(shortest, rec))
return (-1);
2904NV_INT32 get_time(
const NV_CHAR *
string) {
2905 NV_INT32 hour, minute, hhmm;
2908 sscanf(
string,
"%d:%d", &hour, &minute);
2912 if (
string[0] ==
'-') {
2913 if (hour < 0) hour = -hour;
2915 hhmm = -(hour * 100 + minute);
2917 hhmm = hour * 100 + minute;
2941NV_CHAR *ret_time(NV_INT32 time) {
2942 NV_INT32 hour, minute;
2943 static NV_CHAR tname[16];
2945 hour = abs(time) / 100;
2946 assert(hour <= 99999 && hour >= -99999);
2947 minute = abs(time) % 100;
2950 sprintf(tname,
"-%02d:%02d", hour, minute);
2952 sprintf(tname,
"+%02d:%02d", hour, minute);
2961NV_CHAR *ret_time_neat(NV_INT32 time) {
2962 NV_INT32 hour, minute;
2963 static NV_CHAR tname[16];
2965 hour = abs(time) / 100;
2966 assert(hour <= 99999 && hour >= -99999);
2967 minute = abs(time) % 100;
2970 sprintf(tname,
"-%d:%02d", hour, minute);
2972 sprintf(tname,
"+%d:%02d", hour, minute);
2974 strcpy(tname,
"0:00");
2982NV_CHAR *ret_date(NV_U_INT32 date) {
2983 static NV_CHAR tname[30];
2985 strcpy(tname,
"NULL");
2992 sprintf(tname,
"%4u-%02u-%02u", y, m, d);
3016 "libtcd error: attempt to access database when database not open\n");
3026static void boundscheck_monologue(
const NV_CHAR *
string) {
3028 if (strlen(
string) >= MONOLOGUE_LENGTH) {
3042static void boundscheck_oneliner(
const NV_CHAR *
string) {
3044 if (strlen(
string) >= ONELINER_LENGTH) {
3072static NV_CHAR *clip_string(
const NV_CHAR *
string) {
3073 static NV_CHAR new_string[MONOLOGUE_LENGTH];
3074 NV_INT32 i, l, start = -1, end = -1;
3076 boundscheck_monologue(
string);
3077 new_string[0] =
'\0';
3079 l = (int)strlen(
string);
3081 for (i = 0; i < l; ++i) {
3082 if (
string[i] !=
' ') {
3087 for (i = l - 1; i >= start; --i) {
3088 if (
string[i] !=
' ' &&
string[i] != 10 &&
string[i] != 13) {
3093 if (start > -1 && end > -1 && end >= start) {
3094 strncpy(new_string,
string + start, end - start + 1);
3095 new_string[end - start + 1] =
'\0';
3122NV_INT32 search_station(
const NV_CHAR *
string) {
3123 static NV_CHAR last_search[ONELINER_LENGTH];
3124 static NV_U_INT32 j = 0;
3126 NV_CHAR name[ONELINER_LENGTH], search[ONELINER_LENGTH];
3130 "libtcd error: attempt to access database when database not open\n");
3134 boundscheck_oneliner(
string);
3136 for (i = 0; i < strlen(
string) + 1; ++i) search[i] = tolower(
string[i]);
3138 if (strcmp(search, last_search)) j = 0;
3140 strcpy(last_search, search);
3142 while (j < hd.pub.number_of_records) {
3143 for (i = 0; i < strlen(tindex[j].name) + 1; ++i)
3144 name[i] = tolower(tindex[j].name[i]);
3147 if (strstr(name, search))
return (j - 1);
3172NV_INT32 find_station(
const NV_CHAR *name) {
3177 "libtcd error: attempt to access database when database not open\n");
3182 for (i = 0; i < hd.pub.number_of_records; ++i) {
3183 if (!strcmp(name, tindex[i].name))
return (i);
3207NV_INT32 find_tzfile(
const NV_CHAR *name) {
3214 "libtcd error: attempt to access database when database not open\n");
3218 temp = clip_string(name);
3221 for (i = 0; i < hd.pub.tzfiles; ++i) {
3222 if (!strcmp(temp, get_tzfile(i))) {
3249NV_INT32 find_country(
const NV_CHAR *name) {
3256 "libtcd error: attempt to access database when database not open\n");
3260 temp = clip_string(name);
3263 for (i = 0; i < hd.pub.countries; ++i) {
3264 if (!strcmp(temp, get_country(i))) {
3291NV_INT32 find_level_units(
const NV_CHAR *name) {
3298 "libtcd error: attempt to access database when database not open\n");
3302 temp = clip_string(name);
3305 for (i = 0; i < hd.pub.level_unit_types; ++i) {
3306 if (!strcmp(get_level_units(i), temp)) {
3333NV_INT32 find_dir_units(
const NV_CHAR *name) {
3340 "libtcd error: attempt to access database when database not open\n");
3344 temp = clip_string(name);
3347 for (i = 0; i < hd.pub.dir_unit_types; ++i) {
3348 if (!strcmp(get_dir_units(i), temp)) {
3376NV_INT32 find_pedigree(
const NV_CHAR *name) {
return 0; }
3397NV_INT32 find_datum(
const NV_CHAR *name) {
3404 "libtcd error: attempt to access database when database not open\n");
3408 temp = clip_string(name);
3411 for (i = 0; i < hd.pub.datum_types; ++i) {
3412 if (!strcmp(get_datum(i), temp)) {
3424NV_INT32 find_legalese(
const NV_CHAR *name) {
3431 "libtcd error: attempt to access database when database not open\n");
3435 temp = clip_string(name);
3438 for (i = 0; i < hd.pub.legaleses; ++i) {
3439 if (!strcmp(get_legalese(i), temp)) {
3467NV_INT32 find_constituent(
const NV_CHAR *name) {
3473 "libtcd error: attempt to access database when database not open\n");
3477 temp = clip_string(name);
3479 for (i = 0; i < hd.pub.constituents; ++i) {
3480 if (!strcmp(get_constituent(i), temp))
return (i);
3504NV_INT32 find_restriction(
const NV_CHAR *name) {
3511 "libtcd error: attempt to access database when database not open\n");
3515 temp = clip_string(name);
3518 for (i = 0; i < hd.pub.restriction_types; ++i) {
3519 if (!strcmp(get_restriction(i), temp)) {
3545void set_speed(NV_INT32 num, NV_FLOAT64 value) {
3548 "libtcd error: attempt to access database when database not open\n");
3552 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents);
3554 LOG_ERROR(
"libtcd set_speed: somebody tried to set a negative speed (%f)\n",
3558 hd.speed[num] = value;
3582void set_equilibrium(NV_INT32 num, NV_INT32 year, NV_FLOAT32 value) {
3585 "libtcd error: attempt to access database when database not open\n");
3589 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
3590 year < (NV_INT32)hd.pub.number_of_years);
3591 hd.equilibrium[num][year] = value;
3615void set_node_factor(NV_INT32 num, NV_INT32 year, NV_FLOAT32 value) {
3618 "libtcd error: attempt to access database when database not open\n");
3622 assert(num >= 0 && num < (NV_INT32)hd.pub.constituents && year >= 0 &&
3623 year < (NV_INT32)hd.pub.number_of_years);
3626 "libtcd set_node_factor: somebody tried to set a negative or zero node "
3631 hd.node_factor[num][year] = value;
3682 "libtcd error: attempt to access database when database not open\n");
3688 if (strlen(name) + 1 > hd.tzfile_size) {
3689 LOG_ERROR(
"libtcd error: tzfile exceeds size limit (%u).\n",
3691 LOG_ERROR(
"The offending input is: %s\n", name);
3695 if (hd.pub.tzfiles == hd.max_tzfiles) {
3696 LOG_ERROR(
"You have exceeded the maximum number of tzfile types!\n");
3697 LOG_ERROR(
"You cannot add any new tzfile types.\n");
3698 LOG_ERROR(
"Modify the DEFAULT_TZFILE_BITS and rebuild the database.\n");
3702 c_name = clip_string(name);
3704 hd.tzfile[hd.pub.tzfiles] =
3705 (NV_CHAR *)calloc(strlen(c_name) + 1,
sizeof(NV_CHAR));
3707 if (hd.tzfile[hd.pub.tzfiles] == NULL) {
3708 perror(
"Allocating new tzfile string");
3712 strcpy(hd.tzfile[hd.pub.tzfiles++], c_name);
3713 if (db) *db = hd.pub;
3715 return (hd.pub.tzfiles - 1);
3741 "libtcd error: attempt to access database when database not open\n");
3747 if (strlen(name) + 1 > hd.country_size) {
3748 LOG_ERROR(
"libtcd error: country exceeds size limit (%u).\n",
3750 LOG_ERROR(
"The offending input is: %s\n", name);
3754 if (hd.pub.countries == hd.max_countries) {
3755 LOG_ERROR(
"You have exceeded the maximum number of country names!\n");
3756 LOG_ERROR(
"You cannot add any new country names.\n");
3757 LOG_ERROR(
"Modify the DEFAULT_COUNTRY_BITS and rebuild the database.\n");
3761 c_name = clip_string(name);
3763 hd.country[hd.pub.countries] =
3764 (NV_CHAR *)calloc(strlen(c_name) + 1,
sizeof(NV_CHAR));
3766 if (hd.country[hd.pub.countries] == NULL) {
3767 perror(
"Allocating new country string");
3771 strcpy(hd.country[hd.pub.countries++], c_name);
3772 if (db) *db = hd.pub;
3774 return (hd.pub.countries - 1);
3800 "libtcd error: attempt to access database when database not open\n");
3806 if (strlen(name) + 1 > hd.datum_size) {
3807 LOG_ERROR(
"libtcd error: datum exceeds size limit (%u).\n", hd.datum_size);
3808 LOG_ERROR(
"The offending input is: %s\n", name);
3812 if (hd.pub.datum_types == hd.max_datum_types) {
3813 LOG_ERROR(
"You have exceeded the maximum number of datum types!\n");
3814 LOG_ERROR(
"You cannot add any new datum types.\n");
3815 LOG_ERROR(
"Modify the DEFAULT_DATUM_BITS and rebuild the database.\n");
3819 c_name = clip_string(name);
3821 hd.datum[hd.pub.datum_types] =
3822 (NV_CHAR *)calloc(strlen(c_name) + 1,
sizeof(NV_CHAR));
3824 if (hd.datum[hd.pub.datum_types] == NULL) {
3825 perror(
"Allocating new datum string");
3829 strcpy(hd.datum[hd.pub.datum_types++], c_name);
3830 if (db) *db = hd.pub;
3832 return (hd.pub.datum_types - 1);
3843 "libtcd error: attempt to access database when database not open\n");
3849 if (strlen(name) + 1 > hd.legalese_size) {
3850 LOG_ERROR(
"libtcd error: legalese exceeds size limit (%u).\n",
3852 LOG_ERROR(
"The offending input is: %s\n", name);
3856 if (hd.pub.legaleses == hd.max_legaleses) {
3857 LOG_ERROR(
"You have exceeded the maximum number of legaleses!\n");
3858 LOG_ERROR(
"You cannot add any new legaleses.\n");
3859 LOG_ERROR(
"Modify the DEFAULT_LEGALESE_BITS and rebuild the database.\n");
3863 c_name = clip_string(name);
3865 hd.legalese[hd.pub.legaleses] =
3866 (NV_CHAR *)calloc(strlen(c_name) + 1,
sizeof(NV_CHAR));
3868 if (hd.legalese[hd.pub.legaleses] == NULL) {
3869 perror(
"Allocating new legalese string");
3873 strcpy(hd.legalese[hd.pub.legaleses++], c_name);
3874 if (db) *db = hd.pub;
3876 return (hd.pub.legaleses - 1);
3902 "libtcd error: attempt to access database when database not open\n");
3908 if (strlen(name) + 1 > hd.restriction_size) {
3909 LOG_ERROR(
"libtcd error: restriction exceeds size limit (%u).\n",
3910 hd.restriction_size);
3911 LOG_ERROR(
"The offending input is: %s\n", name);
3915 if (hd.pub.restriction_types == hd.max_restriction_types) {
3916 LOG_ERROR(
"You have exceeded the maximum number of restriction types!\n");
3917 LOG_ERROR(
"You cannot add any new restriction types.\n");
3919 "Modify the DEFAULT_RESTRICTION_BITS and rebuild the database.\n");
3923 c_name = clip_string(name);
3925 hd.restriction[hd.pub.restriction_types] =
3926 (NV_CHAR *)calloc(strlen(c_name) + 1,
sizeof(NV_CHAR));
3928 if (hd.restriction[hd.pub.restriction_types] == NULL) {
3929 perror(
"Allocating new restriction string");
3933 strcpy(hd.restriction[hd.pub.restriction_types++], c_name);
3934 if (db) *db = hd.pub;
3936 return (hd.pub.restriction_types - 1);
3942NV_INT32 find_or_add_restriction(
const NV_CHAR *name,
DB_HEADER_PUBLIC *db) {
3944 ret = find_restriction(name);
3945 if (ret < 0) ret = add_restriction(name, db);
3955 ret = find_tzfile(name);
3956 if (ret < 0) ret = add_tzfile(name, db);
3966 ret = find_country(name);
3967 if (ret < 0) ret = add_country(name, db);
3977 ret = find_datum(name);
3978 if (ret < 0) ret = add_datum(name, db);
3988 ret = find_legalese(name);
3989 if (ret < 0) ret = add_legalese(name, db);
4020 if (rec.max_time_add == rec.min_time_add &&
4021 rec.max_level_add == rec.min_level_add &&
4022 rec.max_level_multiply == rec.min_level_multiply &&
4023 rec.max_avg_level == 0 && rec.min_avg_level == 0 &&
4024 rec.max_direction == 361 && rec.min_direction == 361 &&
4025 rec.flood_begins == NULLSLACKOFFSET && rec.ebb_begins == NULLSLACKOFFSET)
4048static NV_U_INT32 header_checksum() {
4049 NV_U_INT32 checksum, i, save_pos;
4051 NV_U_INT32 crc_table[256] = {
4052 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
4053 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
4054 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
4055 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
4056 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
4057 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
4058 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
4059 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
4060 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
4061 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
4062 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
4063 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
4064 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
4065 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
4066 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
4067 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
4068 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
4069 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
4070 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
4071 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
4072 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
4073 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
4074 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
4075 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
4076 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
4077 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
4078 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
4079 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
4080 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
4081 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
4082 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
4083 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
4084 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
4085 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
4086 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
4087 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
4088 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
4089 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
4090 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
4091 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
4092 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
4093 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
4094 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
4098 "libtcd error: attempt to access database when database not open\n");
4102 save_pos = ftell(fp);
4104 fseek(fp, 0, SEEK_SET);
4106 if ((buf = (NV_U_BYTE *)calloc(hd.header_size,
sizeof(NV_U_BYTE))) == NULL) {
4107 perror(
"Allocating checksum buffer");
4113 assert(hd.header_size > 0);
4114 chk_fread(buf, hd.header_size, 1, fp);
4115 for (i = 0; i < (NV_U_INT32)hd.header_size; ++i) {
4116 checksum = crc_table[(checksum ^ buf[i]) & 0xff] ^ (checksum >> 8);
4122 fseek(fp, save_pos, SEEK_SET);
4143static NV_U_INT32 old_header_checksum() {
4144 NV_U_INT32 checksum, i, save_pos;
4149 "libtcd error: attempt to access database when database not open\n");
4153 save_pos = ftell(fp);
4157 fseek(fp, 0, SEEK_SET);
4159 if ((buf = (NV_U_BYTE *)calloc(hd.header_size,
sizeof(NV_U_BYTE))) == NULL) {
4160 perror(
"Allocating checksum buffer");
4164 chk_fread(buf, hd.header_size, 1, fp);
4166 for (i = 0; i < hd.header_size; ++i) checksum += buf[i];
4170 fseek(fp, save_pos, SEEK_SET);
4180static NV_CHAR *curtime() {
4181 static NV_CHAR buf[ONELINER_LENGTH];
4182 time_t t = time(NULL);
4183 require(strftime(buf, ONELINER_LENGTH,
"%Y-%m-%d %H:%M %Z", localtime(&t)) >
4192static NV_U_INT32 bits2bytes(NV_U_INT32 nbits) {
4193 if (nbits % 8)
return nbits / 8 + 1;
4213static void write_tide_db_header() {
4214 NV_U_INT32 i, size, pos;
4215 NV_INT32 start, temp_int;
4216 static NV_CHAR zero = 0;
4217 NV_U_BYTE *buf, checksum_c[4];
4221 "libtcd error: attempt to access database when database not open\n");
4226 fseek(fp, 0, SEEK_SET);
4228 fprintf(fp,
"[VERSION] = %s\n", LIBTCD_VERSION);
4229 fprintf(fp,
"[MAJOR REV] = %u\n", LIBTCD_MAJOR_REV);
4230 fprintf(fp,
"[MINOR REV] = %u\n", LIBTCD_MINOR_REV);
4232 fprintf(fp,
"[LAST MODIFIED] = %s\n", curtime());
4234 fprintf(fp,
"[HEADER SIZE] = %u\n", hd.header_size);
4235 fprintf(fp,
"[NUMBER OF RECORDS] = %u\n", hd.pub.number_of_records);
4237 fprintf(fp,
"[START YEAR] = %d\n", hd.pub.start_year);
4238 fprintf(fp,
"[NUMBER OF YEARS] = %u\n", hd.pub.number_of_years);
4240 fprintf(fp,
"[SPEED BITS] = %u\n", hd.speed_bits);
4241 fprintf(fp,
"[SPEED SCALE] = %u\n", hd.speed_scale);
4242 fprintf(fp,
"[SPEED OFFSET] = %d\n", hd.speed_offset);
4243 fprintf(fp,
"[EQUILIBRIUM BITS] = %u\n", hd.equilibrium_bits);
4244 fprintf(fp,
"[EQUILIBRIUM SCALE] = %u\n", hd.equilibrium_scale);
4245 fprintf(fp,
"[EQUILIBRIUM OFFSET] = %d\n", hd.equilibrium_offset);
4246 fprintf(fp,
"[NODE BITS] = %u\n", hd.node_bits);
4247 fprintf(fp,
"[NODE SCALE] = %u\n", hd.node_scale);
4248 fprintf(fp,
"[NODE OFFSET] = %d\n", hd.node_offset);
4249 fprintf(fp,
"[AMPLITUDE BITS] = %u\n", hd.amplitude_bits);
4250 fprintf(fp,
"[AMPLITUDE SCALE] = %u\n", hd.amplitude_scale);
4251 fprintf(fp,
"[EPOCH BITS] = %u\n", hd.epoch_bits);
4252 fprintf(fp,
"[EPOCH SCALE] = %u\n", hd.epoch_scale);
4254 fprintf(fp,
"[RECORD TYPE BITS] = %u\n", hd.record_type_bits);
4255 fprintf(fp,
"[LATITUDE BITS] = %u\n", hd.latitude_bits);
4256 fprintf(fp,
"[LATITUDE SCALE] = %u\n", hd.latitude_scale);
4257 fprintf(fp,
"[LONGITUDE BITS] = %u\n", hd.longitude_bits);
4258 fprintf(fp,
"[LONGITUDE SCALE] = %u\n", hd.longitude_scale);
4259 fprintf(fp,
"[RECORD SIZE BITS] = %u\n", hd.record_size_bits);
4261 fprintf(fp,
"[STATION BITS] = %u\n", hd.station_bits);
4263 fprintf(fp,
"[DATUM OFFSET BITS] = %u\n", hd.datum_offset_bits);
4264 fprintf(fp,
"[DATUM OFFSET SCALE] = %u\n", hd.datum_offset_scale);
4265 fprintf(fp,
"[DATE BITS] = %u\n", hd.date_bits);
4266 fprintf(fp,
"[MONTHS ON STATION BITS] = %u\n", hd.months_on_station_bits);
4267 fprintf(fp,
"[CONFIDENCE VALUE BITS] = %u\n", hd.confidence_value_bits);
4269 fprintf(fp,
"[TIME BITS] = %u\n", hd.time_bits);
4270 fprintf(fp,
"[LEVEL ADD BITS] = %u\n", hd.level_add_bits);
4271 fprintf(fp,
"[LEVEL ADD SCALE] = %u\n", hd.level_add_scale);
4272 fprintf(fp,
"[LEVEL MULTIPLY BITS] = %u\n", hd.level_multiply_bits);
4273 fprintf(fp,
"[LEVEL MULTIPLY SCALE] = %u\n", hd.level_multiply_scale);
4274 fprintf(fp,
"[DIRECTION BITS] = %u\n", hd.direction_bits);
4276 fprintf(fp,
"[LEVEL UNIT BITS] = %u\n", hd.level_unit_bits);
4277 fprintf(fp,
"[LEVEL UNIT TYPES] = %u\n", hd.pub.level_unit_types);
4278 fprintf(fp,
"[LEVEL UNIT SIZE] = %u\n", hd.level_unit_size);
4280 fprintf(fp,
"[DIRECTION UNIT BITS] = %u\n", hd.dir_unit_bits);
4281 fprintf(fp,
"[DIRECTION UNIT TYPES] = %u\n", hd.pub.dir_unit_types);
4282 fprintf(fp,
"[DIRECTION UNIT SIZE] = %u\n", hd.dir_unit_size);
4284 fprintf(fp,
"[RESTRICTION BITS] = %u\n", hd.restriction_bits);
4285 fprintf(fp,
"[RESTRICTION TYPES] = %u\n", hd.pub.restriction_types);
4286 fprintf(fp,
"[RESTRICTION SIZE] = %u\n", hd.restriction_size);
4288 fprintf(fp,
"[DATUM BITS] = %u\n", hd.datum_bits);
4289 fprintf(fp,
"[DATUM TYPES] = %u\n", hd.pub.datum_types);
4290 fprintf(fp,
"[DATUM SIZE] = %u\n", hd.datum_size);
4292 fprintf(fp,
"[LEGALESE BITS] = %u\n", hd.legalese_bits);
4293 fprintf(fp,
"[LEGALESE TYPES] = %u\n", hd.pub.legaleses);
4294 fprintf(fp,
"[LEGALESE SIZE] = %u\n", hd.legalese_size);
4296 fprintf(fp,
"[CONSTITUENT BITS] = %u\n", hd.constituent_bits);
4297 fprintf(fp,
"[CONSTITUENTS] = %u\n", hd.pub.constituents);
4298 fprintf(fp,
"[CONSTITUENT SIZE] = %u\n", hd.constituent_size);
4300 fprintf(fp,
"[TZFILE BITS] = %u\n", hd.tzfile_bits);
4301 fprintf(fp,
"[TZFILES] = %u\n", hd.pub.tzfiles);
4302 fprintf(fp,
"[TZFILE SIZE] = %u\n", hd.tzfile_size);
4304 fprintf(fp,
"[COUNTRY BITS] = %u\n", hd.country_bits);
4305 fprintf(fp,
"[COUNTRIES] = %u\n", hd.pub.countries);
4306 fprintf(fp,
"[COUNTRY SIZE] = %u\n", hd.country_size);
4308 fprintf(fp,
"[END OF FILE] = %u\n", hd.end_of_file);
4309 fprintf(fp,
"[END OF ASCII HEADER DATA]\n");
4315 for (i = start; i < hd.header_size; ++i) chk_fwrite(&zero, 1, 1, fp);
4320 bit_pack(checksum_c, 0, 32, header_checksum());
4321 chk_fwrite(checksum_c, 4, 1, fp);
4328 size = hd.pub.level_unit_types * hd.level_unit_size;
4330 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4331 perror(
"Allocating unit write buffer");
4334 memset(buf, 0, size);
4336 for (i = 0; i < hd.pub.level_unit_types; ++i) {
4337 assert(strlen(hd.level_unit[i]) + 1 <= hd.level_unit_size);
4338 strcpy((NV_CHAR *)&buf[pos], hd.level_unit[i]);
4339 pos += hd.level_unit_size;
4342 chk_fwrite(buf, pos, 1, fp);
4348 size = hd.pub.dir_unit_types * hd.dir_unit_size;
4350 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4351 perror(
"Allocating unit write buffer");
4354 memset(buf, 0, size);
4356 for (i = 0; i < hd.pub.dir_unit_types; ++i) {
4357 assert(strlen(hd.dir_unit[i]) + 1 <= hd.dir_unit_size);
4358 strcpy((NV_CHAR *)&buf[pos], hd.dir_unit[i]);
4359 pos += hd.dir_unit_size;
4362 chk_fwrite(buf, pos, 1, fp);
4368 size = hd.max_restriction_types * hd.restriction_size;
4370 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4371 perror(
"Allocating restriction write buffer");
4374 memset(buf, 0, size);
4376 for (i = 0; i < hd.max_restriction_types; ++i) {
4377 if (i == hd.pub.restriction_types)
break;
4378 assert(strlen(hd.restriction[i]) + 1 <= hd.restriction_size);
4379 strcpy((NV_CHAR *)&buf[pos], hd.restriction[i]);
4380 pos += hd.restriction_size;
4382 memcpy(&buf[pos],
"__END__", 7);
4384 chk_fwrite(buf, size, 1, fp);
4390 size = hd.max_tzfiles * hd.tzfile_size;
4392 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4393 perror(
"Allocating tzfile write buffer");
4396 memset(buf, 0, size);
4398 for (i = 0; i < hd.max_tzfiles; ++i) {
4399 if (i == hd.pub.tzfiles)
break;
4400 assert(strlen(hd.tzfile[i]) + 1 <= hd.tzfile_size);
4401 strcpy((NV_CHAR *)&buf[pos], hd.tzfile[i]);
4402 pos += hd.tzfile_size;
4404 memcpy(&buf[pos],
"__END__", 7);
4406 chk_fwrite(buf, size, 1, fp);
4412 size = hd.max_countries * hd.country_size;
4414 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4415 perror(
"Allocating country write buffer");
4418 memset(buf, 0, size);
4420 for (i = 0; i < hd.max_countries; ++i) {
4421 if (i == hd.pub.countries)
break;
4422 assert(strlen(hd.country[i]) + 1 <= hd.country_size);
4423 strcpy((NV_CHAR *)&buf[pos], hd.country[i]);
4424 pos += hd.country_size;
4426 memcpy(&buf[pos],
"__END__", 7);
4428 chk_fwrite(buf, size, 1, fp);
4434 size = hd.max_datum_types * hd.datum_size;
4436 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4437 perror(
"Allocating datum write buffer");
4440 memset(buf, 0, size);
4442 for (i = 0; i < hd.max_datum_types; ++i) {
4443 if (i == hd.pub.datum_types)
break;
4444 assert(strlen(hd.datum[i]) + 1 <= hd.datum_size);
4445 strcpy((NV_CHAR *)&buf[pos], hd.datum[i]);
4446 pos += hd.datum_size;
4448 memcpy(&buf[pos],
"__END__", 7);
4450 chk_fwrite(buf, size, 1, fp);
4456 size = hd.max_legaleses * hd.legalese_size;
4458 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4459 perror(
"Allocating legalese write buffer");
4462 memset(buf, 0, size);
4464 for (i = 0; i < hd.max_legaleses; ++i) {
4465 if (i == hd.pub.legaleses)
break;
4466 assert(strlen(hd.legalese[i]) + 1 <= hd.legalese_size);
4467 strcpy((NV_CHAR *)&buf[pos], hd.legalese[i]);
4468 pos += hd.legalese_size;
4470 memcpy(&buf[pos],
"__END__", 7);
4472 chk_fwrite(buf, size, 1, fp);
4478 size = hd.pub.constituents * hd.constituent_size;
4480 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4481 perror(
"Allocating constituent write buffer");
4484 memset(buf, 0, size);
4486 for (i = 0; i < hd.pub.constituents; ++i) {
4487 assert(strlen(hd.constituent[i]) + 1 <= hd.constituent_size);
4488 strcpy((NV_CHAR *)&buf[pos], hd.constituent[i]);
4489 pos += hd.constituent_size;
4492 chk_fwrite(buf, pos, 1, fp);
4500 size = bits2bytes(hd.pub.constituents * hd.speed_bits);
4502 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4503 perror(
"Allocating speed write buffer");
4506 memset(buf, 0, size);
4508 for (i = 0; i < hd.pub.constituents; ++i) {
4509 temp_int = NINT(hd.speed[i] * hd.speed_scale) - hd.speed_offset;
4510 assert(temp_int >= 0);
4511 bit_pack(buf, pos, hd.speed_bits, temp_int);
4512 pos += hd.speed_bits;
4515 chk_fwrite(buf, size, 1, fp);
4521 size = bits2bytes(hd.pub.constituents * hd.pub.number_of_years *
4522 hd.equilibrium_bits);
4524 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4525 perror(
"Allocating equilibrium write buffer");
4528 memset(buf, 0, size);
4530 for (i = 0; i < hd.pub.constituents; ++i) {
4532 for (j = 0; j < hd.pub.number_of_years; ++j) {
4533 temp_int = NINT(hd.equilibrium[i][j] * hd.equilibrium_scale) -
4534 hd.equilibrium_offset;
4535 assert(temp_int >= 0);
4536 bit_pack(buf, pos, hd.equilibrium_bits, temp_int);
4537 pos += hd.equilibrium_bits;
4541 chk_fwrite(buf, size, 1, fp);
4548 bits2bytes(hd.pub.constituents * hd.pub.number_of_years * hd.node_bits);
4550 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
4551 perror(
"Allocating node write buffer");
4554 memset(buf, 0, size);
4556 for (i = 0; i < hd.pub.constituents; ++i) {
4558 for (j = 0; j < hd.pub.number_of_years; ++j) {
4559 temp_int = NINT(hd.node_factor[i][j] * hd.node_scale) - hd.node_offset;
4560 assert(temp_int >= 0);
4561 bit_pack(buf, pos, hd.node_bits, temp_int);
4562 pos += hd.node_bits;
4566 chk_fwrite(buf, size, 1, fp);
4597static void unpack_string(NV_U_BYTE *buf, NV_U_INT32 bufsize, NV_U_INT32 *pos,
4598 NV_CHAR *outbuf, NV_U_INT32 outbuflen,
4599 const NV_CHAR *desc) {
4609 for (i = 0; c; ++i) {
4610 assert(*pos < bufsize);
4611 c = bit_unpack(buf, *pos, 8);
4613 if (i < outbuflen) {
4615 }
else if (i == outbuflen) {
4618 LOG_ERROR(
"libtcd warning: truncating overlong %s\n", desc);
4619 LOG_ERROR(
"The offending string starts with:\n%s\n", outbuf);
4647static void unpack_partial_tide_record(NV_U_BYTE *buf, NV_U_INT32 bufsize,
4657 rec->header.record_size = bit_unpack(buf, *pos, hd.record_size_bits);
4658 *pos += hd.record_size_bits;
4660 rec->header.record_type = bit_unpack(buf, *pos, hd.record_type_bits);
4661 *pos += hd.record_type_bits;
4663 temp_int = signed_bit_unpack(buf, *pos, hd.latitude_bits);
4664 rec->header.latitude = (NV_FLOAT64)temp_int / hd.latitude_scale;
4665 *pos += hd.latitude_bits;
4667 temp_int = signed_bit_unpack(buf, *pos, hd.longitude_bits);
4668 rec->header.longitude = (NV_FLOAT64)temp_int / hd.longitude_scale;
4669 *pos += hd.longitude_bits;
4674 rec->header.tzfile = bit_unpack(buf, *pos, hd.tzfile_bits);
4675 *pos += hd.tzfile_bits;
4677 unpack_string(buf, bufsize, pos, rec->header.name, ONELINER_LENGTH,
4680 rec->header.reference_station = signed_bit_unpack(buf, *pos, hd.station_bits);
4681 *pos += hd.station_bits;
4683 assert(*pos <= bufsize * 8);
4706static NV_INT32 read_partial_tide_record(NV_INT32 num,
TIDE_RECORD *rec) {
4708 NV_U_INT32 maximum_possible_size, pos;
4712 "libtcd error: attempt to access database when database not open\n");
4721 maximum_possible_size = hd.record_size_bits + hd.record_type_bits +
4722 hd.latitude_bits + hd.longitude_bits +
4723 hd.tzfile_bits + (ONELINER_LENGTH * 8) +
4725 maximum_possible_size = bits2bytes(maximum_possible_size);
4727 if ((buf = (NV_U_BYTE *)calloc(maximum_possible_size,
sizeof(NV_U_BYTE))) ==
4729 perror(
"Allocating partial tide record buffer");
4733 current_record = num;
4734 fseek(fp, tindex[num].address, SEEK_SET);
4739 size_t size = fread(buf, 1, maximum_possible_size, fp);
4740 unpack_partial_tide_record(buf, size, rec, &pos);
4760static NV_BOOL read_tide_db_header() {
4762 NV_CHAR varin[ONELINER_LENGTH], *info;
4763 NV_U_INT32 utemp, i, j, pos, size, key_count;
4764 NV_U_BYTE *buf, checksum_c[5];
4769 "libtcd error: attempt to access database when database not open\n");
4773 strcpy(hd.pub.version,
"NO VERSION");
4776 key_count =
sizeof(keys) /
sizeof(
KEY);
4779 memset(&hd, 0,
sizeof(hd));
4782 while (fgets(varin,
sizeof(varin), fp) != NULL) {
4783 if (strlen(varin) == ONELINER_LENGTH - 1) {
4784 if (varin[ONELINER_LENGTH - 2] !=
'\n') {
4785 LOG_ERROR(
"libtcd error: header line too long, begins with:\n");
4786 LOG_ERROR(
"%s\n", varin);
4787 LOG_ERROR(
"in file %s\n", filename);
4788 LOG_ERROR(
"Configured limit is %u\n", ONELINER_LENGTH - 1);
4794 if (strstr(varin,
"[END OF ASCII HEADER DATA]"))
break;
4797 info = strchr(varin,
'=');
4799 LOG_ERROR(
"libtcd error: invalid tide db header line:\n");
4800 LOG_ERROR(
"%s", varin);
4801 LOG_ERROR(
"in file %s\n", filename);
4808 for (i = 0; i < key_count; ++i) {
4809 if (strstr(varin, keys[i].keyphrase)) {
4810 if (!strcmp(keys[i].datatype,
"cstr"))
4811 strcpy((
char *)keys[i].address.cstr, clip_string(info));
4812 else if (!strcmp(keys[i].datatype,
"i32")) {
4813 if (sscanf(info,
"%d", keys[i].address.i32) != 1) {
4814 LOG_ERROR(
"libtcd error: invalid tide db header line:\n");
4815 LOG_ERROR(
"%s", varin);
4816 LOG_ERROR(
"in file %s\n", filename);
4820 }
else if (!strcmp(keys[i].datatype,
"ui32")) {
4821 if (sscanf(info,
"%u", keys[i].address.ui32) != 1) {
4822 LOG_ERROR(
"libtcd error: invalid tide db header line:\n");
4823 LOG_ERROR(
"%s", varin);
4824 LOG_ERROR(
"in file %s\n", filename);
4836 if (!strcmp(hd.pub.version,
"NO VERSION")) {
4837 LOG_ERROR(
"libtcd error: no version found in tide db header\n");
4838 LOG_ERROR(
"in file %s\n", filename);
4844 if (hd.pub.major_rev > LIBTCD_MAJOR_REV) {
4846 "libtcd error: major revision in TCD file (%u) exceeds major revision "
4849 LOG_ERROR(
"libtcd (%u). You must upgrade libtcd to read this file.\n",
4856 fseek(fp, hd.header_size, SEEK_SET);
4860 chk_fread(checksum_c, 4, 1, fp);
4861 utemp = bit_unpack(checksum_c, 0, 32);
4863 if (utemp != header_checksum()) {
4865 if (utemp != old_header_checksum()) {
4866 LOG_ERROR(
"libtcd error: header checksum error in file %s\n", filename);
4868 "Someone may have modified the ASCII portion of the header (don't do that),\n\
4869or it may just be corrupt.\n");
4874 LOG_ERROR(
"libtcd error: header checksum error in file %s\n", filename);
4876 "Someone may have modified the ASCII portion of the header (don't do that),\n\
4877or it may be an ancient pre-version-1.02 TCD file, or it may just be corrupt.\n\
4878Pre-version-1.02 TCD files can be read by building libtcd with COMPAT114\n\
4884 fseek(fp, hd.header_size + 4, SEEK_SET);
4889 hd.max_restriction_types = NINT(pow(2.0, (NV_FLOAT64)hd.restriction_bits));
4893 hd.max_tzfiles = NINT(pow(2.0, (NV_FLOAT64)hd.tzfile_bits));
4897 hd.max_countries = NINT(pow(2.0, (NV_FLOAT64)hd.country_bits));
4902 hd.max_datum_types = NINT(pow(2.0, (NV_FLOAT64)hd.datum_bits));
4907 if (hd.pub.major_rev < 2)
4908 hd.max_legaleses = 1;
4910 hd.max_legaleses = NINT(pow(2.0, (NV_FLOAT64)hd.legalese_bits));
4917 (NV_CHAR **)calloc(hd.pub.level_unit_types,
sizeof(NV_CHAR *));
4919 if ((buf = (NV_U_BYTE *)calloc(hd.level_unit_size,
sizeof(NV_U_BYTE))) ==
4921 perror(
"Allocating level unit read buffer");
4925 for (i = 0; i < hd.pub.level_unit_types; ++i) {
4926 chk_fread(buf, hd.level_unit_size, 1, fp);
4928 (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
4929 strcpy(hd.level_unit[i], (NV_CHAR *)buf);
4935 hd.dir_unit = (NV_CHAR **)calloc(hd.pub.dir_unit_types,
sizeof(NV_CHAR *));
4937 if ((buf = (NV_U_BYTE *)calloc(hd.dir_unit_size,
sizeof(NV_U_BYTE))) ==
4939 perror(
"Allocating dir unit read buffer");
4943 for (i = 0; i < hd.pub.dir_unit_types; ++i) {
4944 chk_fread(buf, hd.dir_unit_size, 1, fp);
4946 (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
4947 strcpy(hd.dir_unit[i], (NV_CHAR *)buf);
4955 (NV_CHAR **)calloc(hd.max_restriction_types,
sizeof(NV_CHAR *));
4957 if ((buf = (NV_U_BYTE *)calloc(hd.restriction_size,
sizeof(NV_U_BYTE))) ==
4959 perror(
"Allocating restriction read buffer");
4963 hd.pub.restriction_types = 0;
4964 for (i = 0; i < hd.max_restriction_types; ++i) {
4965 chk_fread(buf, hd.restriction_size, 1, fp);
4966 if (!strcmp((
char *)buf,
"__END__")) {
4967 hd.pub.restriction_types = i;
4971 (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
4972 strcpy(hd.restriction[i], (NV_CHAR *)buf);
4975 fseek(fp, utemp + hd.max_restriction_types * hd.restriction_size, SEEK_SET);
4978 if (hd.pub.major_rev < 2)
4979 fseek(fp, hd.pedigree_size * NINT(pow(2.0, (NV_FLOAT64)hd.pedigree_bits)),
4981 hd.pub.pedigree_types = 1;
4986 hd.tzfile = (NV_CHAR **)calloc(hd.max_tzfiles,
sizeof(NV_CHAR *));
4988 if ((buf = (NV_U_BYTE *)calloc(hd.tzfile_size,
sizeof(NV_U_BYTE))) == NULL) {
4989 perror(
"Allocating tzfile read buffer");
4994 for (i = 0; i < hd.max_tzfiles; ++i) {
4995 chk_fread(buf, hd.tzfile_size, 1, fp);
4996 if (!strcmp((
char *)buf,
"__END__")) {
5000 hd.tzfile[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
5001 strcpy(hd.tzfile[i], (NV_CHAR *)buf);
5004 fseek(fp, utemp + hd.max_tzfiles * hd.tzfile_size, SEEK_SET);
5009 hd.country = (NV_CHAR **)calloc(hd.max_countries,
sizeof(NV_CHAR *));
5011 if ((buf = (NV_U_BYTE *)calloc(hd.country_size,
sizeof(NV_U_BYTE))) == NULL) {
5012 perror(
"Allocating country read buffer");
5016 hd.pub.countries = 0;
5017 for (i = 0; i < hd.max_countries; ++i) {
5018 chk_fread(buf, hd.country_size, 1, fp);
5019 if (!strcmp((
char *)buf,
"__END__")) {
5020 hd.pub.countries = i;
5023 hd.country[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
5024 strcpy(hd.country[i], (NV_CHAR *)buf);
5027 fseek(fp, utemp + hd.max_countries * hd.country_size, SEEK_SET);
5032 hd.datum = (NV_CHAR **)calloc(hd.max_datum_types,
sizeof(NV_CHAR *));
5034 if ((buf = (NV_U_BYTE *)calloc(hd.datum_size,
sizeof(NV_U_BYTE))) == NULL) {
5035 perror(
"Allocating datum read buffer");
5039 hd.pub.datum_types = 0;
5040 for (i = 0; i < hd.max_datum_types; ++i) {
5041 chk_fread(buf, hd.datum_size, 1, fp);
5042 if (!strcmp((
char *)buf,
"__END__")) {
5043 hd.pub.datum_types = i;
5046 hd.datum[i] = (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
5047 strcpy(hd.datum[i], (NV_CHAR *)buf);
5050 fseek(fp, utemp + hd.max_datum_types * hd.datum_size, SEEK_SET);
5054 if (hd.pub.major_rev < 2) {
5055 hd.legalese = (NV_CHAR **)malloc(
sizeof(NV_CHAR *));
5056 assert(hd.legalese != NULL);
5057 hd.legalese[0] = (NV_CHAR *)malloc(5 *
sizeof(NV_CHAR));
5058 assert(hd.legalese[0] != NULL);
5059 strcpy(hd.legalese[0],
"NULL");
5060 hd.pub.legaleses = 1;
5063 hd.legalese = (NV_CHAR **)calloc(hd.max_legaleses,
sizeof(NV_CHAR *));
5065 if ((buf = (NV_U_BYTE *)calloc(hd.legalese_size,
sizeof(NV_U_BYTE))) ==
5067 perror(
"Allocating legalese read buffer");
5071 hd.pub.legaleses = 0;
5072 for (i = 0; i < hd.max_legaleses; ++i) {
5073 chk_fread(buf, hd.legalese_size, 1, fp);
5074 if (!strcmp((
char *)buf,
"__END__")) {
5075 hd.pub.legaleses = i;
5079 (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
5080 strcpy(hd.legalese[i], (NV_CHAR *)buf);
5083 fseek(fp, utemp + hd.max_legaleses * hd.legalese_size, SEEK_SET);
5088 hd.constituent = (NV_CHAR **)calloc(hd.pub.constituents,
sizeof(NV_CHAR *));
5090 if ((buf = (NV_U_BYTE *)calloc(hd.constituent_size,
sizeof(NV_U_BYTE))) ==
5092 perror(
"Allocating constituent read buffer");
5096 for (i = 0; i < hd.pub.constituents; ++i) {
5097 chk_fread(buf, hd.constituent_size, 1, fp);
5099 (NV_CHAR *)calloc(strlen((
char *)buf) + 1,
sizeof(NV_CHAR));
5100 strcpy(hd.constituent[i], (NV_CHAR *)buf);
5104 if (hd.speed_offset < 0 || hd.equilibrium_offset < 0 || hd.node_offset < 0) {
5105 LOG_ERROR(
"libtcd WARNING: File: %s\n", filename);
5107 "WARNING: This TCD file was created by a pre-version-1.11 libtcd.\n\
5108Versions of libtcd prior to 1.11 contained a serious bug that can result\n\
5109in overflows in the speeds, equilibrium arguments, or node factors. This\n\
5110database should be rebuilt from the original data if possible.\n");
5117 hd.speed = (NV_FLOAT64 *)calloc(hd.pub.constituents,
sizeof(NV_FLOAT64));
5121 if (hd.pub.major_rev < 2)
5122 size = ((hd.pub.constituents * hd.speed_bits) / 8) + 1;
5124 size = bits2bytes(hd.pub.constituents * hd.speed_bits);
5126 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
5127 perror(
"Allocating speed read buffer");
5131 chk_fread(buf, size, 1, fp);
5133 for (i = 0; i < hd.pub.constituents; ++i) {
5134 temp_int = bit_unpack(buf, pos, hd.speed_bits);
5135 hd.speed[i] = (NV_FLOAT64)(temp_int + hd.speed_offset) / hd.speed_scale;
5136 pos += hd.speed_bits;
5137 assert(hd.speed[i] >= 0.0);
5144 (NV_FLOAT32 **)calloc(hd.pub.constituents,
sizeof(NV_FLOAT32 *));
5146 for (i = 0; i < hd.pub.constituents; ++i) {
5148 (NV_FLOAT32 *)calloc(hd.pub.number_of_years,
sizeof(NV_FLOAT32));
5153 if (hd.pub.major_rev < 2)
5155 ((hd.pub.constituents * hd.pub.number_of_years * hd.equilibrium_bits) /
5159 size = bits2bytes(hd.pub.constituents * hd.pub.number_of_years *
5160 hd.equilibrium_bits);
5162 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
5163 perror(
"Allocating equilibrium read buffer");
5167 chk_fread(buf, size, 1, fp);
5169 for (i = 0; i < hd.pub.constituents; ++i) {
5170 for (j = 0; j < hd.pub.number_of_years; ++j) {
5171 temp_int = bit_unpack(buf, pos, hd.equilibrium_bits);
5172 hd.equilibrium[i][j] =
5173 (NV_FLOAT32)(temp_int + hd.equilibrium_offset) / hd.equilibrium_scale;
5174 pos += hd.equilibrium_bits;
5182 (NV_FLOAT32 **)calloc(hd.pub.constituents,
sizeof(NV_FLOAT32 *));
5184 for (i = 0; i < hd.pub.constituents; ++i) {
5186 (NV_FLOAT32 *)calloc(hd.pub.number_of_years,
sizeof(NV_FLOAT32));
5191 if (hd.pub.major_rev < 2)
5193 ((hd.pub.constituents * hd.pub.number_of_years * hd.node_bits) / 8) + 1;
5196 bits2bytes(hd.pub.constituents * hd.pub.number_of_years * hd.node_bits);
5198 if ((buf = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
5199 perror(
"Allocating node read buffer");
5203 chk_fread(buf, size, 1, fp);
5205 for (i = 0; i < hd.pub.constituents; ++i) {
5206 for (j = 0; j < hd.pub.number_of_years; ++j) {
5207 temp_int = bit_unpack(buf, pos, hd.node_bits);
5208 hd.node_factor[i][j] =
5209 (NV_FLOAT32)(temp_int + hd.node_offset) / hd.node_scale;
5210 pos += hd.node_bits;
5211 assert(hd.node_factor[i][j] > 0.0);
5220 if (hd.pub.number_of_records) {
5221 if ((tindex = (
TIDE_INDEX *)calloc(hd.pub.number_of_records,
5223 perror(
"Allocating tide index");
5227 tindex[0].address = ftell(fp);
5231 for (i = 0; i < hd.pub.number_of_records; ++i) {
5235 if (i) tindex[i].address = tindex[i - 1].address + rec.header.record_size;
5237 read_partial_tide_record(i, &rec);
5241 tindex[i].record_size = rec.header.record_size;
5242 tindex[i].record_type = rec.header.record_type;
5243 tindex[i].reference_station = rec.header.reference_station;
5244 assert(rec.header.tzfile >= 0);
5245 tindex[i].tzfile = rec.header.tzfile;
5246 tindex[i].lat = NINT(rec.header.latitude * hd.latitude_scale);
5247 tindex[i].lon = NINT(rec.header.longitude * hd.longitude_scale);
5249 if ((tindex[i].name = (NV_CHAR *)calloc(strlen(rec.header.name) + 1,
5250 sizeof(NV_CHAR))) == NULL) {
5251 perror(
"Allocating index name memory");
5255 strcpy(tindex[i].name, rec.header.name);
5258 current_record = -1;
5281NV_BOOL open_tide_db(
const NV_CHAR *file) {
5283 current_record = -1;
5286 if (!strcmp(file, filename) && !modified)
5291 if ((fp = fopen(file,
"rb+")) == NULL) {
5292 if ((fp = fopen(file,
"rb")) == NULL)
return (NVFalse);
5294 boundscheck_monologue(file);
5295 strcpy(filename, file);
5296 return (read_tide_db_header());
5317void close_tide_db() {
5321 LOG_ERROR(
"libtcd warning: close_tide_db called when no database open\n");
5328 if (modified) write_tide_db_header();
5332 assert(hd.constituent);
5333 for (i = 0; i < hd.pub.constituents; ++i) {
5334 if (hd.constituent[i] != NULL) free(hd.constituent[i]);
5336 free(hd.constituent);
5337 hd.constituent = NULL;
5339 if (hd.speed != NULL) free(hd.speed);
5341 assert(hd.equilibrium);
5342 for (i = 0; i < hd.pub.constituents; ++i) {
5343 if (hd.equilibrium[i] != NULL) free(hd.equilibrium[i]);
5345 free(hd.equilibrium);
5346 hd.equilibrium = NULL;
5348 assert(hd.node_factor);
5349 for (i = 0; i < hd.pub.constituents; ++i) {
5350 if (hd.node_factor[i] != NULL) free(hd.node_factor[i]);
5352 free(hd.node_factor);
5353 hd.node_factor = NULL;
5355 assert(hd.level_unit);
5356 for (i = 0; i < hd.pub.level_unit_types; ++i) {
5357 if (hd.level_unit[i] != NULL) free(hd.level_unit[i]);
5359 free(hd.level_unit);
5360 hd.level_unit = NULL;
5362 assert(hd.dir_unit);
5363 for (i = 0; i < hd.pub.dir_unit_types; ++i) {
5364 if (hd.dir_unit[i] != NULL) free(hd.dir_unit[i]);
5369 assert(hd.restriction);
5370 for (i = 0; i < hd.max_restriction_types; ++i) {
5371 if (hd.restriction[i] != NULL) free(hd.restriction[i]);
5373 free(hd.restriction);
5374 hd.restriction = NULL;
5376 assert(hd.legalese);
5377 for (i = 0; i < hd.max_legaleses; ++i) {
5378 if (hd.legalese[i] != NULL) free(hd.legalese[i]);
5384 for (i = 0; i < hd.max_tzfiles; ++i) {
5385 if (hd.tzfile[i] != NULL) free(hd.tzfile[i]);
5391 for (i = 0; i < hd.max_countries; ++i) {
5392 if (hd.country[i] != NULL) free(hd.country[i]);
5398 for (i = 0; i < hd.max_datum_types; ++i) {
5399 if (hd.datum[i] != NULL) free(hd.datum[i]);
5406 for (i = 0; i < hd.pub.number_of_records; ++i) {
5407 if (tindex[i].name) free(tindex[i].name);
5448NV_BOOL create_tide_db(
const NV_CHAR *file, NV_U_INT32 constituents,
5449 NV_CHAR
const *
const constituent[],
5450 const NV_FLOAT64 *speed, NV_INT32 start_year,
5451 NV_U_INT32 num_years,
5452 NV_FLOAT32
const *
const equilibrium[],
5453 NV_FLOAT32
const *
const node_factor[]) {
5455 NV_FLOAT64 min_value, max_value;
5460 assert(constituent);
5462 assert(equilibrium);
5463 assert(node_factor);
5464 for (i = 0; i < constituents; ++i) {
5465 if (speed[i] < 0.0) {
5467 "libtcd create_tide_db: somebody tried to set a negative speed "
5472 for (j = 0; j < num_years; ++j) {
5473 if (node_factor[i][j] <= 0.0) {
5475 "libtcd create_tide_db: somebody tried to set a negative or zero "
5476 "node factor (%f)\n",
5483 if (fp) close_tide_db();
5485 if ((fp = fopen(file,
"wb+")) == NULL) {
5492 memset(&hd, 0,
sizeof(hd));
5494 hd.pub.major_rev = LIBTCD_MAJOR_REV;
5495 hd.pub.minor_rev = LIBTCD_MINOR_REV;
5497 hd.header_size = DEFAULT_HEADER_SIZE;
5498 hd.pub.number_of_records = DEFAULT_NUMBER_OF_RECORDS;
5500 hd.pub.start_year = start_year;
5501 hd.pub.number_of_years = num_years;
5503 hd.pub.constituents = constituents;
5507 hd.constituent = (NV_CHAR **)calloc(hd.pub.constituents,
sizeof(NV_CHAR *));
5508 for (i = 0; i < hd.pub.constituents; ++i) {
5510 (NV_CHAR *)calloc(strlen(constituent[i]) + 1,
sizeof(NV_CHAR));
5511 strcpy(hd.constituent[i], constituent[i]);
5517 hd.constituent_bits = calculate_bits(hd.pub.constituents);
5521 hd.speed = (NV_FLOAT64 *)calloc(hd.pub.constituents,
sizeof(NV_FLOAT64));
5523 hd.speed_scale = DEFAULT_SPEED_SCALE;
5524 min_value = 99999999.0;
5525 max_value = -99999999.0;
5526 for (i = 0; i < hd.pub.constituents; ++i) {
5527 if (speed[i] < min_value) min_value = speed[i];
5528 if (speed[i] > max_value) max_value = speed[i];
5530 hd.speed[i] = speed[i];
5536 hd.speed_offset = (NINT(min_value * hd.speed_scale));
5537 temp_int = NINT(max_value * hd.speed_scale) - hd.speed_offset;
5538 assert(temp_int >= 0);
5539 hd.speed_bits = calculate_bits((NV_U_INT32)temp_int);
5541 assert(hd.speed_bits < 32);
5546 (NV_FLOAT32 **)calloc(hd.pub.constituents,
sizeof(NV_FLOAT32 *));
5548 hd.equilibrium_scale = DEFAULT_EQUILIBRIUM_SCALE;
5549 min_value = 99999999.0;
5550 max_value = -99999999.0;
5551 for (i = 0; i < hd.pub.constituents; ++i) {
5553 (NV_FLOAT32 *)calloc(hd.pub.number_of_years,
sizeof(NV_FLOAT32));
5554 for (j = 0; j < hd.pub.number_of_years; ++j) {
5555 if (equilibrium[i][j] < min_value) min_value = equilibrium[i][j];
5556 if (equilibrium[i][j] > max_value) max_value = equilibrium[i][j];
5558 hd.equilibrium[i][j] = equilibrium[i][j];
5565 hd.equilibrium_offset = (NINT(min_value * hd.equilibrium_scale));
5566 temp_int = NINT(max_value * hd.equilibrium_scale) - hd.equilibrium_offset;
5567 assert(temp_int >= 0);
5568 hd.equilibrium_bits = calculate_bits((NV_U_INT32)temp_int);
5573 (NV_FLOAT32 **)calloc(hd.pub.constituents,
sizeof(NV_FLOAT32 *));
5575 hd.node_scale = DEFAULT_NODE_SCALE;
5576 min_value = 99999999.0;
5577 max_value = -99999999.0;
5578 for (i = 0; i < hd.pub.constituents; ++i) {
5580 (NV_FLOAT32 *)calloc(hd.pub.number_of_years,
sizeof(NV_FLOAT32));
5581 for (j = 0; j < hd.pub.number_of_years; ++j) {
5582 if (node_factor[i][j] < min_value) min_value = node_factor[i][j];
5583 if (node_factor[i][j] > max_value) max_value = node_factor[i][j];
5585 hd.node_factor[i][j] = node_factor[i][j];
5592 hd.node_offset = (NINT(min_value * hd.node_scale));
5593 temp_int = NINT(max_value * hd.node_scale) - hd.node_offset;
5594 assert(temp_int >= 0);
5595 hd.node_bits = calculate_bits((NV_U_INT32)temp_int);
5599 hd.amplitude_bits = DEFAULT_AMPLITUDE_BITS;
5600 hd.amplitude_scale = DEFAULT_AMPLITUDE_SCALE;
5601 hd.epoch_bits = DEFAULT_EPOCH_BITS;
5602 hd.epoch_scale = DEFAULT_EPOCH_SCALE;
5604 hd.record_type_bits = DEFAULT_RECORD_TYPE_BITS;
5605 hd.latitude_bits = DEFAULT_LATITUDE_BITS;
5606 hd.latitude_scale = DEFAULT_LATITUDE_SCALE;
5607 hd.longitude_bits = DEFAULT_LONGITUDE_BITS;
5608 hd.longitude_scale = DEFAULT_LONGITUDE_SCALE;
5609 hd.record_size_bits = DEFAULT_RECORD_SIZE_BITS;
5611 hd.station_bits = DEFAULT_STATION_BITS;
5613 hd.datum_offset_bits = DEFAULT_DATUM_OFFSET_BITS;
5614 hd.datum_offset_scale = DEFAULT_DATUM_OFFSET_SCALE;
5615 hd.date_bits = DEFAULT_DATE_BITS;
5616 hd.months_on_station_bits = DEFAULT_MONTHS_ON_STATION_BITS;
5617 hd.confidence_value_bits = DEFAULT_CONFIDENCE_VALUE_BITS;
5619 hd.time_bits = DEFAULT_TIME_BITS;
5620 hd.level_add_bits = DEFAULT_LEVEL_ADD_BITS;
5621 hd.level_add_scale = DEFAULT_LEVEL_ADD_SCALE;
5622 hd.level_multiply_bits = DEFAULT_LEVEL_MULTIPLY_BITS;
5623 hd.level_multiply_scale = DEFAULT_LEVEL_MULTIPLY_SCALE;
5624 hd.direction_bits = DEFAULT_DIRECTION_BITS;
5626 hd.constituent_size = DEFAULT_CONSTITUENT_SIZE;
5627 hd.level_unit_size = DEFAULT_LEVEL_UNIT_SIZE;
5628 hd.dir_unit_size = DEFAULT_DIR_UNIT_SIZE;
5629 hd.restriction_size = DEFAULT_RESTRICTION_SIZE;
5630 hd.tzfile_size = DEFAULT_TZFILE_SIZE;
5631 hd.country_size = DEFAULT_COUNTRY_SIZE;
5632 hd.datum_size = DEFAULT_DATUM_SIZE;
5633 hd.legalese_size = DEFAULT_LEGALESE_SIZE;
5637 hd.pub.level_unit_types = DEFAULT_LEVEL_UNIT_TYPES;
5638 hd.level_unit_bits = calculate_bits(hd.pub.level_unit_types - 1);
5641 (NV_CHAR **)calloc(hd.pub.level_unit_types,
sizeof(NV_CHAR *));
5642 for (i = 0; i < hd.pub.level_unit_types; ++i) {
5644 (NV_CHAR *)calloc(strlen(level_unit[i]) + 1,
sizeof(NV_CHAR));
5645 strcpy(hd.level_unit[i], level_unit[i]);
5650 hd.pub.dir_unit_types = DEFAULT_DIR_UNIT_TYPES;
5651 hd.dir_unit_bits = calculate_bits(hd.pub.dir_unit_types - 1);
5653 hd.dir_unit = (NV_CHAR **)calloc(hd.pub.dir_unit_types,
sizeof(NV_CHAR *));
5654 for (i = 0; i < hd.pub.dir_unit_types; ++i) {
5656 (NV_CHAR *)calloc(strlen(dir_unit[i]) + 1,
sizeof(NV_CHAR));
5657 strcpy(hd.dir_unit[i], dir_unit[i]);
5662 hd.restriction_bits = DEFAULT_RESTRICTION_BITS;
5663 hd.max_restriction_types = NINT(pow(2.0, (NV_FLOAT64)hd.restriction_bits));
5664 hd.pub.restriction_types = DEFAULT_RESTRICTION_TYPES;
5667 (NV_CHAR **)calloc(hd.max_restriction_types,
sizeof(NV_CHAR *));
5668 for (i = 0; i < hd.max_restriction_types; ++i) {
5669 if (i == hd.pub.restriction_types)
break;
5672 (NV_CHAR *)calloc(strlen(restriction[i]) + 1,
sizeof(NV_CHAR));
5673 strcpy(hd.restriction[i], restriction[i]);
5678 hd.legalese_bits = DEFAULT_LEGALESE_BITS;
5679 hd.max_legaleses = NINT(pow(2.0, (NV_FLOAT64)hd.legalese_bits));
5680 hd.pub.legaleses = DEFAULT_LEGALESES;
5682 hd.legalese = (NV_CHAR **)calloc(hd.max_legaleses,
sizeof(NV_CHAR *));
5683 for (i = 0; i < hd.max_legaleses; ++i) {
5684 if (i == hd.pub.legaleses)
break;
5687 (NV_CHAR *)calloc(strlen(legalese[i]) + 1,
sizeof(NV_CHAR));
5688 strcpy(hd.legalese[i], legalese[i]);
5693 hd.tzfile_bits = DEFAULT_TZFILE_BITS;
5694 hd.max_tzfiles = NINT(pow(2.0, (NV_FLOAT64)hd.tzfile_bits));
5695 hd.pub.tzfiles = DEFAULT_TZFILES;
5697 hd.tzfile = (NV_CHAR **)calloc(hd.max_tzfiles,
sizeof(NV_CHAR *));
5698 for (i = 0; i < hd.max_tzfiles; ++i) {
5699 if (i == hd.pub.tzfiles)
break;
5701 hd.tzfile[i] = (NV_CHAR *)calloc(strlen(tzfile[i]) + 1,
sizeof(NV_CHAR));
5702 strcpy(hd.tzfile[i], tzfile[i]);
5707 hd.country_bits = DEFAULT_COUNTRY_BITS;
5708 hd.max_countries = NINT(pow(2.0, (NV_FLOAT64)hd.country_bits));
5709 hd.pub.countries = DEFAULT_COUNTRIES;
5711 hd.country = (NV_CHAR **)calloc(hd.max_countries,
sizeof(NV_CHAR *));
5712 for (i = 0; i < hd.max_countries; ++i) {
5713 if (i == hd.pub.countries)
break;
5715 hd.country[i] = (NV_CHAR *)calloc(strlen(country[i]) + 1,
sizeof(NV_CHAR));
5716 strcpy(hd.country[i], country[i]);
5721 hd.datum_bits = DEFAULT_DATUM_BITS;
5722 hd.max_datum_types = NINT(pow(2.0, (NV_FLOAT64)hd.datum_bits));
5723 hd.pub.datum_types = DEFAULT_DATUM_TYPES;
5725 hd.datum = (NV_CHAR **)calloc(hd.max_datum_types,
sizeof(NV_CHAR *));
5726 for (i = 0; i < hd.max_datum_types; ++i) {
5727 if (i == hd.pub.datum_types)
break;
5729 hd.datum[i] = (NV_CHAR *)calloc(strlen(datum[i]) + 1,
sizeof(NV_CHAR));
5730 strcpy(hd.datum[i], datum[i]);
5740 i = (open_tide_db(file));
5744 hd.end_of_file = ftell(fp);
5748 write_tide_db_header();
5757static NV_BOOL check_date(NV_U_INT32 date) {
5763 if (m < 1 || m > 12 || d < 1 || d > 31)
return NVFalse;
5777static NV_BOOL check_tide_record(
TIDE_RECORD *rec) {
5779 NV_BOOL ret = NVTrue;
5782 LOG_ERROR(
"libtcd error: null pointer passed to check_tide_record\n");
5788 boundscheck_oneliner(rec->header.name);
5789 boundscheck_oneliner(rec->source);
5790 boundscheck_monologue(rec->comments);
5791 boundscheck_monologue(rec->notes);
5792 boundscheck_oneliner(rec->station_id_context);
5793 boundscheck_oneliner(rec->station_id);
5794 boundscheck_monologue(rec->xfields);
5797 if (rec->header.record_type == REFERENCE_STATION && rec->units > 0)
5798 rec->level_units = rec->units;
5801 if (rec->header.latitude < -90.0 || rec->header.latitude > 90.0 ||
5802 rec->header.longitude < -180.0 || rec->header.longitude > 180.0) {
5803 LOG_ERROR(
"libtcd error: bad coordinates in tide record\n");
5807 if (rec->header.tzfile < 0 ||
5808 rec->header.tzfile >= (NV_INT32)hd.pub.tzfiles) {
5809 LOG_ERROR(
"libtcd error: bad tzfile in tide record\n");
5813 if (rec->header.name[0] ==
'\0') {
5814 LOG_ERROR(
"libtcd error: null name in tide record\n");
5818 if (rec->country < 0 || rec->country >= (NV_INT32)hd.pub.countries) {
5819 LOG_ERROR(
"libtcd error: bad country in tide record\n");
5823 if (rec->restriction >= hd.pub.restriction_types) {
5824 LOG_ERROR(
"libtcd error: bad restriction in tide record\n");
5828 if (rec->legalese >= hd.pub.legaleses) {
5829 LOG_ERROR(
"libtcd error: bad legalese in tide record\n");
5833 if (!check_date(rec->date_imported)) {
5834 LOG_ERROR(
"libtcd error: bad date_imported in tide record\n");
5838 if (rec->direction_units >= hd.pub.dir_unit_types) {
5839 LOG_ERROR(
"libtcd error: bad direction_units in tide record\n");
5843 if (rec->min_direction < 0 || rec->min_direction > 361) {
5844 LOG_ERROR(
"libtcd error: min_direction out of range in tide record\n");
5848 if (rec->max_direction < 0 || rec->max_direction > 361) {
5849 LOG_ERROR(
"libtcd error: max_direction out of range in tide record\n");
5853 if (rec->level_units >= hd.pub.level_unit_types) {
5854 LOG_ERROR(
"libtcd error: bad units in tide record\n");
5858 switch (rec->header.record_type) {
5859 case REFERENCE_STATION:
5860 if (rec->header.reference_station != -1) {
5861 LOG_ERROR(
"libtcd error: type 1 record, reference_station != -1\n");
5865 if (rec->datum_offset < -13421.7728 || rec->datum_offset > 13421.7727) {
5866 LOG_ERROR(
"libtcd error: datum_offset out of range in tide record\n");
5870 if (rec->datum < 0 || rec->datum >= (NV_INT32)hd.pub.datum_types) {
5871 LOG_ERROR(
"libtcd error: bad datum in tide record\n");
5875 if (rec->zone_offset < -4096 || rec->zone_offset > 4095 ||
5876 rec->zone_offset % 100 >= 60) {
5877 LOG_ERROR(
"libtcd error: bad zone_offset in tide record\n");
5881 if (!check_date(rec->expiration_date)) {
5882 LOG_ERROR(
"libtcd error: bad expiration_date in tide record\n");
5886 if (rec->months_on_station > 1023) {
5888 "libtcd error: months_on_station out of range in tide record\n");
5892 if (!check_date(rec->last_date_on_station)) {
5893 LOG_ERROR(
"libtcd error: bad last_date_on_station in tide record\n");
5897 if (rec->confidence > 15) {
5898 LOG_ERROR(
"libtcd error: confidence out of range in tide record\n");
5903 for (i = 0; i < hd.pub.constituents; ++i) {
5904 if (rec->amplitude[i] < 0.0 || rec->amplitude[i] > 52.4287) {
5906 "libtcd error: constituent amplitude out of range in tide "
5912 for (i = 0; i < hd.pub.constituents; ++i) {
5913 if (rec->epoch[i] < 0.0 || rec->epoch[i] > 360.0) {
5915 "libtcd error: constituent epoch out of range in tide record\n");
5923 case SUBORDINATE_STATION:
5924 if (rec->header.reference_station < 0 ||
5925 rec->header.reference_station >= (NV_INT32)hd.pub.number_of_records) {
5926 LOG_ERROR(
"libtcd error: bad reference_station in tide record\n");
5930 if (rec->min_time_add < -4096 || rec->min_time_add > 4095 ||
5931 rec->min_time_add % 100 >= 60) {
5932 LOG_ERROR(
"libtcd error: bad min_time_add in tide record\n");
5936 if (rec->min_level_add < -65.536 || rec->min_level_add > 65.535) {
5937 LOG_ERROR(
"libtcd error: min_level_add out of range in tide record\n");
5941 if (rec->min_level_multiply < 0.0 || rec->min_level_multiply > 65.535) {
5943 "libtcd error: min_level_multiply out of range in tide record\n");
5947 if (rec->max_time_add < -4096 || rec->max_time_add > 4095 ||
5948 rec->max_time_add % 100 >= 60) {
5949 LOG_ERROR(
"libtcd error: bad max_time_add in tide record\n");
5953 if (rec->max_level_add < -65.536 || rec->max_level_add > 65.535) {
5954 LOG_ERROR(
"libtcd error: max_level_add out of range in tide record\n");
5958 if (rec->max_level_multiply < 0.0 || rec->max_level_multiply > 65.535) {
5960 "libtcd error: max_level_multiply out of range in tide record\n");
5964 if (rec->flood_begins != NULLSLACKOFFSET &&
5965 (rec->flood_begins < -4096 || rec->flood_begins > 4095 ||
5966 rec->flood_begins % 100 >= 60)) {
5967 LOG_ERROR(
"libtcd error: bad flood_begins in tide record\n");
5971 if (rec->ebb_begins != NULLSLACKOFFSET &&
5972 (rec->ebb_begins < -4096 || rec->ebb_begins > 4095 ||
5973 rec->ebb_begins % 100 >= 60)) {
5974 LOG_ERROR(
"libtcd error: bad ebb_begins in tide record\n");
5981 LOG_ERROR(
"libtcd error: invalid record_type in tide record\n");
5985 if (ret == NVFalse) dump_tide_record(rec);
5996 NV_U_INT32 i, count = 0, name_size, source_size, comments_size, notes_size,
5997 station_id_context_size, station_id_size, xfields_size;
6003 name_size = strlen(clip_string(rec->header.name)) + 1;
6004 source_size = strlen(clip_string(rec->source)) + 1;
6005 comments_size = strlen(clip_string(rec->comments)) + 1;
6006 notes_size = strlen(clip_string(rec->notes)) + 1;
6007 station_id_context_size = strlen(clip_string(rec->station_id_context)) + 1;
6008 station_id_size = strlen(clip_string(rec->station_id)) + 1;
6010 xfields_size = strlen(rec->xfields) + 1;
6012 rec->header.record_size =
6013 hd.record_size_bits + hd.record_type_bits + hd.latitude_bits +
6014 hd.longitude_bits + hd.station_bits + hd.tzfile_bits + (name_size * 8) +
6016 hd.country_bits + (source_size * 8) + hd.restriction_bits +
6017 (comments_size * 8) + (notes_size * 8) + hd.legalese_bits +
6018 (station_id_context_size * 8) + (station_id_size * 8) + hd.date_bits +
6019 (xfields_size * 8) + hd.dir_unit_bits + hd.direction_bits +
6020 hd.direction_bits + hd.level_unit_bits;
6022 switch (rec->header.record_type) {
6023 case REFERENCE_STATION:
6024 rec->header.record_size += hd.datum_offset_bits + hd.datum_bits +
6025 hd.time_bits + hd.date_bits +
6026 hd.months_on_station_bits + hd.date_bits +
6027 hd.confidence_value_bits + hd.constituent_bits;
6029 for (i = 0; i < hd.pub.constituents; ++i) {
6030 assert(rec->amplitude[i] >= 0.0);
6031 if (rec->amplitude[i] >= AMPLITUDE_EPSILON) ++count;
6034 rec->header.record_size +=
6035 (count * hd.constituent_bits + count * hd.amplitude_bits +
6036 count * hd.epoch_bits);
6040 case SUBORDINATE_STATION:
6041 rec->header.record_size += hd.time_bits + hd.level_add_bits +
6042 hd.level_multiply_bits + hd.time_bits +
6043 hd.level_add_bits + hd.level_multiply_bits +
6044 hd.time_bits + hd.time_bits;
6051 rec->header.record_size = bits2bytes(rec->header.record_size);
6058static void pack_string(NV_U_BYTE *buf, NV_U_INT32 *pos, NV_CHAR *s) {
6059 NV_U_INT32 i, temp_size;
6063 temp_size = strlen(s) + 1;
6064 for (i = 0; i < temp_size; ++i) {
6065 bit_pack(buf, *pos, 8, s[i]);
6090static void pack_tide_record(
TIDE_RECORD *rec, NV_U_BYTE **bufptr,
6091 NV_U_INT32 *bufsize) {
6092 NV_U_INT32 i, pos, constituent_count;
6101 boundscheck_oneliner(rec->header.name);
6102 boundscheck_oneliner(rec->source);
6103 boundscheck_monologue(rec->comments);
6104 boundscheck_monologue(rec->notes);
6105 boundscheck_oneliner(rec->station_id_context);
6106 boundscheck_oneliner(rec->station_id);
6107 boundscheck_monologue(rec->xfields);
6109 constituent_count = figure_size(rec);
6112 (NV_U_BYTE *)calloc(rec->header.record_size,
sizeof(NV_U_BYTE)))) {
6113 perror(
"libtcd can't allocate memory in pack_tide_record");
6123 bit_pack(buf, pos, hd.record_size_bits, rec->header.record_size);
6124 pos += hd.record_size_bits;
6126 bit_pack(buf, pos, hd.record_type_bits, rec->header.record_type);
6127 pos += hd.record_type_bits;
6129 temp_int = NINT(rec->header.latitude * hd.latitude_scale);
6130 bit_pack(buf, pos, hd.latitude_bits, temp_int);
6131 pos += hd.latitude_bits;
6133 temp_int = NINT(rec->header.longitude * hd.longitude_scale);
6134 bit_pack(buf, pos, hd.longitude_bits, temp_int);
6135 pos += hd.longitude_bits;
6141 bit_pack(buf, pos, hd.tzfile_bits, rec->header.tzfile);
6142 pos += hd.tzfile_bits;
6144 pack_string(buf, &pos, clip_string(rec->header.name));
6146 bit_pack(buf, pos, hd.station_bits, rec->header.reference_station);
6147 pos += hd.station_bits;
6149 bit_pack(buf, pos, hd.country_bits, rec->country);
6150 pos += hd.country_bits;
6152 pack_string(buf, &pos, clip_string(rec->source));
6154 bit_pack(buf, pos, hd.restriction_bits, rec->restriction);
6155 pos += hd.restriction_bits;
6157 pack_string(buf, &pos, clip_string(rec->comments));
6158 pack_string(buf, &pos, clip_string(rec->notes));
6160 bit_pack(buf, pos, hd.legalese_bits, rec->legalese);
6161 pos += hd.legalese_bits;
6163 pack_string(buf, &pos, clip_string(rec->station_id_context));
6164 pack_string(buf, &pos, clip_string(rec->station_id));
6166 bit_pack(buf, pos, hd.date_bits, rec->date_imported);
6167 pos += hd.date_bits;
6170 pack_string(buf, &pos, rec->xfields);
6172 bit_pack(buf, pos, hd.dir_unit_bits, rec->direction_units);
6173 pos += hd.dir_unit_bits;
6175 bit_pack(buf, pos, hd.direction_bits, rec->min_direction);
6176 pos += hd.direction_bits;
6178 bit_pack(buf, pos, hd.direction_bits, rec->max_direction);
6179 pos += hd.direction_bits;
6182 bit_pack(buf, pos, hd.level_unit_bits, rec->level_units);
6183 pos += hd.level_unit_bits;
6187 if (rec->header.record_type == REFERENCE_STATION) {
6188 temp_int = NINT(rec->datum_offset * hd.datum_offset_scale);
6189 bit_pack(buf, pos, hd.datum_offset_bits, temp_int);
6190 pos += hd.datum_offset_bits;
6192 bit_pack(buf, pos, hd.datum_bits, rec->datum);
6193 pos += hd.datum_bits;
6195 bit_pack(buf, pos, hd.time_bits, rec->zone_offset);
6196 pos += hd.time_bits;
6198 bit_pack(buf, pos, hd.date_bits, rec->expiration_date);
6199 pos += hd.date_bits;
6201 bit_pack(buf, pos, hd.months_on_station_bits, rec->months_on_station);
6202 pos += hd.months_on_station_bits;
6204 bit_pack(buf, pos, hd.date_bits, rec->last_date_on_station);
6205 pos += hd.date_bits;
6207 bit_pack(buf, pos, hd.confidence_value_bits, rec->confidence);
6208 pos += hd.confidence_value_bits;
6210 bit_pack(buf, pos, hd.constituent_bits, constituent_count);
6211 pos += hd.constituent_bits;
6213 for (i = 0; i < hd.pub.constituents; ++i) {
6214 if (rec->amplitude[i] >= AMPLITUDE_EPSILON) {
6215 bit_pack(buf, pos, hd.constituent_bits, i);
6216 pos += hd.constituent_bits;
6218 temp_int = NINT(rec->amplitude[i] * hd.amplitude_scale);
6220 bit_pack(buf, pos, hd.amplitude_bits, temp_int);
6221 pos += hd.amplitude_bits;
6223 temp_int = NINT(rec->epoch[i] * hd.epoch_scale);
6224 bit_pack(buf, pos, hd.epoch_bits, temp_int);
6225 pos += hd.epoch_bits;
6231 else if (rec->header.record_type == SUBORDINATE_STATION) {
6232 bit_pack(buf, pos, hd.time_bits, rec->min_time_add);
6233 pos += hd.time_bits;
6235 temp_int = NINT(rec->min_level_add * hd.level_add_scale);
6236 bit_pack(buf, pos, hd.level_add_bits, temp_int);
6237 pos += hd.level_add_bits;
6239 temp_int = NINT(rec->min_level_multiply * hd.level_multiply_scale);
6240 bit_pack(buf, pos, hd.level_multiply_bits, temp_int);
6241 pos += hd.level_multiply_bits;
6243 bit_pack(buf, pos, hd.time_bits, rec->max_time_add);
6244 pos += hd.time_bits;
6246 temp_int = NINT(rec->max_level_add * hd.level_add_scale);
6247 bit_pack(buf, pos, hd.level_add_bits, temp_int);
6248 pos += hd.level_add_bits;
6250 temp_int = NINT(rec->max_level_multiply * hd.level_multiply_scale);
6251 bit_pack(buf, pos, hd.level_multiply_bits, temp_int);
6252 pos += hd.level_multiply_bits;
6254 bit_pack(buf, pos, hd.time_bits, rec->flood_begins);
6255 pos += hd.time_bits;
6257 bit_pack(buf, pos, hd.time_bits, rec->ebb_begins);
6258 pos += hd.time_bits;
6262 LOG_ERROR(
"libtcd error: Record type %d is undefined\n",
6263 rec->header.record_type);
6267 *bufsize = rec->header.record_size;
6268 assert(*bufsize == bits2bytes(pos));
6293static NV_BOOL write_tide_record(NV_INT32 num,
TIDE_RECORD *rec) {
6294 NV_U_BYTE *buf = NULL;
6295 NV_U_INT32 bufsize = 0;
6299 "libtcd error: attempt to access database when database not open\n");
6304 pack_tide_record(rec, &buf, &bufsize);
6309 fseek(fp, tindex[num].address, SEEK_SET);
6313 chk_fwrite(buf, bufsize, 1, fp);
6338 return (read_tide_record(current_record + 1, rec));
6362static void unpack_tide_record(NV_U_BYTE *buf, NV_U_INT32 bufsize,
6365 NV_U_INT32 i, j, pos, count;
6372 int r = find_dir_units(
"degrees true");
6374 rec->direction_units = (NV_U_BYTE)r;
6376 rec->min_direction = rec->max_direction = 361;
6377 rec->flood_begins = rec->ebb_begins = NULLSLACKOFFSET;
6378 rec->header.record_number = current_record;
6380 unpack_partial_tide_record(buf, bufsize, rec, &pos);
6382 switch (rec->header.record_type) {
6383 case REFERENCE_STATION:
6384 case SUBORDINATE_STATION:
6387 LOG_ERROR(
"libtcd fatal error: tried to read type %d tide record.\n",
6388 rec->header.record_type);
6390 "This version of libtcd only supports types 1 and 2. Perhaps you "
6391 "should\nupgrade.\n");
6395 switch (hd.pub.major_rev) {
6402 rec->country = bit_unpack(buf, pos, hd.country_bits);
6403 pos += hd.country_bits;
6406 pos += hd.pedigree_bits;
6408 unpack_string(buf, bufsize, &pos, rec->source, ONELINER_LENGTH,
6411 rec->restriction = bit_unpack(buf, pos, hd.restriction_bits);
6412 pos += hd.restriction_bits;
6414 unpack_string(buf, bufsize, &pos, rec->comments, MONOLOGUE_LENGTH,
6417 if (rec->header.record_type == REFERENCE_STATION) {
6418 rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
6420 rec->units = rec->level_units;
6422 pos += hd.level_unit_bits;
6424 temp_int = signed_bit_unpack(buf, pos, hd.datum_offset_bits);
6425 rec->datum_offset = (NV_FLOAT32)temp_int / hd.datum_offset_scale;
6426 pos += hd.datum_offset_bits;
6428 rec->datum = bit_unpack(buf, pos, hd.datum_bits);
6429 pos += hd.datum_bits;
6431 rec->zone_offset = signed_bit_unpack(buf, pos, hd.time_bits);
6432 pos += hd.time_bits;
6434 rec->expiration_date = bit_unpack(buf, pos, hd.date_bits);
6435 pos += hd.date_bits;
6437 rec->months_on_station =
6438 bit_unpack(buf, pos, hd.months_on_station_bits);
6439 pos += hd.months_on_station_bits;
6441 rec->last_date_on_station = bit_unpack(buf, pos, hd.date_bits);
6442 pos += hd.date_bits;
6444 rec->confidence = bit_unpack(buf, pos, hd.confidence_value_bits);
6445 pos += hd.confidence_value_bits;
6447 for (i = 0; i < hd.pub.constituents; ++i) {
6448 rec->amplitude[i] = 0.0;
6449 rec->epoch[i] = 0.0;
6452 count = bit_unpack(buf, pos, hd.constituent_bits);
6453 pos += hd.constituent_bits;
6455 for (i = 0; i < count; ++i) {
6456 j = bit_unpack(buf, pos, hd.constituent_bits);
6457 pos += hd.constituent_bits;
6460 (NV_FLOAT32)bit_unpack(buf, pos, hd.amplitude_bits) /
6462 pos += hd.amplitude_bits;
6465 (NV_FLOAT32)bit_unpack(buf, pos, hd.epoch_bits) / hd.epoch_scale;
6466 pos += hd.epoch_bits;
6468 }
else if (rec->header.record_type == SUBORDINATE_STATION) {
6469 rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
6470 pos += hd.level_unit_bits;
6472 rec->direction_units = bit_unpack(buf, pos, hd.dir_unit_bits);
6473 pos += hd.dir_unit_bits;
6476 pos += hd.level_unit_bits;
6478 rec->min_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
6479 pos += hd.time_bits;
6481 temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
6482 rec->min_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
6483 pos += hd.level_add_bits;
6486 temp_int = signed_bit_unpack(buf, pos, hd.level_multiply_bits);
6487 rec->min_level_multiply =
6488 (NV_FLOAT32)temp_int / hd.level_multiply_scale;
6489 pos += hd.level_multiply_bits;
6492 pos += hd.level_add_bits;
6494 rec->min_direction = bit_unpack(buf, pos, hd.direction_bits);
6495 pos += hd.direction_bits;
6497 rec->max_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
6498 pos += hd.time_bits;
6500 temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
6501 rec->max_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
6502 pos += hd.level_add_bits;
6505 temp_int = signed_bit_unpack(buf, pos, hd.level_multiply_bits);
6506 rec->max_level_multiply =
6507 (NV_FLOAT32)temp_int / hd.level_multiply_scale;
6508 pos += hd.level_multiply_bits;
6511 pos += hd.level_add_bits;
6513 rec->max_direction = bit_unpack(buf, pos, hd.direction_bits);
6514 pos += hd.direction_bits;
6516 rec->flood_begins = signed_bit_unpack(buf, pos, hd.time_bits);
6517 pos += hd.time_bits;
6519 rec->ebb_begins = signed_bit_unpack(buf, pos, hd.time_bits);
6520 pos += hd.time_bits;
6528 rec->country = bit_unpack(buf, pos, hd.country_bits);
6529 pos += hd.country_bits;
6531 unpack_string(buf, bufsize, &pos, rec->source, ONELINER_LENGTH,
6534 rec->restriction = bit_unpack(buf, pos, hd.restriction_bits);
6535 pos += hd.restriction_bits;
6537 unpack_string(buf, bufsize, &pos, rec->comments, MONOLOGUE_LENGTH,
6539 unpack_string(buf, bufsize, &pos, rec->notes, MONOLOGUE_LENGTH,
6542 rec->legalese = bit_unpack(buf, pos, hd.legalese_bits);
6543 pos += hd.legalese_bits;
6545 unpack_string(buf, bufsize, &pos, rec->station_id_context,
6546 ONELINER_LENGTH,
"station_id_context field");
6547 unpack_string(buf, bufsize, &pos, rec->station_id, ONELINER_LENGTH,
6548 "station_id field");
6550 rec->date_imported = bit_unpack(buf, pos, hd.date_bits);
6551 pos += hd.date_bits;
6553 unpack_string(buf, bufsize, &pos, rec->xfields, MONOLOGUE_LENGTH,
6556 rec->direction_units = bit_unpack(buf, pos, hd.dir_unit_bits);
6557 pos += hd.dir_unit_bits;
6559 rec->min_direction = bit_unpack(buf, pos, hd.direction_bits);
6560 pos += hd.direction_bits;
6562 rec->max_direction = bit_unpack(buf, pos, hd.direction_bits);
6563 pos += hd.direction_bits;
6565 rec->level_units = bit_unpack(buf, pos, hd.level_unit_bits);
6567 rec->units = rec->level_units;
6569 pos += hd.level_unit_bits;
6571 if (rec->header.record_type == REFERENCE_STATION) {
6572 temp_int = signed_bit_unpack(buf, pos, hd.datum_offset_bits);
6573 rec->datum_offset = (NV_FLOAT32)temp_int / hd.datum_offset_scale;
6574 pos += hd.datum_offset_bits;
6576 rec->datum = bit_unpack(buf, pos, hd.datum_bits);
6577 pos += hd.datum_bits;
6579 rec->zone_offset = signed_bit_unpack(buf, pos, hd.time_bits);
6580 pos += hd.time_bits;
6582 rec->expiration_date = bit_unpack(buf, pos, hd.date_bits);
6583 pos += hd.date_bits;
6585 rec->months_on_station =
6586 bit_unpack(buf, pos, hd.months_on_station_bits);
6587 pos += hd.months_on_station_bits;
6589 rec->last_date_on_station = bit_unpack(buf, pos, hd.date_bits);
6590 pos += hd.date_bits;
6592 rec->confidence = bit_unpack(buf, pos, hd.confidence_value_bits);
6593 pos += hd.confidence_value_bits;
6595 for (i = 0; i < hd.pub.constituents; ++i) {
6596 rec->amplitude[i] = 0.0;
6597 rec->epoch[i] = 0.0;
6600 count = bit_unpack(buf, pos, hd.constituent_bits);
6601 pos += hd.constituent_bits;
6603 for (i = 0; i < count; ++i) {
6604 j = bit_unpack(buf, pos, hd.constituent_bits);
6605 pos += hd.constituent_bits;
6608 (NV_FLOAT32)bit_unpack(buf, pos, hd.amplitude_bits) /
6610 pos += hd.amplitude_bits;
6613 (NV_FLOAT32)bit_unpack(buf, pos, hd.epoch_bits) / hd.epoch_scale;
6614 pos += hd.epoch_bits;
6616 }
else if (rec->header.record_type == SUBORDINATE_STATION) {
6617 rec->min_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
6618 pos += hd.time_bits;
6620 temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
6621 rec->min_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
6622 pos += hd.level_add_bits;
6625 temp_int = bit_unpack(buf, pos, hd.level_multiply_bits);
6626 rec->min_level_multiply =
6627 (NV_FLOAT32)temp_int / hd.level_multiply_scale;
6628 pos += hd.level_multiply_bits;
6630 rec->max_time_add = signed_bit_unpack(buf, pos, hd.time_bits);
6631 pos += hd.time_bits;
6633 temp_int = signed_bit_unpack(buf, pos, hd.level_add_bits);
6634 rec->max_level_add = (NV_FLOAT32)temp_int / hd.level_add_scale;
6635 pos += hd.level_add_bits;
6638 temp_int = bit_unpack(buf, pos, hd.level_multiply_bits);
6639 rec->max_level_multiply =
6640 (NV_FLOAT32)temp_int / hd.level_multiply_scale;
6641 pos += hd.level_multiply_bits;
6643 rec->flood_begins = signed_bit_unpack(buf, pos, hd.time_bits);
6644 pos += hd.time_bits;
6646 rec->ebb_begins = signed_bit_unpack(buf, pos, hd.time_bits);
6647 pos += hd.time_bits;
6657 assert(pos <= bufsize * 8);
6681NV_INT32 read_tide_record(NV_INT32 num,
TIDE_RECORD *rec) {
6687 "libtcd error: attempt to access database when database not open\n");
6691 if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records)
return -1;
6694 bufsize = tindex[num].record_size;
6695 if ((buf = (NV_U_BYTE *)calloc(bufsize,
sizeof(NV_U_BYTE))) == NULL) {
6696 perror(
"Allocating read_tide_record buffer");
6700 current_record = num;
6701 require(fseek(fp, tindex[num].address, SEEK_SET) == 0);
6702 chk_fread(buf, tindex[num].record_size, 1, fp);
6703 unpack_tide_record(buf, bufsize, rec);
6730 "libtcd error: attempt to access database when database not open\n");
6735 if (!check_tide_record(rec))
return NVFalse;
6737 fseek(fp, hd.end_of_file, SEEK_SET);
6741 rec->header.record_number = hd.pub.number_of_records++;
6743 if (write_tide_record(-1, rec)) {
6745 tindex, hd.pub.number_of_records *
sizeof(
TIDE_INDEX))) == NULL) {
6746 perror(
"Allocating more index records");
6750 tindex[rec->header.record_number].address = pos;
6751 tindex[rec->header.record_number].record_size = rec->header.record_size;
6752 tindex[rec->header.record_number].record_type = rec->header.record_type;
6753 tindex[rec->header.record_number].reference_station =
6754 rec->header.reference_station;
6755 assert(rec->header.tzfile >= 0);
6756 tindex[rec->header.record_number].tzfile = rec->header.tzfile;
6757 tindex[rec->header.record_number].lat =
6758 NINT(rec->header.latitude * hd.latitude_scale);
6759 tindex[rec->header.record_number].lon =
6760 NINT(rec->header.longitude * hd.longitude_scale);
6762 if ((tindex[rec->header.record_number].name = (NV_CHAR *)calloc(
6763 strlen(rec->header.name) + 1,
sizeof(NV_CHAR))) == NULL) {
6764 perror(
"Allocating index name memory");
6768 strcpy(tindex[rec->header.record_number].name, rec->header.name);
6771 hd.end_of_file = pos;
6775 if (db) *db = hd.pub;
6804 NV_INT32 i, newrecnum, *map;
6805 NV_U_BYTE **allrecs_packed;
6808 LOG_ERROR (
"libtcd error: attempt to access database when database not open\n");
6813 if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records)
return NVFalse;
6817 if (!(map = (NV_INT32 *) malloc (hd.pub.number_of_records *
sizeof(NV_INT32)))) {
6818 perror (
"libtcd: delete_tide_record: can't malloc");
6821 if (!(allrecs_packed = (NV_U_BYTE **) malloc (hd.pub.number_of_records *
sizeof(NV_U_BYTE*)))) {
6822 perror (
"libtcd: delete_tide_record: can't malloc");
6830 require (fseek (fp, tindex[0].address, SEEK_SET) == 0);
6831 for (newrecnum=0,i=0; i<(NV_INT32)hd.pub.number_of_records; ++i) {
6832 assert (ftell(fp) == tindex[i].address);
6833 if (i == num || (tindex[i].record_type == SUBORDINATE_STATION && tindex[i].reference_station == num)) {
6835 allrecs_packed[i] = NULL;
6836 require (fseek (fp, tindex[i].record_size, SEEK_CUR) == 0);
6838 map[i] = newrecnum++;
6839 if (!(allrecs_packed[i] = (NV_U_BYTE *) malloc (tindex[i].record_size))) {
6840 perror (
"libtcd: delete_tide_record: can't malloc");
6841 for (--i; i>=0; --i)
6842 free (allrecs_packed[i]);
6843 free (allrecs_packed);
6847 chk_fread (allrecs_packed[i], tindex[i].record_size, 1, fp);
6853 require (fseek (fp, tindex[0].address, SEEK_SET) == 0);
6854 require (ftruncate (fileno(fp), tindex[0].address) == 0);
6856 for (i=0; i<(NV_INT32)hd.pub.number_of_records; ++i)
6858 if (tindex[i].record_type == SUBORDINATE_STATION) {
6859 assert (tindex[i].reference_station >= 0);
6860 assert (tindex[i].reference_station <= (NV_INT32)hd.pub.number_of_records);
6861 if (map[tindex[i].reference_station] != tindex[i].reference_station) {
6864 unpack_tide_record (allrecs_packed[i], tindex[i].record_size, &rec);
6865 free (allrecs_packed[i]);
6866 rec.header.reference_station = map[tindex[i].reference_station];
6867 pack_tide_record (&rec, &(allrecs_packed[i]), &(tindex[i].record_size));
6870 chk_fwrite (allrecs_packed[i], tindex[i].record_size, 1, fp);
6871 free (allrecs_packed[i]);
6876 free (allrecs_packed);
6882 hd.end_of_file = ftell(fp);
6883 hd.pub.number_of_records = newrecnum;
6886 open_tide_db (filename);
6915NV_BOOL update_tide_record(NV_INT32 num,
TIDE_RECORD *rec)
6922 NV_U_BYTE *
block = NULL;
6926 "libtcd error: attempt to access database when database not open\n");
6931 if (num < 0 || num >= (NV_INT32)hd.pub.number_of_records)
return NVFalse;
6933 if (!check_tide_record(rec))
return NVFalse;
6936 read_tide_record(num, &tmp_rec);
6937 if (rec->header.record_size != tmp_rec.header.record_size) {
6945 size = hd.end_of_file - pos;
6950 if ((
block = (NV_U_BYTE *)calloc(size,
sizeof(NV_U_BYTE))) == NULL) {
6951 perror(
"Allocating block");
6954 chk_fread(
block, size, 1, fp);
6958 write_tide_record(num, rec);
6962 chk_fwrite(
block, size, 1, fp);
6966 hd.end_of_file = ftell(fp);
6970 open_tide_db(filename);
6975 write_tide_record(num, rec);
6978 tindex[num].record_size = rec->header.record_size;
6979 tindex[num].record_type = rec->header.record_type;
6980 tindex[num].reference_station = rec->header.reference_station;
6981 tindex[num].tzfile = rec->header.tzfile;
6982 tindex[num].lat = NINT(rec->header.latitude * hd.latitude_scale);
6983 tindex[num].lon = NINT(rec->header.longitude * hd.longitude_scale);
6988 if (strcmp(tindex[num].name, rec->header.name) != 0) {
6989 free(tindex[num].name);
6991 (NV_CHAR *)calloc(strlen(rec->header.name) + 1,
sizeof(NV_CHAR));
6992 strcpy(tindex[num].name, rec->header.name);
6997 if (db) *db = hd.pub;
7034 NV_INT32 m2, s2, k1, o1;
7035 NV_FLOAT32 epoch_m2, epoch_s2, epoch_k1, epoch_o1;
7038 require((m2 = find_constituent(
"M2")) >= 0);
7039 require((s2 = find_constituent(
"S2")) >= 0);
7040 require((k1 = find_constituent(
"K1")) >= 0);
7041 require((o1 = find_constituent(
"O1")) >= 0);
7043 if (rec->amplitude[m2] == 0.0 || rec->amplitude[s2] == 0.0 ||
7044 rec->amplitude[k1] == 0.0 || rec->amplitude[o1] == 0.0)
7047 epoch_m2 = rec->epoch[m2];
7048 epoch_s2 = rec->epoch[s2];
7049 epoch_k1 = rec->epoch[k1];
7050 epoch_o1 = rec->epoch[o1];
7052 for (i = 0; i < hd.pub.constituents; ++i) {
7053 if (rec->amplitude[i] == 0.0 && rec->epoch[i] == 0.0) {
7054 for (j = 0; j < INFERRED_SEMI_DIURNAL_COUNT; ++j) {
7055 if (!strcmp(inferred_semi_diurnal[j], get_constituent(i))) {
7059 (semi_diurnal_coeff[j] / coeff[0]) * rec->amplitude[m2];
7061 if (fabs((NV_FLOAT64)(epoch_s2 - epoch_m2)) > 180.0) {
7062 if (epoch_s2 < epoch_m2) {
7068 rec->epoch[i] = epoch_m2 + ((hd.speed[i] - hd.speed[m2]) /
7069 (hd.speed[s2] - hd.speed[m2])) *
7070 (epoch_s2 - epoch_m2);
7074 for (j = 0; j < INFERRED_DIURNAL_COUNT; ++j) {
7075 if (!strcmp(inferred_diurnal[j], get_constituent(i))) {
7079 (diurnal_coeff[j] / coeff[1]) * rec->amplitude[o1];
7081 if (fabs((NV_FLOAT64)(epoch_k1 - epoch_o1)) > 180.0) {
7082 if (epoch_k1 < epoch_o1) {
7088 rec->epoch[i] = epoch_o1 + ((hd.speed[i] - hd.speed[o1]) /
7089 (hd.speed[k1] - hd.speed[o1])) *
7090 (epoch_k1 - epoch_o1);
7105static NV_U_BYTE mask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe},
7106 notmask[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
7145NV_U_INT32 calculate_bits(NV_U_INT32 value) {
7146 NV_U_INT32 bits = 32;
7147 NV_U_INT32 theBit = 0x80000000;
7149 while (value < theBit) {
7184void bit_pack(NV_U_BYTE buffer[], NV_U_INT32 start, NV_U_INT32 numbits,
7186 NV_INT32 start_byte, end_byte, start_bit, end_bit, i;
7188 i = start + numbits;
7194 start_byte = start >> 3;
7201 start_bit = start & 7;
7206 i = end_byte - start_byte - 1;
7210 if (start_byte == end_byte) {
7215 buffer[start_byte] &= mask[start_bit] | notmask[end_bit];
7221 buffer[start_byte] |=
7222 (value << (8 - end_bit)) & (notmask[start_bit] & mask[end_bit]);
7230 buffer[start_byte] &= mask[start_bit];
7238 buffer[start_byte++] |=
7239 (value >> (numbits - (8 - start_bit))) & notmask[start_bit];
7246 buffer[start_byte] &= 0;
7250 buffer[start_byte++] |= (value >> ((i << 3) + end_bit)) & 255;
7255 buffer[start_byte] &= notmask[end_bit];
7261 buffer[start_byte] |= (value << (8 - end_bit));
7291NV_U_INT32 bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
7292 NV_U_INT32 numbits) {
7293 NV_INT32 start_byte, end_byte, start_bit, end_bit, i;
7296 i = start + numbits;
7302 start_byte = start >> 3;
7309 start_bit = start & 7;
7314 i = end_byte - start_byte - 1;
7318 if (start_byte == end_byte) {
7322 (NV_U_INT32)buffer[start_byte] & (notmask[start_bit] & mask[end_bit]);
7326 value >>= (8 - end_bit);
7335 value = (NV_U_INT32)(buffer[start_byte++] & notmask[start_bit])
7336 << (numbits - (8 - start_bit));
7343 value += (NV_U_INT32)buffer[start_byte++] << ((i << 3) + end_bit);
7348 if (mask[end_bit]) {
7349 value += (NV_U_INT32)(buffer[start_byte] & mask[end_bit]) >> (8 - end_bit);
7382NV_INT32 signed_bit_unpack(NV_U_BYTE buffer[], NV_U_INT32 start,
7383 NV_U_INT32 numbits) {
7384 static NV_INT32 extend_mask = 0x7fffffff;
7388 assert(numbits > 0);
7390 value = bit_unpack(buffer, start, numbits);
7392 if (value & (1 << (numbits - 1))) value |= (extend_mask << numbits);
Runtime representation of a plugin block.