From 0e3fcaece6bb567279f6422adfdfa046cb45aa4b Mon Sep 17 00:00:00 2001
From: "mcmullen%netscape.com" <mcmullen%netscape.com>
Date: Wed, 10 Mar 1999 21:02:58 +0000
Subject: [PATCH] Added GetModDate and GetFileSize. Fixed a crash with a strcmp
 of null.

---
 base/public/nsFileSpec.h           | 27 ++++++++++++++-
 base/src/mac/nsFileSpecMac.cpp     | 54 ++++++++++++++++++++++--------
 base/src/nsFileSpec.cpp            | 26 ++++++++------
 base/src/unix/nsFileSpecUnix.cpp   | 21 ++++++++++++
 base/src/windows/nsFileSpecWin.cpp | 38 ++++++++++++++++-----
 xpcom/io/nsFileSpec.cpp            | 26 ++++++++------
 xpcom/io/nsFileSpec.h              | 27 ++++++++++++++-
 xpcom/io/nsFileSpecMac.cpp         | 54 ++++++++++++++++++++++--------
 xpcom/io/nsFileSpecUnix.cpp        | 21 ++++++++++++
 xpcom/io/nsFileSpecWin.cpp         | 38 ++++++++++++++++-----
 10 files changed, 264 insertions(+), 68 deletions(-)

diff --git a/base/public/nsFileSpec.h b/base/public/nsFileSpec.h
index fc8a1bae1a4d1..d847f754e045a 100644
--- a/base/public/nsFileSpec.h
+++ b/base/public/nsFileSpec.h
@@ -209,7 +209,7 @@ protected:
 //========================================================================================
 class NS_BASE nsFileSpec
 //    This is whatever each platform really prefers to describe files as.  Declared first
-//  because the other two types have an embeded nsFileSpec object.
+//  because the other two types have an embedded nsFileSpec object.
 //========================================================================================
 {
     public:
@@ -310,6 +310,26 @@ class NS_BASE nsFileSpec
                                     // but a spec.  Volumes on Macintosh can have identical
                                     // names.  Perhaps could be used for an operator --() ?
 
+        typedef PRUint32        TimeStamp; // ie nsFileSpec::TimeStamp.  This is 32 bits now,
+                                           // but might change, eg, to a 64-bit class.  So use the
+                                           // typedef, and use a streaming operator to convert
+                                           // to a string, so that your code won't break.  It's
+                                           // none of your business what the number means.  Don't
+                                           // rely on the implementation.
+        void                    GetModDate(TimeStamp& outStamp) const;
+                                           // This will return different values on different
+                                           // platforms, even for the same file (eg, on a server).
+                                           // But if the platform is constant, it will increase after
+                                           // every file modification.
+        PRBool                  ModDateChanged(const TimeStamp& oldStamp) const
+                                {
+                                    TimeStamp newStamp;
+                                    GetModDate(newStamp);
+                                    return newStamp != oldStamp;
+                                }
+        
+        PRUint32                GetFileSize() const;
+        
         nsFileSpec              operator + (const char* inRelativePath) const;
         nsFileSpec              operator + (const nsString& inRelativePath) const
                                 {
@@ -368,12 +388,17 @@ class NS_BASE nsFileSpec
                                     return Execute(argsString);
                                 }
 
+    protected:
+    #ifdef XP_MAC
+        OSErr                   GetCatInfo(CInfoPBRec& outInfo) const;
+    #endif
         //--------------------------------------------------
         // Data
         //--------------------------------------------------
 
     protected:
                                 friend class nsFilePath;
+                                friend class nsDirectoryIterator;
 #ifdef XP_MAC
         FSSpec                  mSpec;
 #else
diff --git a/base/src/mac/nsFileSpecMac.cpp b/base/src/mac/nsFileSpecMac.cpp
index b54b76361e4d2..62c5de86007de 100644
--- a/base/src/mac/nsFileSpecMac.cpp
+++ b/base/src/mac/nsFileSpecMac.cpp
@@ -602,6 +602,27 @@ PRBool nsFileSpec::Exists() const
 	return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
 } // nsFileSpec::operator =
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	CInfoPBRec pb;
+    if (GetCatInfo(pb) == noErr)
+        outStamp = ((DirInfo*)&pb)->ioDrMdDat; // The mod date is in the same spot for files and dirs.
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	CInfoPBRec pb;
+    if (noErr == GetCatInfo(pb))
+        return (PRUint32)((HFileInfo*)&pb)->ioFlLgLen;
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 void nsFileSpec::SetLeafName(const char* inLeafName)
 // In leaf name can actually be a partial path...
