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