1//----------------------------------------------------------------------
2//  This software is part of the OpenBeOS distribution and is covered
3//  by the OpenBeOS license.
4//
5//  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6//----------------------------------------------------------------------
7
8/*! \file ExtentStream.cpp
9*/
10
11#include "ExtentStream.h"
12
13#include <stdlib.h>
14#include <string.h>
15
16ExtentStream::ExtentStream(DataStream &stream,
17                           const std::list<Udf::extent_address> &extentList,
18                           uint32 blockSize)
19	: SimulatedStream(stream)
20	, fExtentList(extentList)
21	, fBlockSize(blockSize)
22	, fSize(0)
23{
24	for (std::list<Udf::extent_address>::const_iterator i = fExtentList.begin();
25	       i != fExtentList.end();
26	         i++)
27	{
28		fSize += i->length();
29	}
30}
31
32/*! \brief Returns the largest extent in the underlying data stream
33	corresponding to the extent starting at byte position \a pos of
34	byte length \a size in the output parameter \a extent.
35
36	NOTE: If the position is at or beyond the end of the stream, the
37	function will return B_OK, but the value of extent.size will be 0.
38*/
39status_t
40ExtentStream::_GetExtent(off_t pos, size_t size, data_extent &extent)
41{
42	status_t error = pos >= 0 ? B_OK : B_BAD_VALUE;
43	if (!error) {
44		off_t finalOffset = 0;
45		off_t streamPos = 0;
46		for (std::list<Udf::extent_address>::const_iterator i = fExtentList.begin();
47		       i != fExtentList.end();
48		         i++)
49		{
50			off_t offset = i->location() * fBlockSize;
51			finalOffset = offset + i->length();
52			if (streamPos <= pos && pos < streamPos+i->length()) {
53				// Found it
54				off_t difference = pos - streamPos;
55				extent.offset = offset + difference;
56				extent.size = i->length() - difference;
57				if (extent.size > size)
58					extent.size = size;
59				return B_OK;
60			} else {
61				streamPos += i->length();
62			}
63		}
64		// Didn't find it, so pos is past the end of the stream
65		extent.offset = finalOffset;
66		extent.size = 0;
67	}
68	return error;
69}
70
71/*! \brief Returns the current size of the stream.
72*/
73off_t
74ExtentStream::_Size()
75{
76	return fSize;
77}
78