;+ ; NAME: ; CMSVREAD ; ; AUTHOR: ; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770 ; craigm@lheamail.gsfc.nasa.gov ; ; PURPOSE: ; Read a single variable from an open SAVE file ; ; CALLING SEQUENCE: ; ; CMSVREAD, UNIT, DATA [, NAME=NAME, /NO_DATA, VERSION=VERSION, ; TIMESTAMP=TIMESTAMP ] ; ; DESCRIPTION: ; ; CMSVREAD reads a single IDL variable from an open IDL SAVE file. ; The file should already have been opened as a normal file using ; OPENR. ; ; CMSVREAD is a simplified version of the CMSVLIB package, and as ; such is not capable of reading heap data (pointers) or object ; data. Strings, structures, and all array types are supported. ; ; This procedure is part of the CMSVLIB SAVE library for IDL by ; Craig Markwardt. You must have the full CMSVLIB core package ; installed in order for this procedure to function properly. ; ; ================================================================== ; Research Systems, Inc. has issued a separate license intended ; to resolve any potential conflict between this software and the ; IDL End User License Agreement. The text of that license ; can be found in the file LICENSE.RSI, included with this ; software library. ; ================================================================== ; ; INPUTS: ; ; UNIT - the open file unit. ; ; DATA - a named variable, into which the new data is to be read. ; ; KEYWORDS: ; ; NAME - upon output, the name of the saved variable is returned in ; this keyword. If a failure or end of file condition ; occurs, name will be undefined upon return. ; ; STRUCTURE_NAME - if the data to be read is a structure, upon ; output, this keyword will contain the name of the ; structure. A value of '' indicates an anonymous ; structure. ; ; SIZE - upon output, the SIZE type of the data is returned in this ; keyword. ; ; NO_DATA - if set, no data is read from the file, only the variable ; name and type. ; ; TIMESTAMP - after the first call to CMSVREAD on a newly opened ; file, this keyword will contain the file timestamp ; structure. ; ; VERSION - after the first call to CMSVREAD on a newly opened file, ; this keyword will contain the file version information, ; if available. ; ; QUIET - if set, error messages are not printed. ; Default: an error causes errors to be printed with MESSAGE ; ; STATUS - upon return, this keyword will contain 1 for success and ; 0 for failure. ; ; ERRMSG - upon return with a failure, this keyword will contain the ; error condition as a string. ; ; EXAMPLE: ; ; Read all variables from a file, and print help on them. ; ; openr, 50, 'test.sav' ; name = '' ; while n_elements(name) GT 0 do begin ;; EOF signalled by NAME undefined ; cmsvread, 50, data, name=name ; help, name, data ; end ; close, 50 ; ; SEE ALSO: ; ; CMSVWRITE, CMRESTORE, CMSAVE, RESTORE, CMSVLIB ; ; MODIFICATION HISTORY: ; Written and documented, 11 Jan 2001, CM ; Added notification about RSI License, 13 May 2002, CM ; Remove support for undocumented AUTOPROMOTE64 keyword, ; 11 Jan 2010, CM ; NOTE: remember to modify CMSVLIB.PRO when changing library! ; ; $Id: cmsvread.pro,v 1.9 2010/01/11 08:58:13 craigm Exp $ ; ;- ; Copyright (C) 2001, Craig Markwardt ; This software is provided as is without any warranty whatsoever. ; Permission to use, copy, modify, and distribute modified or ; unmodified copies is granted, provided this copyright and disclaimer ; are included unchanged. ;- pro cmsvread, unit0, data, timestamp=tstamp, version=ver, $ name=name, size=sz, no_data=nodata, structure_name=stname, $ promote64=promote64, $ quiet=quiet, status=status, errmsg=errmsg status = 0 catch, catcherr if catcherr EQ 0 then lib = cmsvlib(/query) else lib = 0 catch, /cancel if lib EQ 0 then begin errmsg = 'ERROR: The CMSVLIB library must be in your IDL path.' if keyword_set(quiet) then return else message, errmsg endif name = 0 & dummy = temporary(name) data = 0 & dummy = temporary(data) sz = 0 & dummy = temporary(sz) tp = 0 & dummy = temporary(tp) stname = 0 & dummy = temporary(stname) if n_elements(unit0) EQ 0 then begin errmsg = 'ERROR: UNIT is not defined' if keyword_set(quiet) then return else message, errmsg endif unit = floor(unit0(0)) stat = fstat(unit) if stat.read EQ 0 OR stat.open EQ 0 then begin errmsg = 'ERROR: UNIT is not open for reading' if keyword_set(quiet) then return else message, errmsg endif ;; Thanks to Liam Gumley to show that one can check the file pointer ;; to see if we are at the start. ;; We are at the beginning of the file, make sure this is a proper ;; IDL save file. if stat.cur_ptr EQ 0 then begin cmsv_open, unit, 'FILENAME', pointer, access='R', /reopen, $ status=status, errmsg=errmsg if status EQ 0 then begin if keyword_set(quiet) then return else message, errmsg endif endif done = 0 while NOT done do begin block = 0 & dummy = temporary(block) cmsv_rrec, block, p1, bdata, unit=unit, next_block=pnext, /init, $ block_type=bt, block_name=bn, status=status, errmsg=errmsg, $ promote64=promote64 if status EQ 0 then begin if keyword_set(quiet) then return else message, errmsg endif case bn of 'END_MARKER': begin done = 1 end 'TIMESTAMP': begin tstamp = bdata end 'VERSION': begin ver = bdata end 'VARIABLE': begin sysvar = 0 DO_VARIABLE: tp = 0 cmsv_rvtype, block, p1, name, sz, status=status, template=tp, $ unit=unit, system=sysvar, errmsg=errmsg, $ structure_name=stname if status EQ 0 OR name EQ '' then begin status = 0 if errmsg EQ '' then $ errmsg = 'ERROR: could not read variable name' if keyword_set(quiet) then return else message, errmsg endif if NOT keyword_set(nodata) then begin tp1 = sz(sz(0)+1) if tp1 EQ 0 OR tp1 EQ 10 OR tp1 EQ 11 then begin status = 0 if tp1 EQ 0 then $ errmsg = 'ERROR: variable type is undefined' $ else if tp1 EQ 10 OR tp1 EQ 11 then $ errmsg = 'ERROR: CMSVREAD cannot read heap or objects' if keyword_set(quiet) then return else message, errmsg endif cmsv_rdata, block, p1, sz, data, template=tp, unit=unit, $ status=status, errmsg=errmsg tp = 0 if status EQ 0 then begin errmsg = 'ERROR: could not read data' if keyword_set(quiet) then return else message, errmsg endif endif done = 1 end 'SYSTEM_VARIABLE': begin sysvar = 1 goto, DO_VARIABLE end ELSE: dummy = 1 endcase point_lun, unit, pnext endwhile status = 1 return end