ソースを参照

ImageBackingStore: Automatic fallback to SdFat on unaligned access.

CD-ROM bin/cue files may use varying sector sizes.
Petteri Aimonen 2 年 前
コミット
d0f350822f
1 ファイル変更25 行追加7 行削除
  1. 25 7
      src/ImageBackingStore.cpp

+ 25 - 7
src/ImageBackingStore.cpp

@@ -100,11 +100,13 @@ ImageBackingStore::ImageBackingStore(const char *filename, uint32_t scsi_block_s
         {
             // Convert to raw mapping, this avoids some unnecessary
             // access overhead in SdFat library.
+            // If non-aligned offsets are later requested, it automatically falls
+            // back to SdFat access mode.
             m_israw = true;
             m_blockdev = SD.card();
             m_bgnsector = begin;
             m_endsector = begin + sectorcount - 1;
-            m_fsfile.close();
+            m_fsfile.flush(); // Note: m_fsfile is also kept open as a fallback.
         }
     }
 }
@@ -185,10 +187,16 @@ bool ImageBackingStore::contiguousRange(uint32_t* bgnSector, uint32_t* endSector
 
 bool ImageBackingStore::seek(uint64_t pos)
 {
+    uint32_t sectornum = pos / SD_SECTOR_SIZE;
+
+    if (m_israw && (uint64_t)sectornum * SD_SECTOR_SIZE != pos)
+    {
+        debuglog("---- Unaligned access to image, falling back to SdFat access mode");
+        m_israw = false;
+    }
+
     if (m_israw)
     {
-        uint32_t sectornum = pos / SD_SECTOR_SIZE;
-        assert((uint64_t)sectornum * SD_SECTOR_SIZE == pos);
         m_cursector = m_bgnsector + sectornum;
         return (m_cursector <= m_endsector);
     }
@@ -207,10 +215,15 @@ bool ImageBackingStore::seek(uint64_t pos)
 
 ssize_t ImageBackingStore::read(void* buf, size_t count)
 {
+    uint32_t sectorcount = count / SD_SECTOR_SIZE;
+    if (m_israw && (uint64_t)sectorcount * SD_SECTOR_SIZE != count)
+    {
+        debuglog("---- Unaligned access to image, falling back to SdFat access mode");
+        m_israw = false;
+    }
+
     if (m_israw && m_blockdev)
     {
-        uint32_t sectorcount = count / SD_SECTOR_SIZE;
-        assert((uint64_t)sectorcount * SD_SECTOR_SIZE == count);
         if (m_blockdev->readSectors(m_cursector, (uint8_t*)buf, sectorcount))
         {
             m_cursector += sectorcount;
@@ -244,10 +257,15 @@ ssize_t ImageBackingStore::read(void* buf, size_t count)
 
 ssize_t ImageBackingStore::write(const void* buf, size_t count)
 {
+    uint32_t sectorcount = count / SD_SECTOR_SIZE;
+    if (m_israw && (uint64_t)sectorcount * SD_SECTOR_SIZE != count)
+    {
+        debuglog("---- Unaligned access to image, falling back to SdFat access mode");
+        m_israw = false;
+    }
+
     if (m_israw && m_blockdev)
     {
-        uint32_t sectorcount = count / SD_SECTOR_SIZE;
-        assert((uint64_t)sectorcount * SD_SECTOR_SIZE == count);
         if (m_blockdev->writeSectors(m_cursector, (const uint8_t*)buf, sectorcount))
         {
             m_cursector += sectorcount;