@@ -793,6 +814,19 @@ nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform
   
 } // nsFileSpec::Execute
 
+//----------------------------------------------------------------------------------------
+OSErr nsFileSpec::GetCatInfo(CInfoPBRec& outInfo) const
+//----------------------------------------------------------------------------------------
+{
+	DirInfo	*dipb=(DirInfo *)&outInfo;
+    dipb->ioCompletion = nsnull;
+	dipb->ioFDirIndex = 0; // use dirID and name
+	dipb->ioVRefNum = mSpec.vRefNum;
+	dipb->ioDrDirID = mSpec.parID;
+	dipb->ioNamePtr = const_cast<nsFileSpec*>(this)->mSpec.name;
+	return PBGetCatInfoSync(&outInfo);
+} // nsFileSpec::GetCatInfo()
+
 //========================================================================================
 //					Macintosh nsFilePath implementation
 //========================================================================================
@@ -888,24 +922,15 @@ nsDirectoryIterator::nsDirectoryIterator(
 	, mIndex(-1)
 {
 	CInfoPBRec pb;
-	DirInfo* dipb = (DirInfo*)&pb;
-	// Sorry about this, there seems to be a bug in CWPro 4:
-	const FSSpec& inSpec = inDirectory.nsFileSpec::operator const FSSpec&();
-    Str255 outName;
-    MacFileHelpers::PLstrcpy(outName, inSpec.name);
-	pb.hFileInfo.ioNamePtr = outName;
-	pb.hFileInfo.ioVRefNum = inSpec.vRefNum;
-	pb.hFileInfo.ioDirID = inSpec.parID;
-	pb.hFileInfo.ioFDirIndex = 0;	// use ioNamePtr and ioDirID
-
-	OSErr err = PBGetCatInfoSync( &pb );
-
+    OSErr err = inDirectory.GetCatInfo(pb);
+    
 	// test that we have got a directory back, not a file
-	if ( (err != noErr ) || !( dipb->ioFlAttrib & 0x0010 ) )
+	DirInfo* dipb = (DirInfo*)&pb;
+	if (err != noErr  || !( dipb->ioFlAttrib & 0x0010))
 		return;
 	// Sorry about this, there seems to be a bug in CWPro 4:
 	FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
-	currentSpec.vRefNum = inSpec.vRefNum;
+	currentSpec.vRefNum = currentSpec.vRefNum;
 	currentSpec.parID = dipb->ioDrDirID;
 	mMaxIndex = pb.dirInfo.ioDrNmFls;
 	if (inIterateDirection > 0)
@@ -969,3 +994,4 @@ nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
 		}
 	return *this;
 } // nsDirectoryIterator::operator ++
+
diff --git a/base/src/nsFileSpec.cpp b/base/src/nsFileSpec.cpp
index 62c63b25ea41c..36d63c92385da 100644
--- a/base/src/nsFileSpec.cpp
+++ b/base/src/nsFileSpec.cpp
@@ -776,18 +776,22 @@ PRBool nsFileSpec::operator == (const nsFileSpec& inOther) const
    if ( inOther.mSpec.vRefNum == mSpec.vRefNum &&
         inOther.mSpec.parID   == mSpec.parID &&
         EqualString(inOther.mSpec.name, mSpec.name, false, false))
-        return (PR_TRUE);
-#elif XP_PC
-   // windows does not care about case.
-
-   if (_stricmp(mPath, inOther.mPath ) == 0)
-       return (PR_TRUE);
+        return PR_TRUE;
 #else
-    if (strcmp(mPath, inOther.mPath ) == 0)
-       return (PR_TRUE);
-#endif
-
-   return (PR_FALSE);
+   if (!mPath)
+       return inOther.mPath == nsNull;
+   if (!inOther.mPath)
+       return PR_FALSE;
+	#if defined(XP_PC)
+	   // windows does not care about case.
+	   if (_stricmp(mPath, inOther.mPath ) == 0)
+	       return PR_TRUE;
+	#else
+	   if (strcmp(mPath, inOther.mPath ) == 0)
+	       return PR_TRUE;
+	#endif
+#endif
+   return PR_FALSE;
 }
 
 //----------------------------------------------------------------------------------------
