xref: /haiku/src/add-ons/kernel/file_systems/exfat/DataStream.cpp (revision 1d3959edfb0741a8a8ac768638133add307f8a19)
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 
DataStream(Volume * volume,Inode * inode,off_t size)24 DataStream::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 
~DataStream()36 DataStream::~DataStream()
37 {
38 }
39 
40 
41 status_t
FindBlock(off_t pos,off_t & physical,off_t * _length)42 DataStream::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 	if (fVolume->ClusterToBlock(cluster, block) != B_OK)
56 		return B_BAD_DATA;
57 	physical = block * kBlockSize + offset;
58 	for (uint32 i = 0; i < 64; i++) {
59 		cluster_t extentEnd = fInode->NextCluster(cluster);
60 		if (extentEnd == EXFAT_CLUSTER_END || extentEnd == cluster + 1)
61 			break;
62 		cluster = extentEnd;
63 	}
64 	*_length = min_c((cluster - clusterIndex + 1) * kClusterSize - offset,
65 		fSize - pos);
66 	TRACE("inode %" B_PRIdINO ": cluster %" B_PRIu32 ", pos %" B_PRIdOFF ", %"
67 		B_PRIdOFF "\n", fInode->ID(), clusterIndex, pos, physical);
68 	return B_OK;
69 }
70 
71