public TransformedObject mapRange()

in function/java11/src/main/java/com/amazon/s3objectlambda/transform/RangeMapper.java [30:99]


    public TransformedObject mapRange(String rangeHeaderValue, byte[] responseObjectByteArray) {

        var rangePattern = "([a-z]+)=(\\d+)?-(\\d+)?";
        var rangeRegexPattern = Pattern.compile(rangePattern);
        var rangeRegexMatcher = rangeRegexPattern.matcher(rangeHeaderValue);

        if (!rangeRegexMatcher.find()) {
            return ResponseUtil.getErrorResponse("Invalid Range", Error.INVALID_RANGE);
        }

/*
        First part of the range from regex match.
        This contains the unit in which range is requested.
*/
        var unit = rangeRegexMatcher.group(1);
        if (!Objects.equals(unit, supportedUnit)) {
            return ResponseUtil.getErrorResponse(String.format("Only %s as unit supported but %s was provided ",
                    supportedUnit, unit), Error.INVALID_RANGE);
        }

/*
        Second and third part from the range value are <range-start> and <range-end>
        Read this from the regex matcher.
*/
        var rangeFirstPart = rangeRegexMatcher.group(2);
        var rangeLastPart = rangeRegexMatcher.group(3);

        int rangeStart;
        int rangeEnd;

        if (rangeFirstPart == null && rangeLastPart == null) {
            return ResponseUtil.getErrorResponse("Invalid Range", Error.INVALID_RANGE);
        }

        int objectLength = responseObjectByteArray.length;

        if (rangeFirstPart == null) {
            /* Range request was of the form <unit>=-<suffix-length> so we return the last `suffix-length` bytes. */
            int suffixLength = Integer.parseInt(rangeLastPart);

            /*
             If the byte array length is 26,
             the last byte is at 25th position in the array.
            */
            rangeEnd = objectLength - 1;
            rangeStart = objectLength - suffixLength;
        } else if (rangeLastPart == null) {
            /* Range request was of the form <unit>=<range-start>- so we return from range-start to the end
        of the object. */
            rangeStart = Integer.parseInt(rangeFirstPart);
            rangeEnd = objectLength - 1;
        } else {
            rangeStart = Integer.parseInt(rangeFirstPart);
            rangeEnd = Integer.parseInt(rangeLastPart);
            rangeEnd = Math.min(objectLength - 1, rangeEnd); // Should not exceed object length
        }

        if (rangeEnd < rangeStart || rangeStart < 0) {
            return ResponseUtil.getErrorResponse("Invalid Range", Error.INVALID_RANGE);
        }


//        Add 1 at the range end because Arrays.copyOfRange's is exclusive.
        byte[] objectPart = Arrays.copyOfRange(responseObjectByteArray, rangeStart, rangeEnd + 1);
        var responseObject = new TransformedObject();
        responseObject.setHasError(false);
        responseObject.setObjectResponse(objectPart);

        return responseObject;
    }