Created
January 11, 2012 02:12
-
-
Save radiofreejohn/1592535 to your computer and use it in GitHub Desktop.
IDL dlm to read formatted ASCII files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* gcc nv3h_read_gz.c -shared -Bsymbolic -I/zshare/rsi/idl_6.3/external/include -L/zshare/rsi/idl_6.3/bin/bin.linux.x86_64 -lidl -o nv3h_read_gz.so -fPIC -lz -ldl | |
* | |
* requires zlib 1.2.5 for gzbuffer -- will check for right version | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
#include <zlib.h> | |
#include <dlfcn.h> | |
#include "idl_export.h" | |
char *chomp(char *s) { | |
char *ss = s; | |
while(*s && *s != '\n' && *s != '\r') s++; | |
*s = '\0'; | |
return ss; | |
} | |
IDL_VPTR IDL_CDECL nv3h_read(int argc, IDL_VPTR argv[], char *argk) { | |
IDL_MEMINT dims[IDL_MAX_ARRAY_DIM]; | |
int status; | |
struct stat st_buf; | |
void *dlhandle; | |
int (*fn)(gzFile, int); | |
char *zlibfile = "libz.so.1"; | |
char *zliberror; | |
char messages[8192]; | |
char *filename = IDL_VarGetString(argv[0]); | |
char *fname; | |
double *buffer; | |
IDL_VPTR vpTmp = NULL; | |
IDL_VPTR vpPlainArgs[3]; | |
gzFile *myFp; | |
char *line = malloc(sizeof(char) * 32768); | |
ssize_t len = 0; | |
double val; | |
int nVals = 0; | |
size_t size; | |
char *endline = NULL; | |
//char **comments = NULL; | |
IDL_STRING *comments; | |
static IDL_VPTR silent; | |
static IDL_VPTR nx, ny; | |
static IDL_VPTR commentPtr; | |
char *lineptr = NULL; | |
long dataPosition = 0; | |
long totalDataElements = 0; | |
int longestComment = 0; | |
int nComments = 0; | |
int longestData = 0; | |
int nData = 0; | |
// make sure it's a file we can read | |
status = stat(filename, &st_buf); | |
if (status != 0) { | |
// first see if adding .gz finds it (calling program may strip .gz from filename) | |
strcpy(line, filename); | |
strcat(line, ".gz"); | |
status = stat(line, &st_buf); | |
fname = strdup(line); | |
line[0] = '\0'; | |
} else { | |
fname = strdup(filename); | |
} | |
if (status != 0) { | |
free(line); | |
sprintf(messages, "Error: Cannot read %s\n", fname); | |
free(fname); | |
IDL_Message(IDL_M_NAMED_GENERIC,IDL_MSG_RET, messages); | |
return IDL_GettmpLong(0); | |
} | |
if (!(S_ISREG (st_buf.st_mode))) { | |
free(line); | |
sprintf(messages, "Error: Not a regular file: %s\n", fname); | |
free(fname); | |
IDL_Message(IDL_M_NAMED_GENERIC,IDL_MSG_RET, messages); | |
return IDL_GettmpLong(0); | |
} | |
if ((myFp = gzopen(fname, "rb")) == NULL) { | |
free(line); | |
sprintf(messages, "Error: Cannot open %s.", fname); | |
IDL_Message(IDL_M_NAMED_GENERIC,IDL_MSG_RET, messages); | |
return IDL_GettmpLong(0); | |
} | |
dlhandle = dlopen(zlibfile, RTLD_LAZY); | |
fn = dlsym(dlhandle, "gzbuffer"); | |
if (((zliberror = dlerror()) == NULL) && dlhandle) | |
{ | |
// I know I should use (*fn)(...) here but I know gzbuffer exists | |
gzbuffer(myFp, 131070); | |
dlclose(dlhandle); | |
} | |
IDL_StoreScalarZero(argv[1], IDL_TYP_LONG); | |
IDL_ENSURE_SCALAR(argv[0]); | |
IDL_EXCLUDE_EXPR(argv[1]); | |
while ((gzgets(myFp, line, 32768)) != NULL) { | |
len = strlen(line); | |
if (*line != ';') { | |
nData++; | |
if (len > longestData) { | |
dataPosition = gztell(myFp); | |
} | |
longestData = (len > longestData) ? len : longestData; | |
} else { | |
nComments++; | |
longestComment = (len > longestComment) ? len : longestComment; | |
} | |
} | |
gzseek(myFp, dataPosition-longestData, SEEK_SET); | |
gzgets(myFp, line, 32768); | |
lineptr = line; | |
// find the number of data values per record | |
while ((val = strtod(lineptr, &endline)) || (endline != lineptr)) { | |
nVals++; | |
lineptr = endline; | |
} | |
totalDataElements = nVals * nData; | |
dims[0] = nVals; | |
dims[1] = nData; | |
static IDL_KW_PAR kw_pars[] = { IDL_KW_FAST_SCAN, | |
{"COMMENTS", IDL_TYP_STRING,1,IDL_KW_OUT,0,IDL_CHARA(commentPtr)}, | |
{"NX", IDL_TYP_LONG,1,IDL_KW_OUT|IDL_KW_ZERO,0,IDL_CHARA(nx)}, | |
{"NY", IDL_TYP_LONG,1,IDL_KW_OUT|IDL_KW_ZERO,0,IDL_CHARA(ny)}, | |
{"SILENT", IDL_TYP_LONG,1,IDL_KW_VIN,0,IDL_CHARA(silent)}, | |
{NULL} }; | |
IDL_KWCleanup(IDL_KW_MARK); | |
IDL_KWGetParams(argc, argv, argk, kw_pars, vpPlainArgs, 1); | |
if (commentPtr) | |
IDL_StoreScalarZero(commentPtr, IDL_TYP_STRING); | |
if (nx) { | |
vpTmp = IDL_GettmpLong(nVals); | |
IDL_VarCopy(vpTmp, nx); | |
} | |
if (ny) { | |
vpTmp = IDL_GettmpLong(nData); | |
IDL_VarCopy(vpTmp, ny); | |
} | |
buffer = (double *)IDL_MakeTempArray(IDL_TYP_DOUBLE,2, dims, IDL_ARR_INI_NOP, &vpTmp); | |
IDL_VarCopy(vpTmp,argv[1]); | |
dims[0] = nComments; | |
dims[1] = 0; | |
comments = (IDL_STRING *) IDL_MakeTempArray(IDL_TYP_STRING,1,dims, IDL_ARR_INI_NOP, &vpTmp); | |
if (commentPtr) | |
IDL_VarCopy(vpTmp, commentPtr); | |
gzseek(myFp, 0, SEEK_SET); | |
while ((gzgets(myFp, line, 32768)) != NULL) { | |
len = strlen(line); | |
lineptr = line; | |
if (*line != ';') { | |
while ((val = strtod(lineptr, &endline)) || (endline != lineptr)) { | |
*buffer++ = val; | |
lineptr = endline; | |
} | |
} else { | |
IDL_StrStore(comments++,chomp(line)); | |
} | |
} | |
free(line); | |
free(fname); | |
line = NULL; | |
gzclose(myFp); | |
IDL_KWCleanup(IDL_KW_CLEAN); | |
return IDL_GettmpLong(1); | |
} | |
int IDL_Load(void) { | |
static IDL_SYSFUN_DEF2 function_addr[] = { | |
{ nv3h_read, "NV3H_READ_GZ", 2, 2, IDL_SYSFUN_DEF_F_KEYWORDS }, | |
}; | |
IDL_SysRtnAdd(function_addr, TRUE, 1); | |
return IDL_TRUE; | |
} | |
/* required metadata file: nv3h_read_gz.dlm | |
MODULE nv3h_read_gz | |
DESCRIPTION Read super big NV3H files | |
VERSION 1.0 | |
SOURCE John Clover, UC San Diego. | |
BUILD_DATE Jan, 6 2011 | |
FUNCTION nv3h_read_gz 2 2 KEYWORDS | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment