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