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 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 36 DataStream::~DataStream() 37 { 38 } 39 40 41 status_t 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