Home| general |src.lib|rfile| RfileRead Index

RfileRead

Syntax
int RfileRead(FILE *fp,int num,RfileDecoder *decode, void **data);
Header
general/rfile.h
Library
rfile
Description

The RfileRead function reads data from a file in the rFile format.

The data is read from the I/O stream pointed to by the argument fp.

Data in the rFile format consists of plain ASCII text divided into a number of time stamped records. A line beginning with the character '#' is interpreted as a comment and ignored.

The first line encountered that is not a comment is the time stamp of the record and should consist of the full date and time of the start and end of the record:

syear smonth sday shour sminute ssecond eyear emonth eday ehour eminue esecond

The next line defines the number of blocks within the record:

blocks

Each record is comprised of one or more blocks of data. A block consists of a header followed by a number of data entries. A data entry consists of a number of fields, the type of data fields within a block are always identical.

The first line in the block header defines the number of entries in the block and the number of fields per entry:

entries fields

The following three lines identify the entry fields. The first line gives the names of the fields, the next line give the units associated with that field and the final line gives the data type of the field.

nameA 	nameB	 nameC
unit1A	unitB 	unitC
typeA	typeB	typeC

The data type can be one of:

text
A string (which cannot contain any spaces).
char
A single character.
float
A floating point number.
int
An integer number.

After the header comes the body of the block. Each line in the body is a data entry and must have the same number of columns as the block has fields. The number of lines in the body must be equal to the number of entries defined in the block header.

entry1.A	entry1.B	entry1.C
entry2.A	entry2.B 	entry2.C
entry3.A	entry2.B 	entry3.C

The following is an example of an rFile data file:

# Example data file consisting of two records, 
# each containing two blocks of data.

1997 11 20 0 0 0 1997 11 20 0 5 0
2
5 4
lat 	lon 	hgt 	flg
degree	degree	km	count
float	float	float 	int
55.0	120.0	200.0	0
56.0	121.0	201.0	1
57.0	124.0	210.0	2
58.0	130.0	215.0	0
58.0	132.0	210.0	2
6 2
a	b
count	count
int	int
0	1
2	1
3	2
4	3
5	4
10	1
1997 11 20 00 05 00 1997 11 20 00 10 00
2
4 4
lat 	lon 	hgt 	flg
degree	degree	km	count
float	float	float 	int
35.0	140.0	100.0	2
37.0	144.0	110.0	4
38.0	140.0	115.0	5
38.0	142.0	110.0	6
3 2
a	b
count	count
int	int
10	10
9	21
8	32

The RfileRead function uses a series of user supplied decoder functions to interpret the contents of each block. The number of decoder functions and the array of pointers to them are defined by the arguments num and decode respectively.The user must also supply a block of memory for each decoder function to store its results. Pointers to these memory blocks are stored in the array pointed to by the argument data. Different decoder functions can share the same memory by setting the appropriate entries in the array to point to the same value.

A decoder function has the form:

int decode(char *name,char *unit,char *type,double st_time,double ed_time,int nent,int nfld,int ent,struct RfileData *fdat,void *ptr);

The decoder functions have a type associated with them:

typedef int (*RfileDecoder)(char *,char *,char *,double,double,int,int,int,struct RfileData *,void *ptr);

As a data entry is read from a block, each decoder functions will be called in turn.The first three arguments are space separated text strings giving the name of the fields in the block, the units of each field, and the data type associated with each field. The function should compare these strings with the fields of the block type it can decode. If the function does not recognize this type of block it should take no further action and return a value of zero. If a match is found the function should decode the entry using the remaining arguments and return a value of (1).

The arguments st_time and ed_time give the start end end time of the record in terms of seconds from 0:00UT January 1, 1970. The argument nent give the number of data entries in the data block and the argument nfld gives the number of fields per entry. The index number of the entry to decode is given by the argument ent.

The argument fdat is a pointer to an array of structures containing the decoded fields of the data entry. This structure includes a flag indicating the type of data. Possible values of this flag are:

FIELD_CHAR
A single character.
FIELD_INT
A signed integer.
FIELD_DOUBLE
A double precision floating point number.
FIELD_TXT
A text string.

The function should copy the appropriate member of the union for each element in the array into its data buffer pointed to by the argument ptr.