diff --git a/base/src/unix/nsFileSpecUnix.cpp b/base/src/unix/nsFileSpecUnix.cpp
index d5ea52c5368bc..b3f368305a7c1 100644
--- a/base/src/unix/nsFileSpecUnix.cpp
+++ b/base/src/unix/nsFileSpecUnix.cpp
@@ -98,6 +98,27 @@ PRBool nsFileSpec::Exists() const
     return 0 == stat(mPath, &st); 
 } // nsFileSpec::Exists
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        outStamp = st.st_mtime; 
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        return (PRUint32)st.st_size; 
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 PRBool nsFileSpec::IsFile() const
 //----------------------------------------------------------------------------------------
diff --git a/base/src/windows/nsFileSpecWin.cpp b/base/src/windows/nsFileSpecWin.cpp
index f93ce0ae2be21..1afee4ec6c9e0 100644
--- a/base/src/windows/nsFileSpecWin.cpp
+++ b/base/src/windows/nsFileSpecWin.cpp
@@ -41,14 +41,15 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
 //----------------------------------------------------------------------------------------
 {
   if (!ioPath)
-    return;
+      return;
   
-  if (inMakeDirs) {
-    const int mode = 0700;
-    char* unixStylePath = nsFileSpecHelpers::StringDup(ioPath);
-    nsFileSpecHelpers::NativeToUnix(unixStylePath);
-    nsFileSpecHelpers::MakeAllDirectories(unixStylePath, mode);
-    delete[] unixStylePath;
+  if (inMakeDirs)
+  {
+      const int mode = 0700;
+      char* unixStylePath = nsFileSpecHelpers::StringDup(ioPath);
+      nsFileSpecHelpers::NativeToUnix(unixStylePath);
+      nsFileSpecHelpers::MakeAllDirectories(unixStylePath, mode);
+      delete[] unixStylePath;
   }
   char buffer[_MAX_PATH];
   errno = 0;
@@ -57,7 +58,7 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
 
   NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
   if (canonicalPath[0] == '\0')
-    return;
+      return;
 
   nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
 }
@@ -189,6 +190,27 @@ PRBool nsFileSpec::Exists() const
 	return 0 == stat(mPath, &st); 
 } // nsFileSpec::Exists
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        outStamp = st.st_mtime; 
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        return (PRUint32)st.st_size; 
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 PRBool nsFileSpec::IsFile() const
 //----------------------------------------------------------------------------------------
diff --git a/xpcom/io/nsFileSpec.cpp b/xpcom/io/nsFileSpec.cpp
index 62c63b25ea41c..36d63c92385da 100644
--- a/xpcom/io/nsFileSpec.cpp
+++ b/xpcom/io/nsFileSpec.cpp
@@ -776,18 +776,22 @@ PRBool nsFileSpec::operator == (const nsFileSpec& inOther) const
    if ( inOther.mSpec.vRefNum == mSpec.vRefNum &&
         inOther.mSpec.parID   == mSpec.parID &&
         EqualString(inOther.mSpec.name, mSpec.name, false, false))
-        return (PR_TRUE);
-#elif XP_PC
-   // windows does not care about case.
-
-   if (_stricmp(mPath, inOther.mPath ) == 0)
-       return (PR_TRUE);
+        return PR_TRUE;
 #else
-    if (strcmp(mPath, inOther.mPath ) == 0)
-       return (PR_TRUE);
-#endif
-
-   return (PR_FALSE);
+   if (!mPath)
+       return inOther.mPath == nsNull;
+   if (!inOther.mPath)
+       return PR_FALSE;
+	#if defined(XP_PC)
+	   // windows does not care about case.
+	   if (_stricmp(mPath, inOther.mPath ) == 0)
+	       return PR_TRUE;
+	#else
+	   if (strcmp(mPath, inOther.mPath ) == 0)
+	       return PR_TRUE;
+	#endif
+#endif
+   return PR_FALSE;
 }
 
 //----------------------------------------------------------------------------------------
