dap4/d4cdm/src/main/java/dap4/cdm/nc2/DapNetcdfFile.java
@Override
    protected Array
    readData(Variable cdmvar, Section section)
            throws IOException, InvalidRangeException
    {
        // The section is applied wrt to the DataDMR, so it
        // takes into account any constraint used in forming the dataDMR.
        // We use the Section to produce a view of the underlying variable array.

        assert this.dsp != null;
        Array result = arraymap.get(cdmvar);
        if(result == null)
            throw new IOException("No data for variable: " + cdmvar.getFullName());
        if(section != null) {
            if(cdmvar.getRank() != section.getRank())
                throw new InvalidRangeException(String.format("Section rank != %s rank", cdmvar.getFullName()));
            List<Range> ranges = section.getRanges();
            // Case out the possibilities
            if(CDMUtil.hasVLEN(ranges)) {
                ranges = ranges.subList(0, ranges.size() - 1);// may produce empty list
            }
            if(ranges.size() > 0 && !CDMUtil.isWhole(ranges, cdmvar))
                result = result.sectionNoReduce(ranges);
        }
        return result;
    }
@Override
    protected Array
    readData(Variable cdmvar, Section section)
            throws IOException, InvalidRangeException
    {
        // The section is applied wrt to the DataDMR, so it
        // takes into account any constraint used in forming the dataDMR.
        // We use the Section to produce a view of the underlying variable array.

        assert this.dsp != null;
        Array result = arraymap.get(cdmvar);
        if(result == null)
            throw new IOException("No data for variable: " + cdmvar.getFullName());
        if(section != null) {
            if(cdmvar.getRank() != section.getRank())
                throw new InvalidRangeException(String.format("Section rank != %s rank", cdmvar.getFullName()));
            List<Range> ranges = section.getRanges();
            // Case out the possibilities
            if(CDMUtil.hasVLEN(ranges)) {
                ranges = ranges.subList(0, ranges.size() - 1);// may produce empty list
            }
            if(ranges.size() > 0 && !CDMUtil.isWhole(ranges, cdmvar))
                result = result.sectionNoReduce(ranges);
        }
        return result;
    }
Primary read entry point.
This is the primary implementor of Variable.read.

@param cdmvar  A top-level variable
@param section the section of databuffer to read.
There must be a Range for each Dimension in the variable,
in order. Note: no nulls allowed.
@return An Array object for accessing the databuffer
@throws IOException           if read error
@throws InvalidRangeException if invalid section