From 8569e324ba11ca61d908f5fdf4b234586dd69fa9 Mon Sep 17 00:00:00 2001
From: Urs Fleisch <ufleisch@users.sourceforge.net>
Date: Sun, 19 Apr 2020 11:13:55 +0200
Subject: Support large files over 2GB

Backport of 4dcf0b41c687292e7b1263a679921c157ae2c22a
b01f45e141afa6a89aea319a2783f177e202fa1d
https://github.com/taglib/taglib/pull/77

diff --git a/taglib/ape/apefile.cpp b/taglib/ape/apefile.cpp
index 07057054..4d797d1e 100644
--- a/taglib/ape/apefile.cpp
+++ b/taglib/ape/apefile.cpp
@@ -69,13 +69,13 @@ public:
     delete properties;
   }
 
-  long APELocation;
+  offset_t APELocation;
   long APESize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   ID3v2::Header *ID3v2Header;
-  long ID3v2Location;
+  offset_t ID3v2Location;
   long ID3v2Size;
 
   TagUnion tag;
@@ -292,7 +292,7 @@ void APE::File::read(bool readProperties)
 
   if(readProperties) {
 
-    long streamLength;
+    offset_t streamLength;
 
     if(d->APELocation >= 0)
       streamLength = d->APELocation;
diff --git a/taglib/ape/apeproperties.cpp b/taglib/ape/apeproperties.cpp
index ef99ad04..fe724c30 100644
--- a/taglib/ape/apeproperties.cpp
+++ b/taglib/ape/apeproperties.cpp
@@ -70,7 +70,7 @@ APE::Properties::Properties(File *, ReadStyle style) :
   debug("APE::Properties::Properties() -- This constructor is no longer used.");
 }
 
-APE::Properties::Properties(File *file, long streamLength, ReadStyle style) :
+APE::Properties::Properties(File *file, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
@@ -142,10 +142,10 @@ namespace
   }
 } // namespace
 