diff --git a/xpcom/io/nsFileSpec.h b/xpcom/io/nsFileSpec.h
index fc8a1bae1a4d1..d847f754e045a 100644
--- a/xpcom/io/nsFileSpec.h
+++ b/xpcom/io/nsFileSpec.h
@@ -209,7 +209,7 @@ protected:
 //========================================================================================
 class NS_BASE nsFileSpec
 //    This is whatever each platform really prefers to describe files as.  Declared first
-//  because the other two types have an embeded nsFileSpec object.
+//  because the other two types have an embedded nsFileSpec object.
 //========================================================================================
 {
     public:
@@ -310,6 +310,26 @@ class NS_BASE nsFileSpec
                                     // but a spec.  Volumes on Macintosh can have identical
                                     // names.  Perhaps could be used for an operator --() ?
 
+        typedef PRUint32        TimeStamp; // ie nsFileSpec::TimeStamp.  This is 32 bits now,
+                                           // but might change, eg, to a 64-bit class.  So use the
+                                           // typedef, and use a streaming operator to convert
+                                           // to a string, so that your code won't break.  It's
+                                           // none of your business what the number means.  Don't
+                                           // rely on the implementation.
+        void                    GetModDate(TimeStamp& outStamp) const;
+                                           // This will return different values on different
+                                           // platforms, even for the same file (eg, on a server).
+                                           // But if the platform is constant, it will increase after
+                                           // every file modification.
+        PRBool                  ModDateChanged(const TimeStamp& oldStamp) const
+                                {
+                                    TimeStamp newStamp;
+                                    GetModDate(newStamp);
+                                    return newStamp != oldStamp;
+                                }
+        
+        PRUint32                GetFileSize() const;
+        
         nsFileSpec              operator + (const char* inRelativePath) const;
         nsFileSpec              operator + (const nsString& inRelativePath) const
                                 {
@@ -368,12 +388,17 @@ class NS_BASE nsFileSpec
                                     return Execute(argsString);
                                 }
 
+    protected:
+    #ifdef XP_MAC
+        OSErr                   GetCatInfo(CInfoPBRec& outInfo) const;
+    #endif
         //--------------------------------------------------
         // Data
         //--------------------------------------------------
 
     protected:
                                 friend class nsFilePath;
+                                friend class nsDirectoryIterator;
 #ifdef XP_MAC
         FSSpec                  mSpec;
 #else
diff --git a/xpcom/io/nsFileSpecMac.cpp b/xpcom/io/nsFileSpecMac.cpp
index b54b76361e4d2..62c5de86007de 100644
--- a/xpcom/io/nsFileSpecMac.cpp
+++ b/xpcom/io/nsFileSpecMac.cpp
@@ -602,6 +602,27 @@ PRBool nsFileSpec::Exists() const
 	return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
 } // nsFileSpec::operator =
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	CInfoPBRec pb;
+    if (GetCatInfo(pb) == noErr)
+        outStamp = ((DirInfo*)&pb)->ioDrMdDat; // The mod date is in the same spot for files and dirs.
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	CInfoPBRec pb;
+    if (noErr == GetCatInfo(pb))
+        return (PRUint32)((HFileInfo*)&pb)->ioFlLgLen;
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 void nsFileSpec::SetLeafName(const char* inLeafName)
 // In leaf name can actually be a partial path...
@@ -793,6 +814,19 @@ nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform
   
 } // nsFileSpec::Execute
 
+//----------------------------------------------------------------------------------------
+OSErr nsFileSpec::GetCatInfo(CInfoPBRec& outInfo) const
+//----------------------------------------------------------------------------------------
+{
+	DirInfo	*dipb=(DirInfo *)&outInfo;
+    dipb->ioCompletion = nsnull;
+	dipb->ioFDirIndex = 0; // use dirID and name
+	dipb->ioVRefNum = mSpec.vRefNum;
+	dipb->ioDrDirID = mSpec.parID;
+	dipb->ioNamePtr = const_cast<nsFileSpec*>(this)->mSpec.name;
+	return PBGetCatInfoSync(&outInfo);
+} // nsFileSpec::GetCatInfo()
+
 //========================================================================================
 //					Macintosh nsFilePath implementation
 //========================================================================================
