/***********************************************************************/
/* program name : RNX2CRX */
/* */
/* RINEX file compression program for UNIX/MS-DOS system. */
/* convert the RINEX format to Compact RINEX format */
/* Created by Yuki HATANAKA / Geographical Survey Institute, Japan */
/* */
/* ver. */
/* 4.0.0 2007.02.05 test version Y. Hatanaka */
/* - CRINEX 1/3 for RINEX 2.x/3.x */
/* 4.0.1 2007.05.08 */
/* - elimination of supports for VMS and SUN OS 4.1.x */
/* - output not to the current directory but the same */
/* directory as the input file. */
/* - the same code for DOS and UNIX */
/* 4.0.2 2007.06.07 */
/* - fixing incompatibility of argument and format */
/* string of printf. */
/* 4.0.3 2007.06.21 */
/* - nothing was changed from 4.0.2 except for the */
/* version string to be the same as crx2rnx.c */
/* 4.0.4 2009.06.31 Y. Hatanaka */
/* - rename fuction getline to ggetline */
/* - correct typos in error messages */
/* */
/* Copyright (c) 2007 Geographical Survey Institute */
/* All rights reserved. See the license agreement at */
/* ftp://terras.gsi.go.jp/software/RNXCMP_4.0.4/LICENSE.txt */
/* */
/***********************************************************************/
#define VERSION "ver.4.0.4"
/**** Exit codes are defined here. ****/
#define EXIT_WARNING 2
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
/**** Don't change the lines from here. ****/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
/*** define macro to ***/
#define FLUSH_BUFF printf("%s",top_buff), *(p_buff = top_buff)='\0'
#define CLEAR_BUFF *(p_buff = top_buff)='\0'
#define CRX_VERSION1 "1.0" /* CRINEX version for RINEX 2.x */
#define CRX_VERSION2 "3.0" /* CRINEX version for RINEX 3.x */
#define PROGNAME "RNX2CRX"
#define MAXSAT 90 /* Maximum number of satellites observed at one epoch */
#define MAXTYPE 50 /* Maximum number of data types for a GNSS system */
#define MAXCLM 1024 /* Maximum columns in one line (>MAXTYPE*19+3) */
#define MAX_BUFF_SIZE 131072 /* Muximum size of output buffer (>MAXSAT*(MAXTYPE*19+4)+60 */
#define ARC_ORDER 3 /* order of difference to take */
/* define data structure for fields of clock offset and obsercvation records */
/* Those data will be handled as integers after eliminating decimal points. */
/* Since their size may exceeds range between LONG_MIN and LONG_MAX, */
/* they will be read with being divided properly into upper and lower digits */
typedef struct clock_format{
long u[ARC_ORDER+1]; /* upper X digits */
long l[ARC_ORDER+1]; /* lower 8 digits (can be 9-10 digits for deltas)*/
} clock_format;
typedef struct data_format{
long u[ARC_ORDER+1]; /* upper X digits */
long l[ARC_ORDER+1]; /* lower 5 digits (can be 6-7 digits for deltas) */
int order;
} data_format;
/* define global variables */
long ep_count=0;
long ep_reset=0;
long nl_count=0;
int rinex_version; /* =2 or 3 */
int nsat,ntype,ntype_gnss[UCHAR_MAX],ntype_record[MAXSAT],clk_order = -1;
int exit_status = EXIT_SUCCESS;
int skip_strange_epoch = 0; /* default : stop with error */
clock_format clk1,clk0 = {0,0,0,0,0,0,0,0};
data_format y0[MAXSAT][MAXTYPE], y1[MAXSAT][MAXTYPE];
char flag0[MAXSAT][MAXTYPE*2], flag[MAXSAT][MAXTYPE*2];
char out_buff[MAX_BUFF_SIZE]= {'x','\0'}; /**** a character is put as a stopper to aviod memory overflow ****/
char *top_buff=&out_buff[1],*p_buff; /**** therefore, actual baffer start from the second character ****/
char oldline[MAXCLM] = {'&','\0'};
int nsat_old = 0;
/* declaration of functions */
void parse_args(int argc, char *argv[]);
void header();
int get_next_epoch(char *p_line);
void skip_to_next(char *p_line);
void initialize_all(char *oldline,int *nsat_old, int count);
void put_event_data(char *p_line);
void read_clock(char *line,int shift_cl);
void process_clock();
int set_sat_table(char *p_new, char *p_old, int nsat_old,int *sattbl);
int read_more_sat(int n, char *p);
void data(int *sattbl);
char *strdiff(char *s1, char *s2, char *ds);
int ggetline(data_format *py1, char *flag, char *sat_id, int *ntype_rec);
void read_value(char *p, long *pu, long *pl);
void take_diff(data_format *py1, data_format *py0);
void putdiff(long dddu, long dddl);
void put_clock(long du, long dl, int clk_order);
int read_chk_line(char *line);
void error_exit(int error_no, char *string);
void flush_buff();
/*---------------------------------------------------------------------*/
main(int argc, char *argv[]){
char newline[MAXCLM],dummy[MAXCLM];
char *p,*p_event,*p_nsat,*p_satlst,*p_satold,*p_clock;
int sattbl[MAXSAT],i,j,shift_clk;
/* sattbl[i]: order (at the previous epoch) of i-th satellite */
/* (at the current epoch). -1 is set for the new satellites */
parse_args(argc,argv);
for(i=0;i<UCHAR_MAX;i++)ntype_gnss[i]=-1; /** -1 unless GNSS type is not defined **/
header();
if (rinex_version==2){
p_event =&newline[28]; /** pointer to event flug **/
p_nsat =&newline[29]; /** pointer to n_sat **/
p_satlst =&newline[32]; /** pointer to satellite list **/
p_satold =&oldline[32]; /** pointer to n_sat **/
p_clock =&newline[68]; /** pointer to clock offset data **/
shift_clk = 1;
}else{
p_event =&newline[31];
p_nsat =&newline[32];
p_satlst =&newline[41];
p_satold =&oldline[41];
p_clock =&newline[41];
shift_clk = 4;
}
for(CLEAR_BUFF;;FLUSH_BUFF){
SKIP:
if( ! get_next_epoch(newline) ) return exit_status;
/*** if event flag > 1, then (1)output event data */
/*** (2)initialize all data arcs, and continue to next epoch ***/
if( atoi(strncpy(dummy,p_event,1)) > 1) {
put_event_data(newline);
initialize_all(oldline,&nsat_old,0);
continue;
}
if(strchr(newline,'\0') > p_clock){
read_clock(p_clock,shift_clk); /**** read clock offset ****/
}else{
clk_order = -1; /*** reset data arc for clock offset ***/
}
nsat=atoi(p_nsat);
if(nsat > MAXSAT) error_exit(8,newline);
if(nsat > 12 && rinex_version == 2) read_more_sat(nsat,p_satlst); /*** read continuation lines ***/
if( ep_reset > 0 && ++ep_count > ep_reset ) initialize_all(oldline,&nsat_old,1);
/**** get observation ****/
for(i=0,p=p_satlst ; i<nsat ; i++,p+=3) {
if( ggetline(y1[i],flag[i],p,&ntype_record[i]) ) {
CLEAR_BUFF;
exit_status = EXIT_WARNING;
goto SKIP;
}
}
*p='\0'; /*** terminate satellite list ***/
if(set_sat_table(p_satlst,p_satold,nsat_old,sattbl) ){
CLEAR_BUFF;