public AbstractFetchDataResult getData(final FetchDataRequest fetchDataRequest) {
        return taskContextFactory.contextResult("Data Fetcher", taskContext -> {
            taskContext.info(() -> "Fetching data for " +
                                   fetchDataRequest.getSourceLocation().getMetaId() +
                                   ":" +
                                   fetchDataRequest.getSourceLocation().getPartIndex() +
                                   ":" +
                                   fetchDataRequest.getSourceLocation().getRecordIndex());

            LOGGER.debug(() -> LogUtil.message("getData called for {}:{}:{}",
                    fetchDataRequest.getSourceLocation().getMetaId(),
                    fetchDataRequest.getSourceLocation().getPartIndex(),
                    fetchDataRequest.getSourceLocation().getRecordIndex()));

            // Allow users with 'Use' permission to read data, pipelines and XSLT.
            return securityContext.useAsReadResult(() -> {
                Set<String> availableChildStreamTypes = null;
                Meta meta = null;
                String feedName = null;
                String streamTypeName = null;
                final SourceLocation sourceLocation = fetchDataRequest.getSourceLocation();


                // Get the stream source.
                try (final Source source = streamStore.openSource(
                        fetchDataRequest.getSourceLocation().getMetaId(),
                        true)) {

                    meta = source.getMeta();
                    feedName = meta.getFeedName();
                    streamTypeName = meta.getTypeName();

                    if (sourceLocation.getPartIndex() < 0) {
                        // Handle cases during stepping when we have not yet stepped
                        return createEmptyResult(
                                fetchDataRequest,
                                feedName,
                                streamTypeName,
                                sourceLocation,
                                availableChildStreamTypes,
                                null,
                                new Count<>(0L, true));
                    }

                    long partIndex = fetchDataRequest.getSourceLocation().getPartIndex();


                    // Prevent user going past last part
//                    if (partIndex >= partCount) {
//                        partIndex = partCount - 1;
//                    }

                    try (final InputStreamProvider inputStreamProvider = source.get(partIndex)) {
                        // Find out which child stream types are available.
                        availableChildStreamTypes = getAvailableChildStreamTypes(inputStreamProvider);

                        final String requestedChildStreamType = sourceLocation.getOptChildType()
                                .orElse(null);

                        // Establish the number of parts. even though the parts in the child stream should
                        // be the same as the data stream the data stream may be corrupt so this allows
                        // us to view the other child streams
                        // We need to do this after getAvailableChildStreamTypes so if this count fails then we
                        // still know what the other strm types are.
                        partCount = source.count(requestedChildStreamType);

                        if (partIndex >= partCount) {
                            throw new RuntimeException(LogUtil.message(
                                    "Part number requested [{}] is greater than the number of parts [{}]",
                                    partIndex + 1,
                                    partCount));
                        }

                        try (final SegmentInputStream segmentInputStream = inputStreamProvider.get(
                                requestedChildStreamType)) {

                            final long segmentCount = segmentInputStream.count();
                            final boolean isSegmented = segmentCount > 1;

                            // segment no doesn't matter for non-segmented data
                            if (isSegmented && sourceLocation.getRecordIndex() < 0) {
                                // Handle cases during stepping when we have not yet stepped
                                return createEmptyResult(
                                        fetchDataRequest,
                                        feedName,
                                        streamTypeName,
                                        sourceLocation,
                                        availableChildStreamTypes,
                                        null,
                                        new Count<>(segmentCount, true));
                            }

                            // If this is an error stream and the UI is requesting markers then
                            // create a list of markers.
                            final AbstractFetchDataResult result;
                            if (StreamTypeNames.ERROR.equals(streamTypeName)
                                && (fetchDataRequest.getDisplayMode() == null
                                    || DisplayMode.MARKER.equals(fetchDataRequest.getDisplayMode()))) {

                                result = createErrorMarkerResult(
                                        feedName,
                                        streamTypeName,
                                        segmentInputStream,
                                        fetchDataRequest.getSourceLocation(),
                                        availableChildStreamTypes,
                                        fetchDataRequest.getExpandedSeverities());
                            } else if (DisplayMode.MARKER.equals(fetchDataRequest.getDisplayMode())) {
                                final String msg = LogUtil.message(
                                        "Invalid display mode {} for stream type {}",
                                        fetchDataRequest.getDisplayMode(), streamTypeName);
                                LOGGER.error(msg);
                                throw new RuntimeException(msg);
                            } else {
                                result = createDataResult(
                                        feedName,
                                        streamTypeName,
                                        segmentInputStream,
                                        availableChildStreamTypes,
                                        source,
                                        inputStreamProvider,
                                        fetchDataRequest,
                                        taskContext);
                            }
                            return result;
                        }
                    }
                } catch (final IOException | RuntimeException e) {
                    final String message;
                    if (e.getCause() instanceof ClosedByInterruptException) {
                        message = e.getMessage();
                    } else if (meta != null && Status.LOCKED.equals(meta.getStatus())) {
                        message = "You cannot view locked streams.";
                    } else if (meta != null && Status.DELETED.equals(meta.getStatus())) {
                        message = "This data may no longer exist.";
                    } else {
                        message = "Error fetching data: " + e.getMessage();
                    }

                    if (availableChildStreamTypes == null && fetchDataRequest.getSourceLocation() != null) {
                        try (final Source source = streamStore.openSource(
                                fetchDataRequest.getSourceLocation().getMetaId(), true);
                                final InputStreamProvider inputStreamProvider = source.get(
                                        fetchDataRequest.getSourceLocation().getPartIndex())) {
                            // Have a stab at getting the types so we can display all possible tabs
                            // It is possible the partindex is out of range but we will swallow any ex.
                            availableChildStreamTypes = getAvailableChildStreamTypes(inputStreamProvider);
                        } catch (Exception e2) {
                            LOGGER.debug("Error trying to get child stream types", e2);
                        }
                    }

                    LOGGER.debug(message, e);
                    return createEmptyResult(
                            fetchDataRequest,
                            feedName,
                            streamTypeName,
                            sourceLocation,
                            availableChildStreamTypes,
                            Collections.singletonList(message),
                            new Count<>(partCount, true));
                }
            });
        }).get();
    }
How big our buffers are. This should always be a multiple of 8.
stroom-data/stroom-data-store-impl/src/main/java/stroom/data/store/impl/DataFetcher.java