If no decoder functions are defined, the function will extract the start end end time of each data record. If the argument data is not a NULL pointer it is ssumed to be a pointer to an array of double precision floating point numbers used to store the record times measured in seconds from 00:00UT January 1, 1970.

Returns
Returns the number of bytes read from the stream if a record is successfully read. On error, (-1) is returned.
Errors
On error, (-1) is returned.
Example

Source Code: RfileRead.c

/* RfileRead.c
   ===========
   Author: R.J.Barnes
 Copyright (c) 2012 The Johns Hopkins University/Applied Physics Laboratory

This file is part of the Radar Software Toolkit (RST).

RST is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

Modifications:




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rtypes.h"
#include "rtime.h"
#include "rfile.h"

struct blk1 {
  double st_time,ed_time;
  int npnt;
  double lat[256];
  double lon[256];
  double hgt[256];
  int flg[256];
   
};

struct blk2 {
  double st_time,ed_time;
  int npnt;
  int a[256],b[256];
};

struct data {
  struct blk1 blk1;
  struct blk2 blk2;
} data;


int decode_blk1(char *name,char *unit,char *type,
                double st_time,double ed_time,
                int npnt,int nprm,int pnt,
                struct RfileData *data,void *ptr) {

  char *block="lat lon hgt flg";
  struct blk1 *dp;
  dp=(struct blk1 *) ptr;
  if (strcmp(name,block) !=0) return 0;


  dp->st_time=st_time;
  dp->ed_time=ed_time;
  dp->npnt=npnt;
 
  dp->lat[pnt]=data[0].data.fval;
  dp->lon[pnt]=data[1].data.fval;
  dp->hgt[pnt]=data[2].data.fval;
  dp->flg[pnt]=data[3].data.ival;
  return 1;
}

int decode_blk2(char *name,char *unit,char *type,
                double st_time,double ed_time,
                int npnt,int nprm,int pnt,
                struct RfileData *data,void *ptr) {

  char *block="a b";
  struct blk2 *dp;
  dp=(struct blk2 *)ptr;

  if (strcmp(name,block) !=0) return 0;

  dp->st_time=st_time;
  dp->ed_time=ed_time;
  dp->npnt=npnt;
 
  dp->a[pnt]=data[0].data.ival;
  dp->b[pnt]=data[1].data.ival;
  return 1;
}




int main(int argc,char *argv[]) {

  FILE *fp;
 
  RfileDecoder decode[2];
  void *dptr[2];
  int i;
  int yr,mo,dy,hr,mt; 
  double sc;
 

  if (argc>1) {
    fp=fopen(argv[1],"r");
    if (fp==NULL) {
      fprintf(stderr,"File not found.'n");
      exit(-1);
    }
  } else fp=stdin;
  
  decode[0]=decode_blk1;
  decode[1]=decode_blk2;
  dptr[0]=&data.blk1;
  dptr[1]=&data.blk2;

  while (RfileRead(fp,2,decode,dptr) !=-1) {
    TimeEpochToYMDHMS(data.blk1.st_time,&yr,&mo,&dy,&hr,&mt,&sc);
    fprintf(stdout,"%d-%d-%d %d:%d:%d to ",yr,mo,dy,hr,mt,(int) sc);
    TimeEpochToYMDHMS(data.blk1.ed_time,&yr,&mo,&dy,&hr,&mt,&sc);
    fprintf(stdout,"%d-%d-%d %d:%d:%d'n",yr,mo,dy,hr,mt,(int) sc);
 
    fprintf(stdout,"Block 1'n");
  
    fprintf(stdout,"pnt'tlat'tlon'thgt'tflg'n");
    for (i=0;i<data.blk1.npnt;i++) {
      fprintf(stdout,"%d't%g't%g't%g't%d'n",i,
             data.blk1.lat[i],data.blk1.lon[i],
             data.blk1.hgt[i],data.blk1.flg[i]);
    
    }
    fprintf(stdout,"Block 2'n");
    fprintf(stdout,"pnt'ta'tb'n");
    for (i=0;i<data.blk2.npnt;i++) {
      fprintf(stdout,"%d't%d't%d'n",i,
             data.blk2.a[i],data.blk2.b[i]);
    
    }
    fprintf(stdout,"'n"); 


  }
  if (fp !=stdin) fclose(fp);
  return 0;
}