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