1/*
2 * Copyright 2011, Haiku Inc. All rights reserved.
3 * This file may be used under the terms of the MIT License.
4 *
5 * Authors:
6 *		J��r��me Duval
7 */
8
9
10#include "DataStream.h"
11
12#include "Volume.h"
13
14
15//#define TRACE_EXFAT
16#ifdef TRACE_EXFAT
17#	define TRACE(x...) dprintf("\33[34mexfat:\33[0m " x)
18#else
19#	define TRACE(x...) ;
20#endif
21#define ERROR(x...)	dprintf("\33[34mexfat:\33[0m " x)
22
23
24DataStream::DataStream(Volume* volume, Inode* inode, off_t size)
25	:
26	kBlockSize(volume->BlockSize()),
27	kClusterSize(volume->ClusterSize()),
28	fVolume(volume),
29	fInode(inode),
30	fSize(size)
31{
32	fNumBlocks = size == 0 ? 0 : ((size - 1) / kBlockSize) + 1;
33}
34
35
36DataStream::~DataStream()
37{
38}
39
40
41status_t
42DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length)
43{
44	if (pos >= fSize) {
45		TRACE("FindBlock: offset larger than size\n");
46		return B_ENTRY_NOT_FOUND;
47	}
48	cluster_t clusterIndex = pos / kClusterSize;
49	uint32 offset = pos % kClusterSize;
50
51	cluster_t cluster = fInode->StartCluster();
52	for (uint32 i = 0; i < clusterIndex; i++)
53		cluster = fInode->NextCluster(cluster);
54	fsblock_t block;
55	fVolume->ClusterToBlock(cluster, block);
56	physical = block * kBlockSize + offset;
57	for (uint32 i = 0; i < 64; i++) {
58		cluster_t extentEnd = fInode->NextCluster(cluster);
59		if (extentEnd == EXFAT_CLUSTER_END || extentEnd == cluster + 1)
60			break;
61		cluster = extentEnd;
62	}
63	*_length = min_c((cluster - clusterIndex + 1) * kClusterSize - offset,
64		fSize - pos);
65	TRACE("inode %" B_PRIdINO ": cluster %ld, pos %lld, %lld\n",
66		fInode->ID(), clusterIndex, pos, physical);
67	return B_OK;
68}
69
70