; IDL-OPENDAP interface. ; Copyright (c) 2006 OPeNDAP, Inc. ; Author: Patrick West UCAR/HAO ; ; Based on IDL-DODS Written by Daniel J. Carr - Research Systems, Inc. ; ; This 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 2.1 of the License, or (at your option) any later version. ; ; This library 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 library; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. FUNCTION opendap_handle_content, opendap_data, node, content, node_type, $ has_content, get_data, debug ;{ ; Based on the type of the variable, call the appropriate function ; from idl_dods.cc to get the data IF( debug gt 0ul ) THEN PRINT,"node_type = ",node_type CASE node_type OF ;{ !opendap_NODE_Byte: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"byte" status = OPENDAP_GET_BYTE( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Int16: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"int16" status = OPENDAP_GET_INT16( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_UInt16: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"uint16" status = OPENDAP_GET_UINT16( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Int32: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"int32" status = OPENDAP_GET_INT32( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_UInt32: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"uint32" status = OPENDAP_GET_UINT32( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Float32: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"float32" status = OPENDAP_GET_FLOAT32( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Float64: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"float64" status = OPENDAP_GET_FLOAT64( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ opendap_data = REFORM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_String: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"string" status = OPENDAP_GET_STRING( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ ; The STRTRIM shouldn't have any effect here, however ; if it's removed, the sequence code returns the last value ; for every value of the array opendap_data = STRTRIM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_URL: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"url" status = OPENDAP_GET_STRING( content, val, get_data ) IF( ( status NE 0ul ) AND ( N_ELEMENTS( val ) GT 0ul )) THEN BEGIN;{ ; The STRTRIM shouldn't have any effect here, however ; if it's removed, the sequence code returns the last value ; for every value of the array opendap_data = STRTRIM( TEMPORARY( val ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Array: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"array" d_names = BYTARR(65, 12) status = OPENDAP_GET_ARRAY( content, arr, arr_name, d_names, get_data ) IF( debug gt 0ul ) THEN PRINT,'n_elements(arr) = ',n_elements(arr) IF( ( status NE 0ul ) AND ( N_ELEMENTS( arr ) GT 0ul )) THEN BEGIN;{ arr_size = SIZE( arr ) arr_dims = arr_size[0] ; Figure out how many dimensions are actually used d_dims = 0 FOR j = 0, 11 DO BEGIN ;{ IF( d_names[0, j] NE 0 ) THEN d_dims = d_dims + 1 ENDFOR ;} ; And create an array of the appropriate size to hold them str_names = STRARR( d_dims ) FOR i = d_dims - arr_dims, d_dims - 1 DO BEGIN ;{ temp_name = REFORM( d_names[*,i] ) opendap_fix_name, temp_name str_names[i] = temp_name ENDFOR ;} OPENDAP_FIX_NAME, arr_name ; Build IDL structure to hold the components. opendap_data = CREATE_STRUCT( STRING( arr_name ), $ TEMPORARY( arr ), $ 'dimension_names', $ REVERSE( str_names[d_dims - arr_dims:d_dims-1] ) ) ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Grid: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"grid" ; First lets get the values of the grid, the dimension names, ; the name of the array, etc... IF( debug gt 0ul ) THEN PRINT,"getting array" OPENDAP_GET_GRID_VALUES, content, vcontent IF( debug gt 0ul ) THEN PRINT,"handling array" status = OPENDAP_HANDLE_CONTENT( vals, node, vcontent, $ !opendap_NODE_Array, $ has_content, $ get_data, debug ) IF( debug gt 0ul ) THEN PRINT,"done getting array = ",status IF( ( status NE 0ul ) ) THEN BEGIN ;{ g_names = tag_names( vals ) g_name = g_names[0] IF( debug gt 0ul ) THEN PRINT,"g_name = ",g_name IF( debug gt 0ul ) THEN PRINT,"getting grid" m_names = BYTARR(64, 12) ; map dimension names ; Now lets get the maps status = OPENDAP_GET_GRID( content, m1, m2, m3, m4, m5, m6, $ m7, m8, m9, m10, m11, m12, $ m_names, get_data ) IF( debug GT 0ul ) THEN PRINT," done getting grid: ",status IF( status NE 0ul ) THEN BEGIN ;{ str_names = STRARR( 12 ) n_names = N_ELEMENTS( m_names ) for i_names = 0, n_names - 1 do begin ;{ temp_name = m_names[i_names] OPENDAP_FIX_NAME, temp_name str_names[i_names] = temp_name endfor ;} d_names = TEMPORARY(str_names) IF( debug GT 0ul ) THEN BEGIN ;{ PRINT,' n_names = ',n_names FOR i_names = 0, n_names - 1 DO BEGIN ;{ PRINT,' d_names[',i_names,'] = ',d_names[i_names] ENDFOR ;} IF( N_ELEMENTS( m1 ) GT 0ul ) THEN PRINT,' m1 has data' IF( N_ELEMENTS( m2 ) GT 0ul ) THEN PRINT,' m2 has data' IF( N_ELEMENTS( m3 ) GT 0ul ) THEN PRINT,' m3 has data' IF( N_ELEMENTS( m4 ) GT 0ul ) THEN PRINT,' m4 has data' IF( N_ELEMENTS( m5 ) GT 0ul ) THEN PRINT,' m5 has data' IF( N_ELEMENTS( m6 ) GT 0ul ) THEN PRINT,' m6 has data' IF( N_ELEMENTS( m7 ) GT 0ul ) THEN PRINT,' m7 has data' IF( N_ELEMENTS( m8 ) GT 0ul ) THEN PRINT,' m8 has data' IF( N_ELEMENTS( m9 ) GT 0ul ) THEN PRINT,' m9 has data' IF( N_ELEMENTS( m10 ) GT 0ul ) THEN PRINT,' m10 has data' IF( N_ELEMENTS( m11 ) GT 0ul ) THEN PRINT,' m11 has data' IF( N_ELEMENTS( m12 ) GT 0ul ) THEN PRINT,' m12 has data' ENDIF ;} opendap_data = $ CREATE_STRUCT( g_name, REFORM( TEMPORARY( vals ) ) ) ; Build IDL structure to hold the components. IF( N_ELEMENTS( m1 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[0] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[0] = d_names[0] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[0], $ TEMPORARY( m1 ) ) ENDIF ;} if( N_ELEMENTS( m2 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[1] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[1] = d_names[1] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[1], $ TEMPORARY( m2 ) ) ENDIF ;} IF( N_ELEMENTS( m3 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[2] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[2] = d_names[2] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[2], $ TEMPORARY( m3 ) ) ENDIF ;} IF( N_ELEMENTS( m4 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[3] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[3] = d_names[3] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[3], $ TEMPORARY( m4 ) ) ENDIF ;} if( N_ELEMENTS( m5 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[4] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[4] = d_names[4] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[4], $ TEMPORARY( m5 ) ) ENDIF ;} if( N_ELEMENTS( m6 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[5] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[5] = d_names[5] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[5], $ TEMPORARY( m6 ) ) ENDIF ;} IF( N_ELEMENTS( m7 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[6] ) if( ind[0] GE 0ul ) then begin ;{ d_names[6] = d_names[6] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[6], $ TEMPORARY( m7 ) ) ENDIF ;} IF( N_ELEMENTS( m8 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[7] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[7] = d_names[7] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[7], $ TEMPORARY( m8 ) ) ENDIF ;} IF( N_ELEMENTS( m9 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[8] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[8] = d_names[8] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[8], $ TEMPORARY( m9 ) ) ENDIF ;} IF( N_ELEMENTS( m10 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[9] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[9] = d_names[9] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[9], $ TEMPORARY( m10 ) ) ENDIF ;} IF( N_ELEMENTS( m11 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[10] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[10] = d_names[10] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[10], $ TEMPORARY( m11 ) ) ENDIF ;} if( N_ELEMENTS( m12 ) GT 0ul ) THEN BEGIN ;{ ind = WHERE( TAG_NAMES( opendap_data ) EQ d_names[11] ) IF( ind[0] GE 0ul ) THEN BEGIN ;{ d_names[11] = d_names[11] + '_1' ENDIF ;} opendap_data = $ CREATE_STRUCT( opendap_data, d_names[11], $ TEMPORARY( m12 ) ) ENDIF ;} ENDIF ELSE RETURN, 0ul ;} ENDIF ELSE RETURN, 0ul ;} END ;} !opendap_NODE_Sequence: BEGIN ;{ IF( debug GT 0ul ) THEN PRINT,"sequence" ; get information on the sequence, numbers of rows and number of ; columns. OPENDAP_GET_SEQUENCE_INFO, content, n_rows, n_fields IF( debug GT 0ul ) THEN BEGIN ;{ PRINT,'n_rows = ',n_rows PRINT,'n_fields = ',n_fields ENDIF ;} IF( n_rows EQ 0ul ) THEN BEGIN ;{ n_rows = 1ul ENDIF ;} FOR i_fields = 0ul, n_fields - 1 DO BEGIN ;{ stat = OPENDAP_GET_SEQUENCE_FIELD( node, content, i_fields, $ field_name, field_type, $ field_node, field_content ) IF( stat NE 1ul ) THEN RETURN, 0ul IF( debug gt 0ul ) THEN BEGIN ;{ PRINT,' field[',i_fields,'] name: ',field_name,' type: ',field_type ENDIF ;} FOR i_rows = 0ul, n_rows - 1 DO BEGIN ;{ stat = OPENDAP_GET_SEQUENCE_ROW( field_node, $ field_content, $ field_type, $ i_rows, $ row_value ) IF( stat NE 1ul ) THEN BEGIN ;{ PRINT,'Sequence field ',i_fields, $ ': failed to retrieve row ',i_rows RETURN,0ul ENDIF ;} IF( field_type EQ !opendap_NODE_Structure ) THEN BEGIN ;{ stat = OPENDAP_HANDLE_NODE( field_data, field_node, $ get_data, debug ) ENDIF ELSE BEGIN ;} ;{ stat = OPENDAP_HANDLE_CONTENT( field_data, field_node, $ row_value, field_type, $ has_content, $ get_data, debug ) ENDELSE ;} IF( stat NE 1ul ) THEN BEGIN ;{ PRINT,'Sequence field ',i_fields, $ ': failed to retrieve row ',i_rows,' content' RETURN,0ul ENDIF ;} IF( i_rows EQ 0ul ) THEN BEGIN ;{ vals = [field_data] ENDIF ELSE BEGIN ;} ;{ vals = [vals, field_data] ENDELSE ;} ENDFOR ;} IF( i_fields EQ 0ul ) THEN BEGIN ;{ opendap_data = CREATE_STRUCT( field_name, $ REFORM( TEMPORARY( vals ) ) ) ENDIF ELSE BEGIN ;} ;{ opendap_data = CREATE_STRUCT( opendap_data, field_name, $ REFORM( TEMPORARY( vals ) ) ) ENDELSE ;} ENDFOR ;} END ;} !opendap_NODE_Structure: BEGIN ;{ IF( debug gt 0ul ) THEN PRINT,"structure" ; To get here there are no attributes and no subnodes, so this ; is an empty structure OPENDAP_GET_STRUCT_INFO, content, ctMembers IF( debug GT 0ul ) THEN BEGIN ;{ PRINT,' structure contains ',ctMembers,' members' ENDIF ;} IF( ctMembers EQ 0ul ) THEN BEGIN ;{ opendap_data = CREATE_STRUCT( "EMPTY", "Empty" ) ENDIF ELSE BEGIN ;} ;{ ; This code should not be used, so just returning PRINT,' should not be getting here' RETURN,0ul FOR i_ct=0,ctMembers-1 DO BEGIN ;{ IF( debug GT 0ul ) THEN BEGIN ;{ PRINT,' retrieving member ',i_ct ENDIF ;} stat = OPENDAP_GET_STRUCT_MEMBER( content, i_ct, $ m_type, m_content ) IF( stat NE 1ul ) THEN BEGIN ;{ PRINT,'Failed to retrieve structure member ',i_ct RETURN, 0ul ENDIF ;} IF( debug GT 0ul ) THEN BEGIN ;{ PRINT,' handling member ',i_ct ENDIF ;} stat = OPENDAP_HANDLE_CONTENT( m_data, node, m_content, $ m_type, has_content, $ get_data, debug ) IF( stat NE 1ul ) THEN BEGIN ;{ PRINT,'Failed to retrieve structure member ',i_ct, $ ' content' RETURN, 0ul ENDIF ;} ENDFOR ;} ENDELSE ;} END ;} !opendap_NODE_root: BEGIN ;{ ; To get here there is nothing in the root node, no attributes ; and no content and no subnodes. opendap_data = CREATE_STRUCT( "EMPTY", "Empty" ) END ;} ELSE: BEGIN ;{ PRINT,'Unknown content type',node_type,' in opendap_handle_content' RETURN, 0ul END ;} ENDCASE ;} RETURN, 1ul ;} END