;;----------------------------------------------------------------------------- ;; Name: ARR_STRUCT ;; ;; Purpose: To construct an IDL structure for the PDS ARRAY object ;; ;; Calling Sequence: ;; struct = arr_struct (label, index, endindex, byte_count) ;; ;; Input: ;; label - string array containing the PDS label definitions for ;; current object. ;; index - the index of the label array representing the start of ;; current array object to be processed ;; endindex - the index of the label array representing the end of ;; the current array object ;; byte_count - a long integer variable tracking the bytes from ;; start of parent object; this is passed in by reference ;; ;; Output: ;; struct - an IDL structure containing the definition of current ;; array object ;; ;; External routines: Col_struct, Elem_struct, Extract_arr_subobjects ;; (from verify_arr.pro), Get_index, Extract_keyword, Remove, Break_string ;; ;; Modification history: ;; Written by Puneet Khetarpal, 30 June 2005 ;; ;;----------------------------------------------------------------------------- ;- level 1 ------------------------------------------------------------------- ; precondition: none. ; postcondition: array keywords are extracted from the label function obtain_array_keywords, label, index, endindex ; local variable total_items = 1 ; total items for the current array ; obtain axes keyword axes = extract_keyword(label, 'AXES', index, endindex, 1, 1) ; obtain axis items keyword axis_items = extract_keyword(label, 'AXIS_ITEMS', index, endindex, 1, 1) vals = break_string('AXIS_ITEMS', axis_items, long(axes)) ; separate axis_items = long(vals) ; store and convert vals to long ; multiply axis_items to obtain total items for array for k = 0, axes - 1 do total_items *= axis_items[k] ; extract name keyword name = extract_keyword(label, 'NAME', index, endindex, 1, 1) name = remove(name, '"') name = idl_validname(name, /convert_all) ; convert to idl valid name type ; extract start byte keyword if present start_byte = extract_keyword(label, 'START_BYTE', index, endindex, 0, 1) start_byte = (start_byte eq '###~') ? 1L : long(start_byte) ; store values in keywords keys = {axes:axes, axis_items:axis_items, name:name,start_byte:start_byte,$ total_items:total_items} return, keys end ;- level 0 ------------------------------------------------------------------- ; precondition: label contains an array object, start and end index ; are viable indices, and byte count is passed by reference to track ; total bytes ; postcondition: the current level of array object is constructed as ; an IDL structure, and if another array or collection subobject is ; is present, then it is called again. function arr_struct, label, index, endindex, byte_count ; error protection on_error, 1 ; initialize local variables local_count = 0 ; local data bytes count variable counter = 0 ; variable to track objects in loop ; obtain array keywords keywords = obtain_array_keywords(label, index, endindex) ; initialize structure with any byte count separation if (keywords.start_byte gt byte_count + 1) then begin diff = keywords.start_byte - byte_count - 1 byte_count += diff struct = {buffer:bytarr(diff)} endif localstruct = 0 ; local structure for the while loop ; extract sub objects from label objstruct = extract_arr_subobjects(label, index, endindex) name = objstruct.name ; store obj names subindex = objstruct.index ; store indices count = objstruct.count ; store count ; go through each of the subobjects and construct the sub structure while (counter lt count) do begin subendind = get_index(label, subindex[counter]) ; get endindex ; find how many objects are contained within this object pos = where(subindex gt subindex[counter] and subindex lt subendind, $ matches) ; obtain name of current sub object subname = extract_keyword(label,'NAME',subindex[counter],subendind,1,1) subname = remove(subname, '"') subname = idl_validname(subname, /convert_all) ; convert to valid ; process the current object for element, array, and collection if (stregex(name[counter], 'ELEMENT *',/boolean)) then begin substruct = elem_struct(label, subindex[counter], subendind, $ local_count) ;; else if array object, then process array structure endif else if (stregex(name[counter], 'ARRAY *', /boolean)) then begin substruct = arr_struct(label, subindex[counter], subendind, $ local_count) endif else begin ; process collection object structure substruct = col_struct(label, subindex[counter], subendind, $ local_count) endelse ; add to local structure the current structure if (size(localstruct, /type) eq 8) then begin ; if already defined localstruct = create_struct(localstruct, subname, substruct) endif else begin ; else create a new local structure variable localstruct = create_struct(subname, substruct) endelse ;; increment counter counter++ if (matches gt 0) then begin ; if sub objects found then counter += matches ; skip the sub objects endif endwhile ; after all the sub-elements have been gathered, replicate them ; if there is only one subelement, then only replicate that, else ; replicate the entire local structure variable localstruct = (n_tags(localstruct) eq 1) ? replicate(localstruct.(0), $ keywords.axis_items) : replicate(localstruct, keywords.axis_items) ; update byte count byte_count += keywords.total_items * local_count ; add to main structure if already defined, else define a new structure struct = (size(struct, /type) eq 8) ? create_struct(struct, keywords.name,$ localstruct) : create_struct(keywords.name, localstruct) return, struct end