@@ -888,24 +922,15 @@ nsDirectoryIterator::nsDirectoryIterator(
 	, mIndex(-1)
 {
 	CInfoPBRec pb;
-	DirInfo* dipb = (DirInfo*)&pb;
-	// Sorry about this, there seems to be a bug in CWPro 4:
-	const FSSpec& inSpec = inDirectory.nsFileSpec::operator const FSSpec&();
-    Str255 outName;
-    MacFileHelpers::PLstrcpy(outName, inSpec.name);
-	pb.hFileInfo.ioNamePtr = outName;
-	pb.hFileInfo.ioVRefNum = inSpec.vRefNum;
-	pb.hFileInfo.ioDirID = inSpec.parID;
-	pb.hFileInfo.ioFDirIndex = 0;	// use ioNamePtr and ioDirID
-
-	OSErr err = PBGetCatInfoSync( &pb );
-
+    OSErr err = inDirectory.GetCatInfo(pb);
+    
 	// test that we have got a directory back, not a file
-	if ( (err != noErr ) || !( dipb->ioFlAttrib & 0x0010 ) )
+	DirInfo* dipb = (DirInfo*)&pb;
+	if (err != noErr  || !( dipb->ioFlAttrib & 0x0010))
 		return;
 	// Sorry about this, there seems to be a bug in CWPro 4:
 	FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
-	currentSpec.vRefNum = inSpec.vRefNum;
+	currentSpec.vRefNum = currentSpec.vRefNum;
 	currentSpec.parID = dipb->ioDrDirID;
 	mMaxIndex = pb.dirInfo.ioDrNmFls;
 	if (inIterateDirection > 0)
@@ -969,3 +994,4 @@ nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
 		}
 	return *this;
 } // nsDirectoryIterator::operator ++
+
diff --git a/xpcom/io/nsFileSpecUnix.cpp b/xpcom/io/nsFileSpecUnix.cpp
index d5ea52c5368bc..b3f368305a7c1 100644
--- a/xpcom/io/nsFileSpecUnix.cpp
+++ b/xpcom/io/nsFileSpecUnix.cpp
@@ -98,6 +98,27 @@ PRBool nsFileSpec::Exists() const
     return 0 == stat(mPath, &st); 
 } // nsFileSpec::Exists
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        outStamp = st.st_mtime; 
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        return (PRUint32)st.st_size; 
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 PRBool nsFileSpec::IsFile() const
 //----------------------------------------------------------------------------------------
diff --git a/xpcom/io/nsFileSpecWin.cpp b/xpcom/io/nsFileSpecWin.cpp
index f93ce0ae2be21..1afee4ec6c9e0 100644
--- a/xpcom/io/nsFileSpecWin.cpp
+++ b/xpcom/io/nsFileSpecWin.cpp
@@ -41,14 +41,15 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
 //----------------------------------------------------------------------------------------
 {
   if (!ioPath)
-    return;
+      return;
   
-  if (inMakeDirs) {
-    const int mode = 0700;
-    char* unixStylePath = nsFileSpecHelpers::StringDup(ioPath);
-    nsFileSpecHelpers::NativeToUnix(unixStylePath);
-    nsFileSpecHelpers::MakeAllDirectories(unixStylePath, mode);
-    delete[] unixStylePath;
+  if (inMakeDirs)
+  {
+      const int mode = 0700;
+      char* unixStylePath = nsFileSpecHelpers::StringDup(ioPath);
+      nsFileSpecHelpers::NativeToUnix(unixStylePath);
+      nsFileSpecHelpers::MakeAllDirectories(unixStylePath, mode);
+      delete[] unixStylePath;
   }
   char buffer[_MAX_PATH];
   errno = 0;
@@ -57,7 +58,7 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
 
   NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
   if (canonicalPath[0] == '\0')
-    return;
+      return;
 
   nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
 }
@@ -189,6 +190,27 @@ PRBool nsFileSpec::Exists() const
 	return 0 == stat(mPath, &st); 
 } // nsFileSpec::Exists
 
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        outStamp = st.st_mtime; 
+    else
+        outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+	struct stat st;
+    if (stat(mPath, &st) == 0) 
+        return (PRUint32)st.st_size; 
+    return 0;
+} // nsFileSpec::GetFileSize
+
 //----------------------------------------------------------------------------------------
 PRBool nsFileSpec::IsFile() const
 //----------------------------------------------------------------------------------------
-- 
GitLab