-void APE::Properties::read(File *file, long streamLength)
+void APE::Properties::read(File *file, offset_t streamLength)
 {
   // First, we assume that the file pointer is set at the first descriptor.
-  long offset = file->tell();
+  offset_t offset = file->tell();
   int version = headerVersion(file->readBlock(6));
 
   // Next, we look for the descriptor.
diff --git a/taglib/ape/apeproperties.h b/taglib/ape/apeproperties.h
index 8c67481a..d7ddaa30 100644
--- a/taglib/ape/apeproperties.h
+++ b/taglib/ape/apeproperties.h
@@ -61,7 +61,7 @@ namespace TagLib {
        * Create an instance of APE::Properties with the data read from the
        * APE::File \a file.
        */
-      Properties(File *file, long streamLength, ReadStyle style = Average);
+      Properties(File *file, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Destroys this APE::Properties instance.
@@ -129,7 +129,7 @@ namespace TagLib {
       Properties(const Properties &);
       Properties &operator=(const Properties &);
 
-      void read(File *file, long streamLength);
+      void read(File *file, offset_t streamLength);
 
       void analyzeCurrent(File *file);
       void analyzeOld(File *file);
diff --git a/taglib/ape/apetag.cpp b/taglib/ape/apetag.cpp
index 4235f73e..3cf91b2e 100644
--- a/taglib/ape/apetag.cpp
+++ b/taglib/ape/apetag.cpp
@@ -80,7 +80,7 @@ public:
     footerLocation(0) {}
 
   File *file;
-  long footerLocation;
+  offset_t footerLocation;
 
   Footer footer;
   ItemListMap itemListMap;
@@ -95,7 +95,7 @@ APE::Tag::Tag() :
 {
 }
 
-APE::Tag::Tag(TagLib::File *file, long footerLocation) :
+APE::Tag::Tag(TagLib::File *file, offset_t footerLocation) :
   d(new TagPrivate())
 {
   d->file = file;
diff --git a/taglib/ape/apetag.h b/taglib/ape/apetag.h
index 01504291..4829379a 100644
--- a/taglib/ape/apetag.h
+++ b/taglib/ape/apetag.h
@@ -66,7 +66,7 @@ namespace TagLib {
        * Create an APE tag and parse the data in \a file with APE footer at
        * \a tagOffset.
        */
-      Tag(TagLib::File *file, long footerLocation);
+      Tag(TagLib::File *file, offset_t footerLocation);
 
       /*!
        * Destroys this Tag instance.
diff --git a/taglib/flac/flacfile.cpp b/taglib/flac/flacfile.cpp
index a71d688b..8ff99d89 100644
--- a/taglib/flac/flacfile.cpp
+++ b/taglib/flac/flacfile.cpp
@@ -79,10 +79,10 @@ public:
   }
 
   const ID3v2::FrameFactory *ID3v2FrameFactory;
-  long ID3v2Location;
+  offset_t ID3v2Location;
   long ID3v2OriginalSize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   TagUnion tag;
 
@@ -90,8 +90,8 @@ public:
   ByteVector xiphCommentData;
   BlockList blocks;
 
-  long flacStart;
-  long streamStart;
+  offset_t flacStart;
+  offset_t streamStart;
   bool scanned;
 };
 
@@ -219,8 +219,8 @@ bool FLAC::File::save()
 
   // Compute the amount of padding, and append that to data.
 
-  long originalLength = d->streamStart - d->flacStart;
-  long paddingLength = originalLength - data.size() - 4;
+  offset_t originalLength = d->streamStart - d->flacStart;
+  offset_t paddingLength = originalLength - data.size() - 4;
 
   if(paddingLength <= 0) {
     paddingLength = MinPaddingLength;
@@ -228,9 +228,9 @@ bool FLAC::File::save()
   else {
     // Padding won't increase beyond 1% of the file size or 1MB.
 
-    long threshold = length() / 100;
-    threshold = std::max(threshold, MinPaddingLength);
-    threshold = std::min(threshold, MaxPaddingLegnth);
+    offset_t threshold = length() / 100;
+    threshold = std::max<offset_t>(threshold, MinPaddingLength);
+    threshold = std::min<offset_t>(threshold, MaxPaddingLegnth);
 
     if(paddingLength > threshold)
       paddingLength = MinPaddingLength;
@@ -341,7 +341,7 @@ ByteVector FLAC::File::streamInfoData()
   return ByteVector();
 }
 
-long FLAC::File::streamLength()
+offset_t FLAC::File::streamLength()
 {
   debug("FLAC::File::streamLength() -- This function is obsolete. Returning zero.");
   return 0;
@@ -456,7 +456,7 @@ void FLAC::File::read(bool readProperties)
 
     const ByteVector infoData = d->blocks.front()->render();
 
-    long streamLength;
+    offset_t streamLength;
 
     if(d->ID3v1Location >= 0)
       streamLength = d->ID3v1Location - d->streamStart;
@@ -477,7 +477,7 @@ void FLAC::File::scan()
   if(!isValid())
     return;
 
-  long nextBlockOffset;
+  offset_t nextBlockOffset;
 
   if(d->ID3v2Location >= 0)
     nextBlockOffset = find("fLaC", d->ID3v2Location + d->ID3v2OriginalSize);
diff --git a/taglib/flac/flacfile.h b/taglib/flac/flacfile.h
index a43c68c6..05803767 100644
--- a/taglib/flac/flacfile.h
+++ b/taglib/flac/flacfile.h
@@ -256,7 +256,7 @@ namespace TagLib {
        *
        * \deprecated Always returns zero.
        */
-      TAGLIB_DEPRECATED long streamLength();  // BIC: remove
+      TAGLIB_DEPRECATED offset_t streamLength();  // BIC: remove
 
       /*!
        * Returns a list of pictures attached to the FLAC file.
diff --git a/taglib/flac/flacproperties.cpp b/taglib/flac/flacproperties.cpp
index b947f039..a798940a 100644
--- a/taglib/flac/flacproperties.cpp
+++ b/taglib/flac/flacproperties.cpp
@@ -55,7 +55,7 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-FLAC::Properties::Properties(ByteVector data, long streamLength, ReadStyle style) :
+FLAC::Properties::Properties(ByteVector data, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
@@ -128,7 +128,7 @@ ByteVector FLAC::Properties::signature() const
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void FLAC::Properties::read(const ByteVector &data, long streamLength)
+void FLAC::Properties::read(const ByteVector &data, offset_t streamLength)
 {
   if(data.size() < 18) {
     debug("FLAC::Properties::read() - FLAC properties must contain at least 18 bytes.");
diff --git a/taglib/flac/flacproperties.h b/taglib/flac/flacproperties.h
index e58f9aea..c47e4493 100644
--- a/taglib/flac/flacproperties.h
+++ b/taglib/flac/flacproperties.h
@@ -50,7 +50,7 @@ namespace TagLib {
        * ByteVector \a data.
        */
        // BIC: switch to const reference
-      Properties(ByteVector data, long streamLength, ReadStyle style = Average);
+      Properties(ByteVector data, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Create an instance of FLAC::Properties with the data read from the
@@ -137,7 +137,7 @@ namespace TagLib {
       Properties(const Properties &);
       Properties &operator=(const Properties &);
 
-      void read(const ByteVector &data, long streamLength);
+      void read(const ByteVector &data, offset_t streamLength);
 
       class PropertiesPrivate;
       PropertiesPrivate *d;
diff --git a/taglib/mp4/mp4atom.cpp b/taglib/mp4/mp4atom.cpp
index 02e90f9c..edd615f2 100644
--- a/taglib/mp4/mp4atom.cpp
+++ b/taglib/mp4/mp4atom.cpp
@@ -93,7 +93,7 @@ MP4::Atom::Atom(File *file)
   for(int i = 0; i < numContainers; i++) {
     if(name == containers[i]) {
       if(name == "meta") {
-        long posAfterMeta = file->tell();
+        offset_t posAfterMeta = file->tell();
         ByteVector nextSize = file->readBlock(8).mid(4, 4);
         static const char *const metaChildrenNames[] = {
             "hdlr", "ilst", "mhdr", "ctry", "lang"
@@ -182,7 +182,7 @@ MP4::Atoms::Atoms(File *file)
   atoms.setAutoDelete(true);
 
   file->seek(0, File::End);
-  long end = file->tell();
+  offset_t end = file->tell();
   file->seek(0);
   while(file->tell() + 8 <= end) {
     MP4::Atom *atom = new MP4::Atom(file);
diff --git a/taglib/mp4/mp4atom.h b/taglib/mp4/mp4atom.h
index 0a0669e4..48873cc9 100644
--- a/taglib/mp4/mp4atom.h
+++ b/taglib/mp4/mp4atom.h
@@ -80,8 +80,8 @@ namespace TagLib {
       Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
       bool path(AtomList &path, const char *name1, const char *name2 = 0, const char *name3 = 0);
       AtomList findall(const char *name, bool recursive = false);
-      long offset;
-      long length;
+      offset_t offset;
+      offset_t length;
       TagLib::ByteVector name;
       AtomList children;
     private:
diff --git a/taglib/mp4/mp4properties.cpp b/taglib/mp4/mp4properties.cpp
index df628800..fa2ed147 100644
--- a/taglib/mp4/mp4properties.cpp
+++ b/taglib/mp4/mp4properties.cpp
@@ -38,7 +38,7 @@ namespace
   {
     long long totalLength = 0;
     for(MP4::AtomList::ConstIterator it = list.begin(); it != list.end(); ++it) {
-      long length = (*it)->length;
+      offset_t length = (*it)->length;
       if(length == 0)
         return 0; // for safety, see checkValid() in mp4file.cpp
 
diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp
index 946c789d..5ba83474 100644
--- a/taglib/mp4/mp4tag.cpp
+++ b/taglib/mp4/mp4tag.cpp
@@ -583,7 +583,7 @@ MP4::Tag::updateParents(const AtomList &path, long delta, int ignore)
 }
 
 void
-MP4::Tag::updateOffsets(long delta, long offset)
+MP4::Tag::updateOffsets(long delta, offset_t offset)
 {
   MP4::Atom *moov = d->atoms->find("moov");
   if(moov) {
@@ -667,7 +667,7 @@ MP4::Tag::saveNew(ByteVector data)
     data = renderAtom("udta", data);
   }
 
-  long offset = path.back()->offset + 8;
+  offset_t offset = path.back()->offset + 8;
   d->file->insert(data, offset, 0);
 
   updateParents(path, data.size());
@@ -685,8 +685,8 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
   AtomList::ConstIterator it = path.end();
 
   MP4::Atom *ilst = *(--it);
-  long offset = ilst->offset;
-  long length = ilst->length;
+  offset_t offset = ilst->offset;
+  offset_t length = ilst->length;
 
   MP4::Atom *meta = *(--it);
   AtomList::ConstIterator index = meta->children.find(ilst);
diff --git a/taglib/mp4/mp4tag.h b/taglib/mp4/mp4tag.h
index 42b3d4b3..a4f78cf1 100644
--- a/taglib/mp4/mp4tag.h
+++ b/taglib/mp4/mp4tag.h
@@ -149,7 +149,7 @@ namespace TagLib {
         ByteVector renderCovr(const ByteVector &name, const Item &item) const;
 
         void updateParents(const AtomList &path, long delta, int ignore = 0);
-        void updateOffsets(long delta, long offset);
+        void updateOffsets(long delta, offset_t offset);
 
         void saveNew(ByteVector data);
         void saveExisting(ByteVector data, const AtomList &path);
diff --git a/taglib/mpc/mpcfile.cpp b/taglib/mpc/mpcfile.cpp
index 4e955875..7070649b 100644
--- a/taglib/mpc/mpcfile.cpp
+++ b/taglib/mpc/mpcfile.cpp
@@ -61,13 +61,13 @@ public:
     delete properties;
   }
 
-  long APELocation;
+  offset_t APELocation;
   long APESize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   ID3v2::Header *ID3v2Header;
-  long ID3v2Location;
+  offset_t ID3v2Location;
   long ID3v2Size;
 
   TagUnion tag;
@@ -310,7 +310,7 @@ void MPC::File::read(bool readProperties)
 
   if(readProperties) {
 
-    long streamLength;
+    offset_t streamLength;
 
     if(d->APELocation >= 0)
       streamLength = d->APELocation;
diff --git a/taglib/mpc/mpcproperties.cpp b/taglib/mpc/mpcproperties.cpp
index effaabed..724e5c7d 100644
--- a/taglib/mpc/mpcproperties.cpp
+++ b/taglib/mpc/mpcproperties.cpp
@@ -66,14 +66,14 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) :
+MPC::Properties::Properties(const ByteVector &data, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
   readSV7(data, streamLength);
 }
 
-MPC::Properties::Properties(File *file, long streamLength, ReadStyle style) :
+MPC::Properties::Properties(File *file, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
@@ -203,7 +203,7 @@ namespace
   const unsigned short sftable [8] = { 44100, 48000, 37800, 32000, 0, 0, 0, 0 };
 }  // namespace
 
-void MPC::Properties::readSV8(File *file, long streamLength)
+void MPC::Properties::readSV8(File *file, offset_t streamLength)
 {
   bool readSH = false, readRG = false;
 
@@ -295,7 +295,7 @@ void MPC::Properties::readSV8(File *file, long streamLength)
   }
 }
 
-void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
+void MPC::Properties::readSV7(const ByteVector &data, offset_t streamLength)
 {
   if(data.startsWith("MP+")) {
     if(data.size() < 4)
diff --git a/taglib/mpc/mpcproperties.h b/taglib/mpc/mpcproperties.h
index 1db925d6..2c692735 100644
--- a/taglib/mpc/mpcproperties.h
+++ b/taglib/mpc/mpcproperties.h
@@ -53,13 +53,13 @@ namespace TagLib {
        *
        * This constructor is deprecated. It only works for MPC version up to 7.
        */
-      Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
+      Properties(const ByteVector &data, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Create an instance of MPC::Properties with the data read directly
        * from a MPC::File.
        */
-      Properties(File *file, long streamLength, ReadStyle style = Average);
+      Properties(File *file, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Destroys this MPC::Properties instance.
@@ -146,8 +146,8 @@ namespace TagLib {
       Properties(const Properties &);
       Properties &operator=(const Properties &);
 
-      void readSV7(const ByteVector &data, long streamLength);
-      void readSV8(File *file, long streamLength);
+      void readSV7(const ByteVector &data, offset_t streamLength);
+      void readSV8(File *file, offset_t streamLength);
 
       class PropertiesPrivate;
       PropertiesPrivate *d;
diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp
index 667adfa6..bdf1b9a8 100644
--- a/taglib/mpeg/id3v1/id3v1tag.cpp
+++ b/taglib/mpeg/id3v1/id3v1tag.cpp
@@ -48,7 +48,7 @@ public:
     genre(255) {}
 
   File *file;
-  long tagOffset;
+  offset_t tagOffset;
 
   String title;
   String artist;
@@ -88,7 +88,7 @@ ID3v1::Tag::Tag() :
 {
 }
 
-ID3v1::Tag::Tag(File *file, long tagOffset) :
+ID3v1::Tag::Tag(File *file, offset_t tagOffset) :
   d(new TagPrivate())
 {
   d->file = file;
diff --git a/taglib/mpeg/id3v1/id3v1tag.h b/taglib/mpeg/id3v1/id3v1tag.h
index 5803312f..acdda66c 100644
--- a/taglib/mpeg/id3v1/id3v1tag.h
+++ b/taglib/mpeg/id3v1/id3v1tag.h
@@ -114,7 +114,7 @@ namespace TagLib {
        * Create an ID3v1 tag and parse the data in \a file starting at
        * \a tagOffset.
        */
-      Tag(File *file, long tagOffset);
+      Tag(File *file, offset_t tagOffset);
 
       /*!
        * Destroys this Tag instance.
diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp
index f1930d0e..ba0ddb1e 100644
--- a/taglib/mpeg/id3v2/id3v2tag.cpp
+++ b/taglib/mpeg/id3v2/id3v2tag.cpp
@@ -88,7 +88,7 @@ public:
   const FrameFactory *factory;
 
   File *file;
-  long tagOffset;
+  offset_t tagOffset;
 
   Header header;
   ExtendedHeader *extendedHeader;
@@ -125,7 +125,7 @@ ID3v2::Tag::Tag() :
   d->factory = FrameFactory::instance();
 }
 
-ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) :
+ID3v2::Tag::Tag(File *file, offset_t tagOffset, const FrameFactory *factory) :
   d(new TagPrivate())
 {
   d->factory = factory;
@@ -686,9 +686,9 @@ ByteVector ID3v2::Tag::render(Version version) const
   else {
     // Padding won't increase beyond 1% of the file size or 1MB.
 
-    long threshold = d->file ? d->file->length() / 100 : 0;
-    threshold = std::max(threshold, MinPaddingSize);
-    threshold = std::min(threshold, MaxPaddingSize);
+    offset_t threshold = d->file ? d->file->length() / 100 : 0;
+    threshold = std::max<offset_t>(threshold, MinPaddingSize);
+    threshold = std::min<offset_t>(threshold, MaxPaddingSize);
 
     if(paddingSize > threshold)
       paddingSize = MinPaddingSize;
diff --git a/taglib/mpeg/id3v2/id3v2tag.h b/taglib/mpeg/id3v2/id3v2tag.h
index b0b61749..1c7bcac9 100644
--- a/taglib/mpeg/id3v2/id3v2tag.h
+++ b/taglib/mpeg/id3v2/id3v2tag.h
@@ -146,7 +146,7 @@ namespace TagLib {
        *
        * \see FrameFactory
        */
-      Tag(File *file, long tagOffset,
+      Tag(File *file, offset_t tagOffset,
           const FrameFactory *factory = FrameFactory::instance());
 
       /*!
diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
index efe8af2a..a852b939 100644
--- a/taglib/mpeg/mpegfile.cpp
+++ b/taglib/mpeg/mpegfile.cpp
@@ -63,13 +63,13 @@ public:
 
   const ID3v2::FrameFactory *ID3v2FrameFactory;
 
-  long ID3v2Location;
+  offset_t ID3v2Location;
   long ID3v2OriginalSize;
 
-  long APELocation;
+  offset_t APELocation;
   long APEOriginalSize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   TagUnion tag;
 
@@ -105,13 +105,13 @@ bool MPEG::File::isSupported(IOStream *stream)
   // MPEG frame headers are really confusing with irrelevant binary data.
   // So we check if a frame header is really valid.
 
-  long headerOffset;
+  offset_t headerOffset;
   const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true, &headerOffset);
 
   if(buffer.isEmpty())
       return false;
 
-  const long originalPosition = stream->tell();
+  const offset_t originalPosition = stream->tell();
   AdapterFile file(stream);
 
   for(unsigned int i = 0; i < buffer.size() - 1; ++i) {
@@ -406,7 +406,7 @@ void MPEG::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
   d->ID3v2FrameFactory = factory;
 }
 
-long MPEG::File::nextFrameOffset(long position)
+offset_t MPEG::File::nextFrameOffset(offset_t position)
 {
   ByteVector frameSyncBytes(2, '\0');
 
@@ -430,12 +430,12 @@ long MPEG::File::nextFrameOffset(long position)
   }
 }
 
-long MPEG::File::previousFrameOffset(long position)
+offset_t MPEG::File::previousFrameOffset(offset_t position)
 {
   ByteVector frameSyncBytes(2, '\0');
 
   while(position > 0) {
-    const long bufferLength = std::min<long>(position, bufferSize());
+    const offset_t bufferLength = std::min<offset_t>(position, bufferSize());
     position -= bufferLength;
 
     seek(position);
@@ -455,9 +455,9 @@ long MPEG::File::previousFrameOffset(long position)
   return -1;
 }
 
-long MPEG::File::firstFrameOffset()
+offset_t MPEG::File::firstFrameOffset()
 {
-  long position = 0;
+  offset_t position = 0;
 
   if(hasID3v2Tag())
     position = d->ID3v2Location + ID3v2Tag()->header()->completeTagSize();
@@ -465,9 +465,9 @@ long MPEG::File::firstFrameOffset()
   return nextFrameOffset(position);
 }
 
-long MPEG::File::lastFrameOffset()
+offset_t MPEG::File::lastFrameOffset()
 {
-  long position;
+  offset_t position;
 
   if(hasAPETag())
     position = d->APELocation - 1;
@@ -535,7 +535,7 @@ void MPEG::File::read(bool readProperties)
   ID3v1Tag(true);
 }
 
-long MPEG::File::findID3v2()
+offset_t MPEG::File::findID3v2()
 {
   if(!isValid())
     return -1;
diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h
index 381d89a0..2020f154 100644
--- a/taglib/mpeg/mpegfile.h
+++ b/taglib/mpeg/mpegfile.h
@@ -322,24 +322,24 @@ namespace TagLib {
       /*!
        * Returns the position in the file of the first MPEG frame.
        */
-      long firstFrameOffset();
+      offset_t firstFrameOffset();
 
       /*!
        * Returns the position in the file of the next MPEG frame,
        * using the current position as start
        */
-      long nextFrameOffset(long position);
+      offset_t nextFrameOffset(offset_t position);
 
       /*!
        * Returns the position in the file of the previous MPEG frame,
        * using the current position as start
        */
-      long previousFrameOffset(long position);
+      offset_t previousFrameOffset(offset_t position);
 
       /*!
        * Returns the position in the file of the last MPEG frame.
        */
-      long lastFrameOffset();
+      offset_t lastFrameOffset();
 
       /*!
        * Returns whether or not the file on disk actually has an ID3v1 tag.
@@ -376,7 +376,7 @@ namespace TagLib {
       File &operator=(const File &);
 
       void read(bool readProperties);
-      long findID3v2();
+      offset_t findID3v2();
 
       class FilePrivate;
       FilePrivate *d;
diff --git a/taglib/mpeg/mpegheader.cpp b/taglib/mpeg/mpegheader.cpp
index 5a5015d6..b9405008 100644
--- a/taglib/mpeg/mpegheader.cpp
+++ b/taglib/mpeg/mpegheader.cpp
@@ -75,7 +75,7 @@ MPEG::Header::Header(const ByteVector &data) :
   debug("MPEG::Header::Header() - This constructor is no longer used.");
 }
 
-MPEG::Header::Header(File *file, long offset, bool checkLength) :
+MPEG::Header::Header(File *file, offset_t offset, bool checkLength) :
   d(new HeaderPrivate())
 {
   parse(file, offset, checkLength);
@@ -170,7 +170,7 @@ MPEG::Header &MPEG::Header::operator=(const Header &h)
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void MPEG::Header::parse(File *file, long offset, bool checkLength)
+void MPEG::Header::parse(File *file, offset_t offset, bool checkLength)
 {
   file->seek(offset);
   const ByteVector data = file->readBlock(4);
diff --git a/taglib/mpeg/mpegheader.h b/taglib/mpeg/mpegheader.h
index cb8eb251..3c260625 100644
--- a/taglib/mpeg/mpegheader.h
+++ b/taglib/mpeg/mpegheader.h
@@ -61,7 +61,7 @@ namespace TagLib {
        * check if the frame length is parsed and calculated correctly.  So it's
        * suitable for seeking for the first valid frame.
        */
-      Header(File *file, long offset, bool checkLength = true);
+      Header(File *file, offset_t offset, bool checkLength = true);
 
       /*!
        * Does a shallow copy of \a h.
@@ -167,7 +167,7 @@ namespace TagLib {
       Header &operator=(const Header &h);
 
     private:
-      void parse(File *file, long offset, bool checkLength);
+      void parse(File *file, offset_t offset, bool checkLength);
 
       class HeaderPrivate;
       HeaderPrivate *d;
diff --git a/taglib/mpeg/mpegproperties.cpp b/taglib/mpeg/mpegproperties.cpp
index 5eec84f7..d66f8ab1 100644
--- a/taglib/mpeg/mpegproperties.cpp
+++ b/taglib/mpeg/mpegproperties.cpp
@@ -157,7 +157,7 @@ void MPEG::Properties::read(File *file)
 {
   // Only the first valid frame is required if we have a VBR header.
 
-  const long firstFrameOffset = file->firstFrameOffset();
+  const offset_t firstFrameOffset = file->firstFrameOffset();
   if(firstFrameOffset < 0) {
     debug("MPEG::Properties::read() -- Could not find an MPEG frame in the stream.");
     return;
@@ -197,14 +197,14 @@ void MPEG::Properties::read(File *file)
 
     // Look for the last MPEG audio frame to calculate the stream length.
 
-    const long lastFrameOffset = file->lastFrameOffset();
+    const offset_t lastFrameOffset = file->lastFrameOffset();
     if(lastFrameOffset < 0) {
       debug("MPEG::Properties::read() -- Could not find an MPEG frame in the stream.");
     }
     else
     {
       const Header lastHeader(file, lastFrameOffset, false);
-      const long streamLength = lastFrameOffset - firstFrameOffset + lastHeader.frameLength();
+      const offset_t streamLength = lastFrameOffset - firstFrameOffset + lastHeader.frameLength();
       if (streamLength > 0)
         d->length = static_cast<int>(streamLength * 8.0 / d->bitrate + 0.5);
     }
diff --git a/taglib/ogg/flac/oggflacfile.cpp b/taglib/ogg/flac/oggflacfile.cpp
index 07ea9dcc..5c2f95c6 100644
--- a/taglib/ogg/flac/oggflacfile.cpp
+++ b/taglib/ogg/flac/oggflacfile.cpp
@@ -58,8 +58,8 @@ public:
   Properties *properties;
   ByteVector streamInfoData;
   ByteVector xiphCommentData;
-  long streamStart;
-  long streamLength;
+  offset_t streamStart;
+  offset_t streamLength;
   bool scanned;
 
   bool hasXiphComment;
@@ -206,7 +206,7 @@ ByteVector Ogg::FLAC::File::xiphCommentData()
   return d->xiphCommentData;
 }
 
-long Ogg::FLAC::File::streamLength()
+offset_t Ogg::FLAC::File::streamLength()
 {
   scan();
   return d->streamLength;
@@ -223,7 +223,7 @@ void Ogg::FLAC::File::scan()
     return;
 
   int ipacket = 0;
-  long overhead = 0;
+  offset_t overhead = 0;
 
   ByteVector metadataHeader = packet(ipacket);
   if(metadataHeader.isEmpty())
diff --git a/taglib/ogg/flac/oggflacfile.h b/taglib/ogg/flac/oggflacfile.h
index b2686e45..0e5e1ac4 100644
--- a/taglib/ogg/flac/oggflacfile.h
+++ b/taglib/ogg/flac/oggflacfile.h
@@ -134,7 +134,7 @@ namespace TagLib {
        * Returns the length of the audio-stream, used by FLAC::Properties for
        * calculating the bitrate.
        */
-      long streamLength();
+      offset_t streamLength();
 
       /*!
        * Returns whether or not the file on disk actually has a XiphComment.
diff --git a/taglib/ogg/oggfile.cpp b/taglib/ogg/oggfile.cpp
index 1f2cce93..86063915 100644
--- a/taglib/ogg/oggfile.cpp
+++ b/taglib/ogg/oggfile.cpp
@@ -129,7 +129,7 @@ void Ogg::File::setPacket(unsigned int i, const ByteVector &p)
 const Ogg::PageHeader *Ogg::File::firstPageHeader()
 {
   if(!d->firstPageHeader) {
-    const long firstPageHeaderOffset = find("OggS");
+    const offset_t firstPageHeaderOffset = find("OggS");
     if(firstPageHeaderOffset < 0)
       return 0;
 
@@ -142,7 +142,7 @@ const Ogg::PageHeader *Ogg::File::firstPageHeader()
 const Ogg::PageHeader *Ogg::File::lastPageHeader()
 {
   if(!d->lastPageHeader) {
-    const long lastPageHeaderOffset = rfind("OggS");
+    const offset_t lastPageHeaderOffset = rfind("OggS");
     if(lastPageHeaderOffset < 0)
       return 0;
 
@@ -192,7 +192,7 @@ bool Ogg::File::readPages(unsigned int i)
 {
   while(true) {
     unsigned int packetIndex;
-    long offset;
+    offset_t offset;
 
     if(d->pages.isEmpty()) {
       packetIndex = 0;
@@ -275,8 +275,8 @@ void Ogg::File::writePacket(unsigned int i, const ByteVector &packet)
   for(it = pages.begin(); it != pages.end(); ++it)
     data.append((*it)->render());
 
-  const unsigned long originalOffset = firstPage->fileOffset();
-  const unsigned long originalLength = lastPage->fileOffset() + lastPage->size() - originalOffset;
+  const offset_t originalOffset = firstPage->fileOffset();
+  const offset_t originalLength = lastPage->fileOffset() + lastPage->size() - originalOffset;
 
   insert(data, originalOffset, originalLength);
 
@@ -286,7 +286,7 @@ void Ogg::File::writePacket(unsigned int i, const ByteVector &packet)
     = pages.back()->pageSequenceNumber() - lastPage->pageSequenceNumber();
 
   if(numberOfNewPages != 0) {
-    long pageOffset = originalOffset + data.size();
+    offset_t pageOffset = originalOffset + data.size();
 
     while(true) {
       Page page(this, pageOffset);
diff --git a/taglib/ogg/oggpage.cpp b/taglib/ogg/oggpage.cpp
index 869c357a..990b4c4f 100644
--- a/taglib/ogg/oggpage.cpp
+++ b/taglib/ogg/oggpage.cpp
@@ -37,14 +37,14 @@ using namespace TagLib;
 class Ogg::Page::PagePrivate
 {
 public:
-  PagePrivate(File *f = 0, long pageOffset = -1) :
+  PagePrivate(File *f = 0, offset_t pageOffset = -1) :
     file(f),
     fileOffset(pageOffset),
     header(f, pageOffset),
     firstPacketIndex(-1) {}
 
   File *file;
-  long fileOffset;
+  offset_t fileOffset;
   PageHeader header;
   int firstPacketIndex;
   ByteVectorList packets;
@@ -54,7 +54,7 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-Ogg::Page::Page(Ogg::File *file, long pageOffset) :
+Ogg::Page::Page(Ogg::File *file, offset_t pageOffset) :
   d(new PagePrivate(file, pageOffset))
 {
 }
@@ -64,7 +64,7 @@ Ogg::Page::~Page()
   delete d;
 }
 
-long Ogg::Page::fileOffset() const
+offset_t Ogg::Page::fileOffset() const
 {
   return d->fileOffset;
 }
diff --git a/taglib/ogg/oggpage.h b/taglib/ogg/oggpage.h
index 4829b070..4ed704f6 100644
--- a/taglib/ogg/oggpage.h
+++ b/taglib/ogg/oggpage.h
@@ -55,14 +55,14 @@ namespace TagLib {
       /*!
        * Read an Ogg page from the \a file at the position \a pageOffset.
        */
-      Page(File *file, long pageOffset);
+      Page(File *file, offset_t pageOffset);
 
       virtual ~Page();
 
       /*!
        * Returns the page's position within the file (in bytes).
        */
-      long fileOffset() const;
+      offset_t fileOffset() const;
 
       /*!
        * Returns a pointer to the header for this page.  This pointer will become
diff --git a/taglib/ogg/oggpageheader.cpp b/taglib/ogg/oggpageheader.cpp
index 3c3c4ee1..10a1efc2 100644
--- a/taglib/ogg/oggpageheader.cpp
+++ b/taglib/ogg/oggpageheader.cpp
@@ -66,7 +66,7 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-Ogg::PageHeader::PageHeader(Ogg::File *file, long pageOffset) :
+Ogg::PageHeader::PageHeader(Ogg::File *file, offset_t pageOffset) :
   d(new PageHeaderPrivate())
 {
   if(file && pageOffset >= 0)
@@ -225,7 +225,7 @@ ByteVector Ogg::PageHeader::render() const
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void Ogg::PageHeader::read(Ogg::File *file, long pageOffset)
+void Ogg::PageHeader::read(Ogg::File *file, offset_t pageOffset)
 {
   file->seek(pageOffset);
 
diff --git a/taglib/ogg/oggpageheader.h b/taglib/ogg/oggpageheader.h
index d62feb3d..29709626 100644
--- a/taglib/ogg/oggpageheader.h
+++ b/taglib/ogg/oggpageheader.h
@@ -52,7 +52,7 @@ namespace TagLib {
        * create a page with no (and as such, invalid) data that must be set
        * later.
        */
-      PageHeader(File *file = 0, long pageOffset = -1);
+      PageHeader(File *file = 0, offset_t pageOffset = -1);
 
       /*!
        * Deletes this instance of the PageHeader.
@@ -219,7 +219,7 @@ namespace TagLib {
       PageHeader(const PageHeader &);
       PageHeader &operator=(const PageHeader &);
 
-      void read(Ogg::File *file, long pageOffset);
+      void read(Ogg::File *file, offset_t pageOffset);
       ByteVector lacingValues() const;
 
       class PageHeaderPrivate;
diff --git a/taglib/ogg/opus/opusproperties.cpp b/taglib/ogg/opus/opusproperties.cpp
index b60cc01d..e19ab64d 100644
--- a/taglib/ogg/opus/opusproperties.cpp
+++ b/taglib/ogg/opus/opusproperties.cpp
@@ -163,7 +163,7 @@ void Opus::Properties::read(File *file)
 
       if(frameCount > 0) {
         const double length = frameCount * 1000.0 / 48000.0;
-        long fileLengthWithoutOverhead = file->length();
+        offset_t fileLengthWithoutOverhead = file->length();
         // Ignore the two mandatory header packets, see "3. Packet Organization"
         // in https://tools.ietf.org/html/rfc7845.html
         for (unsigned int i = 0; i < 2; ++i) {
diff --git a/taglib/ogg/speex/speexproperties.cpp b/taglib/ogg/speex/speexproperties.cpp
index b7a11cc6..fae184a0 100644
--- a/taglib/ogg/speex/speexproperties.cpp
+++ b/taglib/ogg/speex/speexproperties.cpp
@@ -182,7 +182,7 @@ void Speex::Properties::read(File *file)
 
       if(frameCount > 0) {
         const double length = frameCount * 1000.0 / d->sampleRate;
-        long fileLengthWithoutOverhead = file->length();
+        offset_t fileLengthWithoutOverhead = file->length();
         // Ignore the two header packets, see "Ogg file format" in
         // https://www.speex.org/docs/manual/speex-manual/node8.html
         for (unsigned int i = 0; i < 2; ++i) {
diff --git a/taglib/ogg/vorbis/vorbisproperties.cpp b/taglib/ogg/vorbis/vorbisproperties.cpp
index c2909204..b38e138a 100644
--- a/taglib/ogg/vorbis/vorbisproperties.cpp
+++ b/taglib/ogg/vorbis/vorbisproperties.cpp
@@ -186,7 +186,7 @@ void Vorbis::Properties::read(File *file)
 
       if(frameCount > 0) {
         const double length = frameCount * 1000.0 / d->sampleRate;
-        long fileLengthWithoutOverhead = file->length();
+        offset_t fileLengthWithoutOverhead = file->length();
         // Ignore the three initial header packets, see "1.3.1. Decode Setup" in
         // https://xiph.org/vorbis/doc/Vorbis_I_spec.html
         for (unsigned int i = 0; i < 3; ++i) {
diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp
index 005551f4..87ce7240 100644
--- a/taglib/riff/rifffile.cpp
+++ b/taglib/riff/rifffile.cpp
@@ -38,7 +38,7 @@ using namespace TagLib;
 struct Chunk
 {
   ByteVector   name;
-  unsigned int offset;
+  offset_t offset;
   unsigned int size;
   unsigned int padding;
 };
@@ -54,7 +54,7 @@ public:
   const Endianness endianness;
 
   unsigned int size;
-  long sizeOffset;
+  offset_t sizeOffset;
 
   std::vector<Chunk> chunks;
 };
@@ -108,7 +108,7 @@ unsigned int RIFF::File::chunkDataSize(unsigned int i) const
   return d->chunks[i].size;
 }
 
-unsigned int RIFF::File::chunkOffset(unsigned int i) const
+offset_t RIFF::File::chunkOffset(unsigned int i) const
 {
   if(i >= d->chunks.size()) {
     debug("RIFF::File::chunkOffset() - Index out of range. Returning 0.");
@@ -212,7 +212,7 @@ void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bo
 
   Chunk &last = d->chunks.back();
 
-  long offset = last.offset + last.size + last.padding;
+  offset_t offset = last.offset + last.size + last.padding;
   if(offset & 1) {
     if(last.padding == 1) {
       last.padding = 0; // This should not happen unless the file is corrupted.
@@ -283,7 +283,7 @@ void RIFF::File::read()
 {
   const bool bigEndian = (d->endianness == BigEndian);
 
-  long offset = tell();
+  offset_t offset = tell();
 
   offset += 4;
   d->sizeOffset = offset;
@@ -345,7 +345,7 @@ void RIFF::File::read()
 }
 
 void RIFF::File::writeChunk(const ByteVector &name, const ByteVector &data,
-                            unsigned long offset, unsigned long replace)
+                            offset_t offset, unsigned long replace)
 {
   ByteVector combined;
 
diff --git a/taglib/riff/rifffile.h b/taglib/riff/rifffile.h
index 1ed49503..314dc4d9 100644
--- a/taglib/riff/rifffile.h
+++ b/taglib/riff/rifffile.h
@@ -71,7 +71,7 @@ namespace TagLib {
       /*!
        * \return The offset within the file for the selected chunk number.
        */
-      unsigned int chunkOffset(unsigned int i) const;
+      offset_t chunkOffset(unsigned int i) const;
 
       /*!
        * \return The size of the chunk data.
@@ -145,7 +145,7 @@ namespace TagLib {
 
       void read();
       void writeChunk(const ByteVector &name, const ByteVector &data,
-                      unsigned long offset, unsigned long replace = 0);
+                      offset_t offset, unsigned long replace = 0);
 
       /*!
        * Update the global RIFF size based on the current internal structure.
diff --git a/taglib/tagutils.cpp b/taglib/tagutils.cpp
index 5fcd12aa..27154dc3 100644
--- a/taglib/tagutils.cpp
+++ b/taglib/tagutils.cpp
@@ -33,7 +33,7 @@
 
 using namespace TagLib;
 
-long Utils::findID3v1(File *file)
+offset_t Utils::findID3v1(File *file)
 {
   if(!file->isValid())
     return -1;
@@ -42,14 +42,14 @@ long Utils::findID3v1(File *file)
 
   if (file->length() >= 131) {
     file->seek(-131, File::End);
-    const long p = file->tell() + 3;
+    const offset_t p = file->tell() + 3;
     const TagLib::ByteVector data = file->readBlock(8);
 
     if(data.containsAt(ID3v1::Tag::fileIdentifier(), 3) && (data != APE::Tag::fileIdentifier()))
       return p;
   } else {
     file->seek(-128, File::End);
-    const long p = file->tell();
+    const offset_t p = file->tell();
 
     if(file->readBlock(3) == ID3v1::Tag::fileIdentifier())
       return p;
@@ -58,7 +58,7 @@ long Utils::findID3v1(File *file)
   return -1;
 }
 
-long Utils::findID3v2(File *file)
+offset_t Utils::findID3v2(File *file)
 {
   if(!file->isValid())
     return -1;
@@ -71,7 +71,7 @@ long Utils::findID3v2(File *file)
   return -1;
 }
 
-long Utils::findAPE(File *file, long id3v1Location)
+offset_t Utils::findAPE(File *file, offset_t id3v1Location)
 {
   if(!file->isValid())
     return -1;
@@ -81,7 +81,7 @@ long Utils::findAPE(File *file, long id3v1Location)
   else
     file->seek(-32, File::End);
 
-  const long p = file->tell();
+  const offset_t p = file->tell();
 
   if(file->readBlock(8) == APE::Tag::fileIdentifier())
     return p;
@@ -90,13 +90,13 @@ long Utils::findAPE(File *file, long id3v1Location)
 }
 
 ByteVector TagLib::Utils::readHeader(IOStream *stream, unsigned int length,
-                                     bool skipID3v2, long *headerOffset)
+                                     bool skipID3v2, offset_t *headerOffset)
 {
   if(!stream || !stream->isOpen())
     return ByteVector();
 
-  const long originalPosition = stream->tell();
-  long bufferOffset = 0;
+  const offset_t originalPosition = stream->tell();
+  offset_t bufferOffset = 0;
 
   if(skipID3v2) {
     stream->seek(0);
diff --git a/taglib/tagutils.h b/taglib/tagutils.h
index b7863494..c2bba562 100644
--- a/taglib/tagutils.h
+++ b/taglib/tagutils.h
@@ -39,14 +39,14 @@ namespace TagLib {
 
   namespace Utils {
 
-    long findID3v1(File *file);
+    offset_t findID3v1(File *file);
 
-    long findID3v2(File *file);
+    offset_t findID3v2(File *file);
 
-    long findAPE(File *file, long id3v1Location);
+    offset_t findAPE(File *file, offset_t id3v1Location);
 
     ByteVector readHeader(IOStream *stream, unsigned int length, bool skipID3v2,
-                          long *headerOffset = 0);
+                          offset_t *headerOffset = 0);
   }  // namespace Utils
 }  // namespace TagLib
 
diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h
index 64ccf0a8..21e6d5ff 100644
--- a/taglib/toolkit/taglib.h
+++ b/taglib/toolkit/taglib.h
@@ -54,6 +54,11 @@
 #define TAGLIB_DEPRECATED
 #endif
 
+#define TAGLIB_WITH_OFFSET_TYPE
+#ifndef _WIN32
+#include <sys/types.h>
+#endif
+
 #include <string>
 
 //! A namespace for all TagLib related classes and functions
@@ -79,6 +84,14 @@ namespace TagLib {
   typedef unsigned long      ulong;
   typedef unsigned long long ulonglong;
 
+  // Offset or length type for I/O streams.
+  // In Win32, always 64bit. Otherwise, equivalent to off_t.
+#ifdef _WIN32
+  typedef long long offset_t;
+#else
+  typedef off_t     offset_t;
+#endif
+
   /*!
    * Unfortunately std::wstring isn't defined on some systems, (i.e. GCC < 3)
    * so I'm providing something here that should be constant.
diff --git a/taglib/toolkit/tbytevectorstream.cpp b/taglib/toolkit/tbytevectorstream.cpp
index bce3a7c6..09053597 100644
--- a/taglib/toolkit/tbytevectorstream.cpp
+++ b/taglib/toolkit/tbytevectorstream.cpp
@@ -40,7 +40,7 @@ public:
   ByteVectorStreamPrivate(const ByteVector &data);
 
   ByteVector data;
-  long position;
+  offset_t position;
 };
 
 ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) :
@@ -88,7 +88,7 @@ void ByteVectorStream::writeBlock(const ByteVector &data)
   d->position += size;
 }
 
-void ByteVectorStream::insert(const ByteVector &data, unsigned long start, unsigned long replace)
+void ByteVectorStream::insert(const ByteVector &data, offset_t start, unsigned long replace)
 {
   long sizeDiff = data.size() - replace;
   if(sizeDiff < 0) {
@@ -96,20 +96,20 @@ void ByteVectorStream::insert(const ByteVector &data, unsigned long start, unsig
   }
   else if(sizeDiff > 0) {
     truncate(length() + sizeDiff);
-    unsigned long readPosition  = start + replace;
-    unsigned long writePosition = start + data.size();
+    offset_t readPosition  = start + replace;
+    offset_t writePosition = start + data.size();
     memmove(d->data.data() + writePosition, d->data.data() + readPosition, length() - sizeDiff - readPosition);
   }
   seek(start);
   writeBlock(data);
 }
 
-void ByteVectorStream::removeBlock(unsigned long start, unsigned long length)
+void ByteVectorStream::removeBlock(offset_t start, unsigned long length)
 {
-  unsigned long readPosition = start + length;
-  unsigned long writePosition = start;
-  if(readPosition < static_cast<unsigned long>(ByteVectorStream::length())) {
-    unsigned long bytesToMove = ByteVectorStream::length() - readPosition;
+  offset_t readPosition = start + length;
+  offset_t writePosition = start;
+  if(readPosition < ByteVectorStream::length()) {
+    offset_t bytesToMove = ByteVectorStream::length() - readPosition;
     memmove(d->data.data() + writePosition, d->data.data() + readPosition, bytesToMove);
     writePosition += bytesToMove;
   }
@@ -127,7 +127,7 @@ bool ByteVectorStream::isOpen() const
   return true;
 }
 
-void ByteVectorStream::seek(long offset, Position p)
+void ByteVectorStream::seek(offset_t offset, Position p)
 {
   switch(p) {
   case Beginning:
@@ -146,17 +146,17 @@ void ByteVectorStream::clear()
 {
 }
 
-long ByteVectorStream::tell() const
+offset_t ByteVectorStream::tell() const
 {
   return d->position;
 }
 
-long ByteVectorStream::length()
+offset_t ByteVectorStream::length()
 {
   return d->data.size();
 }
 
-void ByteVectorStream::truncate(long length)
+void ByteVectorStream::truncate(offset_t length)
 {
   d->data.resize(length);
 }
diff --git a/taglib/toolkit/tbytevectorstream.h b/taglib/toolkit/tbytevectorstream.h
index 5aa8fcfd..8c2f4fa4 100644
--- a/taglib/toolkit/tbytevectorstream.h
+++ b/taglib/toolkit/tbytevectorstream.h
@@ -81,7 +81,7 @@ namespace TagLib {
      * \note This method is slow since it requires rewriting all of the file
      * after the insertion point.
      */
-    void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
+    void insert(const ByteVector &data, offset_t start = 0, unsigned long replace = 0);
 
     /*!
      * Removes a block of the file starting a \a start and continuing for
@@ -90,7 +90,7 @@ namespace TagLib {
      * \note This method is slow since it involves rewriting all of the file
      * after the removed portion.
      */
-    void removeBlock(unsigned long start = 0, unsigned long length = 0);
+    void removeBlock(offset_t start = 0, unsigned long length = 0);
 
     /*!
      * Returns true if the file is read only (or if the file can not be opened).
@@ -109,7 +109,7 @@ namespace TagLib {
      *
      * \see Position
      */
-    void seek(long offset, Position p = Beginning);
+    void seek(offset_t offset, Position p = Beginning);
 
     /*!
      * Reset the end-of-file and error flags on the file.
@@ -119,17 +119,17 @@ namespace TagLib {
     /*!
      * Returns the current offset within the file.
      */
-    long tell() const;
+    offset_t tell() const;
 
     /*!
      * Returns the length of the file.
      */
-    long length();
+    offset_t length();
 
     /*!
      * Truncates the file to a \a length.
      */
-    void truncate(long length);
+    void truncate(offset_t length);
 
     ByteVector *data();
 
diff --git a/taglib/toolkit/tfile.cpp b/taglib/toolkit/tfile.cpp
index 4f7bf6e7..9fe31e16 100644
--- a/taglib/toolkit/tfile.cpp
+++ b/taglib/toolkit/tfile.cpp
@@ -231,14 +231,14 @@ void File::writeBlock(const ByteVector &data)
   d->stream->writeBlock(data);
 }
 
-long File::find(const ByteVector &pattern, long fromOffset, const ByteVector &before)
+offset_t File::find(const ByteVector &pattern, offset_t fromOffset, const ByteVector &before)
 {
   if(!d->stream || pattern.size() > bufferSize())
       return -1;
 
   // The position in the file that the current buffer starts at.
 
-  long bufferOffset = fromOffset;
+  offset_t bufferOffset = fromOffset;
   ByteVector buffer;
 
   // These variables are used to keep track of a partial match that happens at
@@ -250,7 +250,7 @@ long File::find(const ByteVector &pattern, long fromOffset, const ByteVector &be
   // Save the location of the current read pointer.  We will restore the
   // position using seek() before all returns.
 
-  long originalPosition = tell();
+  offset_t originalPosition = tell();
 
   // Start the search at the offset.
 
@@ -327,7 +327,7 @@ long File::find(const ByteVector &pattern, long fromOffset, const ByteVector &be
 }
 
 
-long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &before)
+offset_t File::rfind(const ByteVector &pattern, offset_t fromOffset, const ByteVector &before)
 {
   if(!d->stream || pattern.size() > bufferSize())
       return -1;
@@ -347,15 +347,15 @@ long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &b
   // Save the location of the current read pointer.  We will restore the
   // position using seek() before all returns.
 
-  long originalPosition = tell();
+  offset_t originalPosition = tell();
 
   // Start the search at the offset.
 
   if(fromOffset == 0)
     fromOffset = length();
 
-  long bufferLength = bufferSize();
-  long bufferOffset = fromOffset + pattern.size();
+  offset_t bufferLength = bufferSize();
+  offset_t bufferOffset = fromOffset + pattern.size();
 
   // See the notes in find() for an explanation of this algorithm.
 
@@ -401,12 +401,12 @@ long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &b
   return -1;
 }
 
-void File::insert(const ByteVector &data, unsigned long start, unsigned long replace)
+void File::insert(const ByteVector &data, offset_t start, unsigned long replace)
 {
   d->stream->insert(data, start, replace);
 }
 
-void File::removeBlock(unsigned long start, unsigned long length)
+void File::removeBlock(offset_t start, unsigned long length)
 {
   d->stream->removeBlock(start, length);
 }
@@ -426,12 +426,12 @@ bool File::isValid() const
   return isOpen() && d->valid;
 }
 
-void File::seek(long offset, Position p)
+void File::seek(offset_t offset, Position p)
 {
   d->stream->seek(offset, static_cast<IOStream::Position>(p));
 }
 
-void File::truncate(long length)
+void File::truncate(offset_t length)
 {
   d->stream->truncate(length);
 }
@@ -441,12 +441,12 @@ void File::clear()
   d->stream->clear();
 }
 
-long File::tell() const
+offset_t File::tell() const
 {
   return d->stream->tell();
 }
 
-long File::length()
+offset_t File::length()
 {
   return d->stream->length();
 }
diff --git a/taglib/toolkit/tfile.h b/taglib/toolkit/tfile.h
index bb8c2b30..c024c4e8 100644
--- a/taglib/toolkit/tfile.h
+++ b/taglib/toolkit/tfile.h
@@ -180,8 +180,8 @@ namespace TagLib {
      * \note This has the practical limitation that \a pattern can not be longer
      * than the buffer size used by readBlock().  Currently this is 1024 bytes.
      */
-    long find(const ByteVector &pattern,
-              long fromOffset = 0,
+    offset_t find(const ByteVector &pattern,
+              offset_t fromOffset = 0,
               const ByteVector &before = ByteVector());
 
     /*!
@@ -196,8 +196,8 @@ namespace TagLib {
      * \note This has the practical limitation that \a pattern can not be longer
      * than the buffer size used by readBlock().  Currently this is 1024 bytes.
      */
-    long rfind(const ByteVector &pattern,
-               long fromOffset = 0,
+    offset_t rfind(const ByteVector &pattern,
+               offset_t fromOffset = 0,
                const ByteVector &before = ByteVector());
 
     /*!
@@ -207,7 +207,7 @@ namespace TagLib {
      * \note This method is slow since it requires rewriting all of the file
      * after the insertion point.
      */
-    void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
+    void insert(const ByteVector &data, offset_t start = 0, unsigned long replace = 0);
 
     /*!
      * Removes a block of the file starting a \a start and continuing for
@@ -216,7 +216,7 @@ namespace TagLib {
      * \note This method is slow since it involves rewriting all of the file
      * after the removed portion.
      */
-    void removeBlock(unsigned long start = 0, unsigned long length = 0);
+    void removeBlock(offset_t start = 0, unsigned long length = 0);
 
     /*!
      * Returns true if the file is read only (or if the file can not be opened).
@@ -240,7 +240,7 @@ namespace TagLib {
      *
      * \see Position
      */
-    void seek(long offset, Position p = Beginning);
+    void seek(offset_t offset, Position p = Beginning);
 
     /*!
      * Reset the end-of-file and error flags on the file.
@@ -250,12 +250,12 @@ namespace TagLib {
     /*!
      * Returns the current offset within the file.
      */
-    long tell() const;
+    offset_t tell() const;
 
     /*!
      * Returns the length of the file.
      */
-    long length();
+    offset_t length();
 
     /*!
      * Returns true if \a file can be opened for reading.  If the file does not
@@ -303,7 +303,7 @@ namespace TagLib {
     /*!
      * Truncates the file to a \a length.
      */
-    void truncate(long length);
+    void truncate(offset_t length);
 
     /*!
      * Returns the buffer size that is used for internal buffering.
diff --git a/taglib/toolkit/tfilestream.cpp b/taglib/toolkit/tfilestream.cpp
index 989e1d23..85a859f9 100644
--- a/taglib/toolkit/tfilestream.cpp
+++ b/taglib/toolkit/tfilestream.cpp
@@ -236,7 +236,7 @@ void FileStream::writeBlock(const ByteVector &data)
   writeFile(d->file, data);
 }
 
-void FileStream::insert(const ByteVector &data, unsigned long start, unsigned long replace)
+void FileStream::insert(const ByteVector &data, offset_t start, unsigned long replace)
 {
   if(!isOpen()) {
     debug("FileStream::insert() -- invalid file.");
@@ -270,15 +270,15 @@ void FileStream::insert(const ByteVector &data, unsigned long start, unsigned lo
   // the *difference* in the tag sizes.  We want to avoid overwriting parts
   // that aren't yet in memory, so this is necessary.
 
-  unsigned long bufferLength = bufferSize();
+  size_t bufferLength = bufferSize();
 
   while(data.size() - replace > bufferLength)
     bufferLength += bufferSize();
 
   // Set where to start the reading and writing.
 
-  long readPosition = start + replace;
-  long writePosition = start;
+  offset_t readPosition = start + replace;
+  offset_t writePosition = start;
 
   ByteVector buffer = data;
   ByteVector aboutToOverwrite(static_cast<unsigned int>(bufferLength));
@@ -317,7 +317,7 @@ void FileStream::insert(const ByteVector &data, unsigned long start, unsigned lo
   }
 }
 
-void FileStream::removeBlock(unsigned long start, unsigned long length)
+void FileStream::removeBlock(offset_t start, unsigned long length)
 {
   if(!isOpen()) {
     debug("FileStream::removeBlock() -- invalid file.");
@@ -326,8 +326,8 @@ void FileStream::removeBlock(unsigned long start, unsigned long length)
 
   unsigned long bufferLength = bufferSize();
 
-  long readPosition = start + length;
-  long writePosition = start;
+  offset_t readPosition = start + length;
+  offset_t writePosition = start;
 
   ByteVector buffer(static_cast<unsigned int>(bufferLength));
 
@@ -363,7 +363,7 @@ bool FileStream::isOpen() const
   return (d->file != InvalidFileHandle);
 }
 
-void FileStream::seek(long offset, Position p)
+void FileStream::seek(offset_t offset, Position p)
 {
   if(!isOpen()) {
     debug("FileStream::seek() -- invalid file.");
@@ -420,16 +420,15 @@ void FileStream::clear()
 #endif
 }
 
-long FileStream::tell() const
+offset_t FileStream::tell() const
 {
 #ifdef _WIN32
 
   const LARGE_INTEGER zero = {};
   LARGE_INTEGER position;
 
-  if(SetFilePointerEx(d->file, zero, &position, FILE_CURRENT) &&
-     position.QuadPart <= LONG_MAX) {
-    return static_cast<long>(position.QuadPart);
+  if(SetFilePointerEx(d->file, zero, &position, FILE_CURRENT)) {
+    return position.QuadPart;
   }
   else {
     debug("FileStream::tell() -- Failed to get the file pointer.");
@@ -443,7 +442,7 @@ long FileStream::tell() const
 #endif
 }
 
-long FileStream::length()
+offset_t FileStream::length()
 {
   if(!isOpen()) {
     debug("FileStream::length() -- invalid file.");
@@ -454,8 +453,8 @@ long FileStream::length()
 
   LARGE_INTEGER fileSize;
 
-  if(GetFileSizeEx(d->file, &fileSize) && fileSize.QuadPart <= LONG_MAX) {
-    return static_cast<long>(fileSize.QuadPart);
+  if(GetFileSizeEx(d->file, &fileSize)) {
+    return fileSize.QuadPart;
   }
   else {
     debug("FileStream::length() -- Failed to get the file size.");
@@ -464,10 +463,10 @@ long FileStream::length()
 
 #else
 
-  const long curpos = tell();
+  const offset_t curpos = tell();
 
   seek(0, End);
-  const long endpos = tell();
+  const offset_t endpos = tell();
 
   seek(curpos, Beginning);
 
@@ -480,11 +479,11 @@ long FileStream::length()
 // protected members
 ////////////////////////////////////////////////////////////////////////////////
 
-void FileStream::truncate(long length)
+void FileStream::truncate(offset_t length)
 {
 #ifdef _WIN32
 
-  const long currentPos = tell();
+  const offset_t currentPos = tell();
 
   seek(length);
 
diff --git a/taglib/toolkit/tfilestream.h b/taglib/toolkit/tfilestream.h
index dd3b8652..6fee9f05 100644
--- a/taglib/toolkit/tfilestream.h
+++ b/taglib/toolkit/tfilestream.h
@@ -92,7 +92,7 @@ namespace TagLib {
      * \note This method is slow since it requires rewriting all of the file
      * after the insertion point.
      */
-    void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
+    void insert(const ByteVector &data, offset_t start = 0, unsigned long replace = 0);
 
     /*!
      * Removes a block of the file starting a \a start and continuing for
@@ -101,7 +101,7 @@ namespace TagLib {
      * \note This method is slow since it involves rewriting all of the file
      * after the removed portion.
      */
-    void removeBlock(unsigned long start = 0, unsigned long length = 0);
+    void removeBlock(offset_t start = 0, unsigned long length = 0);
 
     /*!
      * Returns true if the file is read only (or if the file can not be opened).
@@ -120,7 +120,7 @@ namespace TagLib {
      *
      * \see Position
      */
-    void seek(long offset, Position p = Beginning);
+    void seek(offset_t offset, Position p = Beginning);
 
     /*!
      * Reset the end-of-file and error flags on the file.
@@ -130,17 +130,17 @@ namespace TagLib {
     /*!
      * Returns the current offset within the file.
      */
-    long tell() const;
+    offset_t tell() const;
 
     /*!
      * Returns the length of the file.
      */
-    long length();
+    offset_t length();
 
     /*!
      * Truncates the file to a \a length.
      */
-    void truncate(long length);
+    void truncate(offset_t length);
 
   protected:
 
diff --git a/taglib/toolkit/tiostream.h b/taglib/toolkit/tiostream.h
index 1972d935..e089aef8 100644
--- a/taglib/toolkit/tiostream.h
+++ b/taglib/toolkit/tiostream.h
@@ -110,7 +110,7 @@ namespace TagLib {
      * after the insertion point.
      */
     virtual void insert(const ByteVector &data,
-                        unsigned long start = 0, unsigned long replace = 0) = 0;
+                        offset_t start = 0, unsigned long replace = 0) = 0;
 
     /*!
      * Removes a block of the file starting a \a start and continuing for
@@ -119,7 +119,7 @@ namespace TagLib {
      * \note This method is slow since it involves rewriting all of the file
      * after the removed portion.
      */
-    virtual void removeBlock(unsigned long start = 0, unsigned long length = 0) = 0;
+    virtual void removeBlock(offset_t start = 0, unsigned long length = 0) = 0;
 
     /*!
      * Returns true if the file is read only (or if the file can not be opened).
@@ -138,7 +138,7 @@ namespace TagLib {
      *
      * \see Position
      */
-    virtual void seek(long offset, Position p = Beginning) = 0;
+    virtual void seek(offset_t offset, Position p = Beginning) = 0;
 
     /*!
      * Reset the end-of-stream and error flags on the stream.
@@ -148,17 +148,17 @@ namespace TagLib {
     /*!
      * Returns the current offset within the stream.
      */
-    virtual long tell() const = 0;
+    virtual offset_t tell() const = 0;
 
     /*!
      * Returns the length of the stream.
      */
-    virtual long length() = 0;
+    virtual offset_t length() = 0;
 
     /*!
      * Truncates the stream to a \a length.
      */
-    virtual void truncate(long length) = 0;
+    virtual void truncate(offset_t length) = 0;
 
   private:
     IOStream(const IOStream &);
diff --git a/taglib/trueaudio/trueaudiofile.cpp b/taglib/trueaudio/trueaudiofile.cpp
index e1dd7b99..77b835ab 100644
--- a/taglib/trueaudio/trueaudiofile.cpp
+++ b/taglib/trueaudio/trueaudiofile.cpp
@@ -63,10 +63,10 @@ public:
   }
 
   const ID3v2::FrameFactory *ID3v2FrameFactory;
-  long ID3v2Location;
+  offset_t ID3v2Location;
   long ID3v2OriginalSize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   TagUnion tag;
 
@@ -290,7 +290,7 @@ void TrueAudio::File::read(bool readProperties)
 
   if(readProperties) {
 
-    long streamLength;
+    offset_t streamLength;
 
     if(d->ID3v1Location >= 0)
       streamLength = d->ID3v1Location;
diff --git a/taglib/trueaudio/trueaudioproperties.cpp b/taglib/trueaudio/trueaudioproperties.cpp
index 0aab2419..3a403848 100644
--- a/taglib/trueaudio/trueaudioproperties.cpp
+++ b/taglib/trueaudio/trueaudioproperties.cpp
@@ -61,7 +61,7 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-TrueAudio::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) :
+TrueAudio::Properties::Properties(const ByteVector &data, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
@@ -122,7 +122,7 @@ int TrueAudio::Properties::ttaVersion() const
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void TrueAudio::Properties::read(const ByteVector &data, long streamLength)
+void TrueAudio::Properties::read(const ByteVector &data, offset_t streamLength)
 {
   if(data.size() < 4) {
     debug("TrueAudio::Properties::read() -- data is too short.");
diff --git a/taglib/trueaudio/trueaudioproperties.h b/taglib/trueaudio/trueaudioproperties.h
index 490fea8e..9a72a7e3 100644
--- a/taglib/trueaudio/trueaudioproperties.h
+++ b/taglib/trueaudio/trueaudioproperties.h
@@ -52,7 +52,7 @@ namespace TagLib {
        * Create an instance of TrueAudio::Properties with the data read from the
        * ByteVector \a data.
        */
-      Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
+      Properties(const ByteVector &data, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Destroys this TrueAudio::Properties instance.
@@ -120,7 +120,7 @@ namespace TagLib {
       Properties(const Properties &);
       Properties &operator=(const Properties &);
 
-      void read(const ByteVector &data, long streamLength);
+      void read(const ByteVector &data, offset_t streamLength);
 
       class PropertiesPrivate;
       PropertiesPrivate *d;
diff --git a/taglib/wavpack/wavpackfile.cpp b/taglib/wavpack/wavpackfile.cpp
index 291e9b88..bdca24ca 100644
--- a/taglib/wavpack/wavpackfile.cpp
+++ b/taglib/wavpack/wavpackfile.cpp
@@ -61,10 +61,10 @@ public:
     delete properties;
   }
 
-  long APELocation;
+  offset_t APELocation;
   long APESize;
 
-  long ID3v1Location;
+  offset_t ID3v1Location;
 
   TagUnion tag;
 
@@ -270,7 +270,7 @@ void WavPack::File::read(bool readProperties)
 
   if(readProperties) {
 
-    long streamLength;
+    offset_t streamLength;
 
     if(d->APELocation >= 0)
       streamLength = d->APELocation;
diff --git a/taglib/wavpack/wavpackproperties.cpp b/taglib/wavpack/wavpackproperties.cpp
index 1dd2a054..cc65f2d0 100644
--- a/taglib/wavpack/wavpackproperties.cpp
+++ b/taglib/wavpack/wavpackproperties.cpp
@@ -66,14 +66,14 @@ public:
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-WavPack::Properties::Properties(const ByteVector &, long, ReadStyle style) :
+WavPack::Properties::Properties(const ByteVector &, offset_t, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
   debug("WavPack::Properties::Properties() -- This constructor is no longer used.");
 }
 
-WavPack::Properties::Properties(File *file, long streamLength, ReadStyle style) :
+WavPack::Properties::Properties(File *file, offset_t streamLength, ReadStyle style) :
   AudioProperties(style),
   d(new PropertiesPrivate())
 {
@@ -257,9 +257,9 @@ namespace
 
 }  // namespace
 
-void WavPack::Properties::read(File *file, long streamLength)
+void WavPack::Properties::read(File *file, offset_t streamLength)
 {
-  long offset = 0;
+  offset_t offset = 0;
 
   while(true) {
     file->seek(offset);
@@ -339,9 +339,9 @@ void WavPack::Properties::read(File *file, long streamLength)
   }
 }
 
-unsigned int WavPack::Properties::seekFinalIndex(File *file, long streamLength)
+unsigned int WavPack::Properties::seekFinalIndex(File *file, offset_t streamLength)
 {
-  long offset = streamLength;
+  offset_t offset = streamLength;
 
   while (offset >= 32) {
     offset = file->rfind("wvpk", offset - 4);
diff --git a/taglib/wavpack/wavpackproperties.h b/taglib/wavpack/wavpackproperties.h
index e1a481df..8360f9c9 100644
--- a/taglib/wavpack/wavpackproperties.h
+++ b/taglib/wavpack/wavpackproperties.h
@@ -58,13 +58,13 @@ namespace TagLib {
        * \deprecated This constructor will be dropped in favor of the one below
        * in a future version.
        */
-      TAGLIB_DEPRECATED Properties(const ByteVector &data, long streamLength,
+      TAGLIB_DEPRECATED Properties(const ByteVector &data, offset_t streamLength,
                                    ReadStyle style = Average);
 
       /*!
        * Create an instance of WavPack::Properties.
        */
-      Properties(File *file, long streamLength, ReadStyle style = Average);
+      Properties(File *file, offset_t streamLength, ReadStyle style = Average);
 
       /*!
        * Destroys this WavPack::Properties instance.
@@ -137,8 +137,8 @@ namespace TagLib {
       Properties(const Properties &);
       Properties &operator=(const Properties &);
 
-      void read(File *file, long streamLength);
-      unsigned int seekFinalIndex(File *file, long streamLength);
+      void read(File *file, offset_t streamLength);
+      unsigned int seekFinalIndex(File *file, offset_t streamLength);
 
       class PropertiesPrivate;
       PropertiesPrivate *d;
diff --git a/taglib/xm/xmfile.cpp b/taglib/xm/xmfile.cpp
index 61a554c8..e5cd6156 100644
--- a/taglib/xm/xmfile.cpp
+++ b/taglib/xm/xmfile.cpp
@@ -591,7 +591,7 @@ void XM::File::read(bool)
     unsigned int count = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
     READ_ASSERT(count == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
 
-    long offset = 0;
+    offset_t offset = 0;
     if(sampleCount > 0) {
       unsigned long sampleHeaderSize = 0;
       sumSampleCount += sampleCount;
diff --git a/tests/plainfile.h b/tests/plainfile.h
index 6147b56b..b42475f9 100644
--- a/tests/plainfile.h
+++ b/tests/plainfile.h
@@ -41,7 +41,7 @@ public:
 
   ByteVector readAll() {
     seek(0, End);
-    long end = tell();
+    offset_t end = tell();
     seek(0);
     return readBlock(end);
   }
diff --git a/tests/test_aiff.cpp b/tests/test_aiff.cpp
index 0337729f..03cc545e 100644
--- a/tests/test_aiff.cpp
+++ b/tests/test_aiff.cpp
@@ -141,8 +141,8 @@ public:
     CPPUNIT_ASSERT_EQUAL(String("Title1"), f.tag()->title());
 
     f.save();
-    CPPUNIT_ASSERT_EQUAL(7030L, f.length());
-    CPPUNIT_ASSERT_EQUAL(-1L, f.find("Title2"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(7030), f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(-1), f.find("Title2"));
   }
 
   void testFuzzedFile1()
diff --git a/tests/test_asf.cpp b/tests/test_asf.cpp
index 293abe30..ca13e16d 100644
--- a/tests/test_asf.cpp
+++ b/tests/test_asf.cpp
@@ -389,10 +389,10 @@ public:
       ASF::File f(copy.fileName().c_str());
       f.tag()->setTitle(longText(128 * 1024));
       f.save();
-      CPPUNIT_ASSERT_EQUAL(297578L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(297578), f.length());
       f.tag()->setTitle(longText(16 * 1024));
       f.save();
-      CPPUNIT_ASSERT_EQUAL(68202L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(68202), f.length());
     }
   }
 
diff --git a/tests/test_bytevectorstream.cpp b/tests/test_bytevectorstream.cpp
index f8308c6d..b13ca61b 100644
--- a/tests/test_bytevectorstream.cpp
+++ b/tests/test_bytevectorstream.cpp
@@ -117,7 +117,7 @@ public:
   {
     ByteVector v("abcdefghijklmnopqrstuvwxyz");
     ByteVectorStream stream(v);
-    CPPUNIT_ASSERT_EQUAL(26L, stream.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(26), stream.length());
 
     stream.seek(-4, IOStream::End);
     CPPUNIT_ASSERT_EQUAL(ByteVector("w"), stream.readBlock(1));
diff --git a/tests/test_file.cpp b/tests/test_file.cpp
index ef8c1b10..a30ae4e2 100644
--- a/tests/test_file.cpp
+++ b/tests/test_file.cpp
@@ -53,19 +53,19 @@ public:
     }
     {
       PlainFile file(name.c_str());
-      CPPUNIT_ASSERT_EQUAL(10l, file.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(10), file.length());
 
-      CPPUNIT_ASSERT_EQUAL(2l, file.find(ByteVector("23", 2)));
-      CPPUNIT_ASSERT_EQUAL(2l, file.find(ByteVector("23", 2), 2));
-      CPPUNIT_ASSERT_EQUAL(7l, file.find(ByteVector("23", 2), 3));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2), file.find(ByteVector("23", 2)));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2), file.find(ByteVector("23", 2), 2));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(7), file.find(ByteVector("23", 2), 3));
 
       file.seek(0);
       const ByteVector v = file.readBlock(file.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)10, v.size());
 
-      CPPUNIT_ASSERT_EQUAL((long)v.find("23"),    file.find("23"));
-      CPPUNIT_ASSERT_EQUAL((long)v.find("23", 2), file.find("23", 2));
-      CPPUNIT_ASSERT_EQUAL((long)v.find("23", 3), file.find("23", 3));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.find("23")),    file.find("23"));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.find("23", 2)), file.find("23", 2));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.find("23", 3)), file.find("23", 3));
     }
   }
 
@@ -81,19 +81,19 @@ public:
     }
     {
       PlainFile file(name.c_str());
-      CPPUNIT_ASSERT_EQUAL(10l, file.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(10), file.length());
 
-      CPPUNIT_ASSERT_EQUAL(7l, file.rfind(ByteVector("23", 2)));
-      CPPUNIT_ASSERT_EQUAL(7l, file.rfind(ByteVector("23", 2), 7));
-      CPPUNIT_ASSERT_EQUAL(2l, file.rfind(ByteVector("23", 2), 6));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(7), file.rfind(ByteVector("23", 2)));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(7), file.rfind(ByteVector("23", 2), 7));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2), file.rfind(ByteVector("23", 2), 6));
 
       file.seek(0);
       const ByteVector v = file.readBlock(file.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)10, v.size());
 
-      CPPUNIT_ASSERT_EQUAL((long)v.rfind("23"),    file.rfind("23"));
-      CPPUNIT_ASSERT_EQUAL((long)v.rfind("23", 7), file.rfind("23", 7));
-      CPPUNIT_ASSERT_EQUAL((long)v.rfind("23", 6), file.rfind("23", 6));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.rfind("23")),    file.rfind("23"));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.rfind("23", 7)), file.rfind("23", 7));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(v.rfind("23", 6)), file.rfind("23", 6));
     }
   }
 
@@ -103,22 +103,22 @@ public:
     std::string name = copy.fileName();
 
     PlainFile f(name.c_str());
-    CPPUNIT_ASSERT_EQUAL((long)0, f.tell());
-    CPPUNIT_ASSERT_EQUAL((long)4328, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0), f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4328), f.length());
 
     f.seek(100, File::Beginning);
-    CPPUNIT_ASSERT_EQUAL((long)100, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(100), f.tell());
     f.seek(100, File::Current);
-    CPPUNIT_ASSERT_EQUAL((long)200, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(200), f.tell());
     f.seek(-300, File::Current);
-    CPPUNIT_ASSERT_EQUAL((long)200, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(200), f.tell());
 
     f.seek(-100, File::End);
-    CPPUNIT_ASSERT_EQUAL((long)4228, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4228), f.tell());
     f.seek(-100, File::Current);
-    CPPUNIT_ASSERT_EQUAL((long)4128, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4128), f.tell());
     f.seek(300, File::Current);
-    CPPUNIT_ASSERT_EQUAL((long)4428, f.tell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4428), f.tell());
   }
 
   void testTruncate()
@@ -128,18 +128,17 @@ public:
 
     {
       PlainFile f(name.c_str());
-      CPPUNIT_ASSERT_EQUAL(4328L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4328), f.length());
 
       f.truncate(2000);
-      CPPUNIT_ASSERT_EQUAL(2000L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2000), f.length());
     }
     {
       PlainFile f(name.c_str());
-      CPPUNIT_ASSERT_EQUAL(2000L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2000), f.length());
     }
   }
 
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestFile);
-
diff --git a/tests/test_flac.cpp b/tests/test_flac.cpp
index c83f1e90..d5352b3c 100644
--- a/tests/test_flac.cpp
+++ b/tests/test_flac.cpp
@@ -91,8 +91,8 @@ public:
     {
       FLAC::File f(newname.c_str());
       CPPUNIT_ASSERT_EQUAL(String("The Artist"), f.tag()->artist());
-      CPPUNIT_ASSERT_EQUAL(69L, f.find("Artist"));
-      CPPUNIT_ASSERT_EQUAL(-1L, f.find("Artist", 70));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(69), f.find("Artist"));
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(-1), f.find("Artist", 70));
     }
   }
 
@@ -253,9 +253,9 @@ public:
     FLAC::File f(copy.fileName().c_str());
     f.ID3v2Tag(true)->setTitle("0123456789");
     f.save();
-    CPPUNIT_ASSERT_EQUAL(5735L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(5735), f.length());
     f.save();
-    CPPUNIT_ASSERT_EQUAL(5735L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(5735), f.length());
     CPPUNIT_ASSERT(f.find("fLaC") >= 0);
   }
 
@@ -266,9 +266,9 @@ public:
     FLAC::File f(copy.fileName().c_str());
     f.xiphComment()->setTitle(longText(8 * 1024));
     f.save();
-    CPPUNIT_ASSERT_EQUAL(12862L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(12862), f.length());
     f.save();
-    CPPUNIT_ASSERT_EQUAL(12862L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(12862), f.length());
   }
 
   void testSaveMultipleValues()
@@ -449,7 +449,7 @@ public:
     {
       FLAC::File f(copy.fileName().c_str());
       CPPUNIT_ASSERT(!f.hasID3v1Tag());
-      CPPUNIT_ASSERT_EQUAL((long)4692, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4692), f.length());
 
       f.seek(0x0100);
       audioStream = f.readBlock(4436);
@@ -457,7 +457,7 @@ public:
       f.ID3v1Tag(true)->setTitle("01234 56789 ABCDE FGHIJ");
       f.save();
       CPPUNIT_ASSERT(f.hasID3v1Tag());
-      CPPUNIT_ASSERT_EQUAL((long)4820, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4820), f.length());
 
       f.seek(0x0100);
       CPPUNIT_ASSERT_EQUAL(audioStream, f.readBlock(4436));
diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp
index 36ddc436..9de2596d 100644
--- a/tests/test_id3v2.cpp
+++ b/tests/test_id3v2.cpp
@@ -1553,14 +1553,14 @@ public:
     {
       MPEG::File f(newname.c_str());
       CPPUNIT_ASSERT(f.hasID3v2Tag());
-      CPPUNIT_ASSERT_EQUAL(74789L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(74789), f.length());
       f.ID3v2Tag()->setTitle("ABCDEFGHIJ");
       f.save(MPEG::File::ID3v2, File::StripOthers);
     }
     {
       MPEG::File f(newname.c_str());
       CPPUNIT_ASSERT(f.hasID3v2Tag());
-      CPPUNIT_ASSERT_EQUAL(9263L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(9263), f.length());
     }
   }
 
@@ -1618,7 +1618,7 @@ public:
     {
       MPEG::File f(copy.fileName().c_str());
       CPPUNIT_ASSERT(f.hasID3v2Tag());
-      CPPUNIT_ASSERT_EQUAL((long)3594, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(3594), f.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)1505, f.ID3v2Tag()->header()->completeTagSize());
       CPPUNIT_ASSERT_EQUAL(String("Artist A"), f.ID3v2Tag()->artist());
       CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
@@ -1689,4 +1689,3 @@ public:
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);
-
diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp
index 2ead2bab..5c6a9cbb 100644
--- a/tests/test_mp4.cpp
+++ b/tests/test_mp4.cpp
@@ -298,7 +298,7 @@ public:
 
       MP4::Atoms atoms(&f);
       MP4::Atom *moov = atoms.atoms[0];
-      CPPUNIT_ASSERT_EQUAL(long(77), moov->length);
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(77), moov->length);
 
       f.tag()->setItem("pgap", true);
       f.save();
@@ -311,7 +311,7 @@ public:
       MP4::Atoms atoms(&f);
       MP4::Atom *moov = atoms.atoms[0];
       // original size + 'pgap' size + padding
-      CPPUNIT_ASSERT_EQUAL(long(77 + 25 + 974), moov->length);
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(77 + 25 + 974), moov->length);
     }
   }
 
@@ -589,8 +589,8 @@ public:
     f.tag()->setTitle("0123456789");
     f.save();
     f.save();
-    CPPUNIT_ASSERT_EQUAL(2862L, f.find("0123456789"));
-    CPPUNIT_ASSERT_EQUAL(-1L, f.find("0123456789", 2863));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2862), f.find("0123456789"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(-1), f.find("0123456789", 2863));
   }
 
   void testWithZeroLengthAtom()
diff --git a/tests/test_mpeg.cpp b/tests/test_mpeg.cpp
index 03eb702b..bd3e316d 100644
--- a/tests/test_mpeg.cpp
+++ b/tests/test_mpeg.cpp
@@ -119,10 +119,10 @@ public:
     CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
     CPPUNIT_ASSERT(!f.audioProperties()->xingHeader());
 
-    const long last = f.lastFrameOffset();
+    offset_t last = f.lastFrameOffset();
     const MPEG::Header lastHeader(&f, last, false);
 
-    CPPUNIT_ASSERT_EQUAL(28213L, last);
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(28213), last);
     CPPUNIT_ASSERT_EQUAL(209, lastHeader.frameLength());
   }
 
@@ -258,20 +258,20 @@ public:
     {
       MPEG::File f(TEST_FILE_PATH_C("ape.mp3"));
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL((long)0x0000, f.firstFrameOffset());
-      CPPUNIT_ASSERT_EQUAL((long)0x1FD6, f.lastFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x0000), f.firstFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x1FD6), f.lastFrameOffset());
     }
     {
       MPEG::File f(TEST_FILE_PATH_C("ape-id3v1.mp3"));
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL((long)0x0000, f.firstFrameOffset());
-      CPPUNIT_ASSERT_EQUAL((long)0x1FD6, f.lastFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x0000), f.firstFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x1FD6), f.lastFrameOffset());
     }
     {
       MPEG::File f(TEST_FILE_PATH_C("ape-id3v2.mp3"));
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL((long)0x041A, f.firstFrameOffset());
-      CPPUNIT_ASSERT_EQUAL((long)0x23F0, f.lastFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x041A), f.firstFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(0x23F0), f.lastFrameOffset());
     }
   }
 
@@ -418,7 +418,7 @@ public:
       f.save();
       f.ID3v2Tag(true)->setTitle(std::string(4096, 'X').c_str());
       f.save();
-      CPPUNIT_ASSERT_EQUAL(5141L, f.firstFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(5141), f.firstFrameOffset());
     }
   }
 
@@ -430,7 +430,7 @@ public:
     f.ID3v2Tag(true)->setTitle("0123456789");
     f.save();
     f.save();
-    CPPUNIT_ASSERT_EQUAL(-1L, f.find("ID3", 3));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(-1), f.find("ID3", 3));
   }
 
   void testRepeatedSave3()
@@ -524,8 +524,8 @@ public:
       MPEG::File f(copy.fileName().c_str());
       CPPUNIT_ASSERT(f.isValid());
       CPPUNIT_ASSERT(f.hasID3v2Tag());
-      CPPUNIT_ASSERT_EQUAL(2255L, f.firstFrameOffset());
-      CPPUNIT_ASSERT_EQUAL(6015L, f.lastFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2255), f.firstFrameOffset());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(6015), f.lastFrameOffset());
       CPPUNIT_ASSERT_EQUAL(String("Title A"), f.ID3v2Tag()->title());
       f.ID3v2Tag()->setTitle("Title B");
       f.save();
diff --git a/tests/test_ogg.cpp b/tests/test_ogg.cpp
index 0008429e..3c5e4ac6 100644
--- a/tests/test_ogg.cpp
+++ b/tests/test_ogg.cpp
@@ -84,7 +84,7 @@ public:
     {
       Vorbis::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(136383L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(136383), f.length());
       CPPUNIT_ASSERT_EQUAL(19, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(30U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(131127U, f.packet(1).size());
@@ -100,7 +100,7 @@ public:
     {
       Vorbis::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(4370L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4370), f.length());
       CPPUNIT_ASSERT_EQUAL(3, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(30U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(60U, f.packet(1).size());
diff --git a/tests/test_oggflac.cpp b/tests/test_oggflac.cpp
index 1d00d123..b8fde4a9 100644
--- a/tests/test_oggflac.cpp
+++ b/tests/test_oggflac.cpp
@@ -62,7 +62,7 @@ public:
       CPPUNIT_ASSERT_EQUAL(String("The Artist"), f.tag()->artist());
 
       f.seek(0, File::End);
-      CPPUNIT_ASSERT_EQUAL(9134L, f.tell());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(9134), f.tell());
     }
   }
 
@@ -87,7 +87,7 @@ public:
     {
       Ogg::FLAC::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(141141L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(141141), f.length());
       CPPUNIT_ASSERT_EQUAL(21, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(51U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(131126U, f.packet(1).size());
@@ -104,7 +104,7 @@ public:
     {
       Ogg::FLAC::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(9128L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(9128), f.length());
       CPPUNIT_ASSERT_EQUAL(5, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(51U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(59U, f.packet(1).size());
diff --git a/tests/test_opus.cpp b/tests/test_opus.cpp
index 9a49d239..d172e479 100644
--- a/tests/test_opus.cpp
+++ b/tests/test_opus.cpp
@@ -102,7 +102,7 @@ public:
     {
       Ogg::Opus::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(167534L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(167534), f.length());
       CPPUNIT_ASSERT_EQUAL(27, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(19U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(131380U, f.packet(1).size());
@@ -119,7 +119,7 @@ public:
     {
       Ogg::Opus::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(35521L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(35521), f.length());
       CPPUNIT_ASSERT_EQUAL(11, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(19U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(313U, f.packet(1).size());
diff --git a/tests/test_riff.cpp b/tests/test_riff.cpp
index f9a20dfb..0aeebde3 100644
--- a/tests/test_riff.cpp
+++ b/tests/test_riff.cpp
@@ -40,7 +40,7 @@ public:
   PublicRIFF(FileName file) : RIFF::File(file, BigEndian) {};
   unsigned int riffSize() { return RIFF::File::riffSize(); };
   unsigned int chunkCount() { return RIFF::File::chunkCount(); };
-  unsigned int chunkOffset(unsigned int i) { return RIFF::File::chunkOffset(i); };
+  offset_t chunkOffset(unsigned int i) { return RIFF::File::chunkOffset(i); };
   unsigned int chunkPadding(unsigned int i) { return RIFF::File::chunkPadding(i); };
   unsigned int chunkDataSize(unsigned int i) { return RIFF::File::chunkDataSize(i); };
   ByteVector chunkName(unsigned int i) { return RIFF::File::chunkName(i); };
@@ -78,7 +78,7 @@ public:
     {
       PublicRIFF f(filename.c_str());
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(0x1728 + 8), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(0x1728 + 8), f.chunkOffset(2));
 
       f.setChunkData("TEST", "foo");
     }
@@ -87,7 +87,7 @@ public:
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), f.chunkData(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(3), f.chunkDataSize(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(0x1728 + 8), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(0x1728 + 8), f.chunkOffset(2));
 
       f.setChunkData("SSND", "abcd");
 
@@ -120,18 +120,18 @@ public:
 
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(0xff0 + 8), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(0xff0 + 8), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL(long(4400), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4400), f.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4399 - 8), f.riffSize());
       f.setChunkData("TEST", "abcd");
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(3));
@@ -139,15 +139,15 @@ public:
     }
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(3));
-      CPPUNIT_ASSERT_EQUAL(long(4412), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4412), f.length());
     }
   }
 
@@ -158,18 +158,18 @@ public:
 
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(0xff0 + 8), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(0xff0 + 8), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL(long(4399), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4399), f.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4399 - 8), f.riffSize());
       f.setChunkData("TEST", "abcd");
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(3));
@@ -177,15 +177,15 @@ public:
     }
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(3));
-      CPPUNIT_ASSERT_EQUAL(long(4412), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4412), f.length());
     }
   }
 
@@ -196,18 +196,18 @@ public:
 
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(0xff0 + 8), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(0xff0 + 8), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(0), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL(long(4399), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4399), f.length());
       CPPUNIT_ASSERT_EQUAL((unsigned int)(4399 - 8), f.riffSize());
       f.setChunkData("TEST", "abc");
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(3), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(3));
@@ -215,15 +215,15 @@ public:
     }
     {
       PublicRIFF f(filename.c_str());
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4088), f.chunkOffset(2));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4088), f.chunkOffset(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(311), f.chunkDataSize(2));
       CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(2));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(2));
-      CPPUNIT_ASSERT_EQUAL((unsigned int)(4408), f.chunkOffset(3));
+      CPPUNIT_ASSERT_EQUAL((offset_t)(4408), f.chunkOffset(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(3), f.chunkDataSize(3));
       CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(3));
       CPPUNIT_ASSERT_EQUAL((unsigned int)(1), f.chunkPadding(3));
-      CPPUNIT_ASSERT_EQUAL(long(4412), f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(4412), f.length());
     }
   }
 
@@ -235,21 +235,21 @@ public:
     PublicRIFF f(filename.c_str());
 
     CPPUNIT_ASSERT_EQUAL(5928U, f.riffSize());
-    CPPUNIT_ASSERT_EQUAL(5936L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(5936), f.length());
     CPPUNIT_ASSERT_EQUAL(ByteVector("COMM"), f.chunkName(0));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x000C + 8), f.chunkOffset(0));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x000C + 8), f.chunkOffset(0));
     CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f.chunkName(1));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x0026 + 8), f.chunkOffset(1));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x0026 + 8), f.chunkOffset(1));
     CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.chunkName(2));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x1728 + 8), f.chunkOffset(2));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x1728 + 8), f.chunkOffset(2));
 
     const ByteVector data(0x400, ' ');
     f.setChunkData("SSND", data);
     CPPUNIT_ASSERT_EQUAL(1070U, f.riffSize());
-    CPPUNIT_ASSERT_EQUAL(1078L, f.length());
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x000C + 8), f.chunkOffset(0));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x0026 + 8), f.chunkOffset(1));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x042E + 8), f.chunkOffset(2));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(1078), f.length());
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x000C + 8), f.chunkOffset(0));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x0026 + 8), f.chunkOffset(1));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x042E + 8), f.chunkOffset(2));
 
     f.seek(f.chunkOffset(0) - 8);
     CPPUNIT_ASSERT_EQUAL(ByteVector("COMM"), f.readBlock(4));
@@ -260,10 +260,10 @@ public:
 
     f.setChunkData(0, data);
     CPPUNIT_ASSERT_EQUAL(2076U, f.riffSize());
-    CPPUNIT_ASSERT_EQUAL(2084L, f.length());
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x000C + 8), f.chunkOffset(0));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x0414 + 8), f.chunkOffset(1));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x081C + 8), f.chunkOffset(2));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(2084), f.length());
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x000C + 8), f.chunkOffset(0));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x0414 + 8), f.chunkOffset(1));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x081C + 8), f.chunkOffset(2));
 
     f.seek(f.chunkOffset(0) - 8);
     CPPUNIT_ASSERT_EQUAL(ByteVector("COMM"), f.readBlock(4));
@@ -274,9 +274,9 @@ public:
 
     f.removeChunk("SSND");
     CPPUNIT_ASSERT_EQUAL(1044U, f.riffSize());
-    CPPUNIT_ASSERT_EQUAL(1052L, f.length());
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x000C + 8), f.chunkOffset(0));
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x0414 + 8), f.chunkOffset(1));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(1052), f.length());
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x000C + 8), f.chunkOffset(0));
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x0414 + 8), f.chunkOffset(1));
 
     f.seek(f.chunkOffset(0) - 8);
     CPPUNIT_ASSERT_EQUAL(ByteVector("COMM"), f.readBlock(4));
@@ -285,8 +285,8 @@ public:
 
     f.removeChunk(0);
     CPPUNIT_ASSERT_EQUAL(12U, f.riffSize());
-    CPPUNIT_ASSERT_EQUAL(20L, f.length());
-    CPPUNIT_ASSERT_EQUAL((unsigned int)(0x000C + 8), f.chunkOffset(0));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(20), f.length());
+    CPPUNIT_ASSERT_EQUAL((offset_t)(0x000C + 8), f.chunkOffset(0));
 
     f.seek(f.chunkOffset(0) - 8);
     CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f.readBlock(4));
@@ -295,4 +295,3 @@ public:
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestRIFF);
-
diff --git a/tests/test_speex.cpp b/tests/test_speex.cpp
index 1f5bb754..c8268c21 100644
--- a/tests/test_speex.cpp
+++ b/tests/test_speex.cpp
@@ -67,7 +67,7 @@ public:
     {
       Ogg::Speex::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(156330L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(156330), f.length());
       CPPUNIT_ASSERT_EQUAL(23, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(80U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(131116U, f.packet(1).size());
@@ -84,7 +84,7 @@ public:
     {
       Ogg::Speex::File f(newname.c_str());
       CPPUNIT_ASSERT(f.isValid());
-      CPPUNIT_ASSERT_EQUAL(24317L, f.length());
+      CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(24317), f.length());
       CPPUNIT_ASSERT_EQUAL(7, f.lastPageHeader()->pageSequenceNumber());
       CPPUNIT_ASSERT_EQUAL(80U, f.packet(0).size());
       CPPUNIT_ASSERT_EQUAL(49U, f.packet(1).size());
diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp
index 61081393..55d71e0b 100644
--- a/tests/test_wav.cpp
+++ b/tests/test_wav.cpp
@@ -268,7 +268,7 @@ public:
     ScopedFileCopy copy("duplicate_tags", ".wav");
 
     RIFF::WAV::File f(copy.fileName().c_str());
-    CPPUNIT_ASSERT_EQUAL(17052L, f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(17052), f.length());
 
     // duplicate_tags.wav has duplicate ID3v2/INFO tags.
     // title() returns "Title2" if can't skip the second tag.
@@ -280,8 +280,8 @@ public:
     CPPUNIT_ASSERT_EQUAL(String("Title1"), f.InfoTag()->title());
 
     f.save();
-    CPPUNIT_ASSERT_EQUAL(15898L, f.length());
-    CPPUNIT_ASSERT_EQUAL(-1L, f.find("Title2"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(15898), f.length());
+    CPPUNIT_ASSERT_EQUAL(static_cast<offset_t>(-1), f.find("Title2"));
   }
 
   void testFuzzedFile1()
