gecko-dev/xpcom/io/nsFileSpec.cpp

488 lines
17 KiB
C++
Raw Normal View History

1998-12-08 02:22:54 +00:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsFileSpec.h"
#include "prtypes.h"
#ifdef NS_USING_NAMESPACE
1998-12-11 03:17:47 +00:00
#include <strstream>
1998-12-11 03:17:47 +00:00
#else
1998-12-11 03:17:47 +00:00
#include <ostream.h>
#include <strstream.h>
1998-12-11 03:17:47 +00:00
#endif
1998-12-08 02:22:54 +00:00
#ifdef NS_USING_NAMESPACE
using std::ends;
using std::ostrstream;
#endif
1998-12-11 03:17:47 +00:00
#include <string.h>
#include "nsDebug.h"
1998-12-08 02:22:54 +00:00
//========================================================================================
NS_NAMESPACE nsFileSpecHelpers
1998-12-08 02:22:54 +00:00
//========================================================================================
{
enum
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
, kMaxAltDigitLength = 5
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
1998-12-08 02:22:54 +00:00
};
NS_NAMESPACE_PROTOTYPE void LeafReplace(
char*& ioPath,
1998-12-08 02:22:54 +00:00
char inSeparator,
const char* inLeafName);
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
} NS_NAMESPACE_END
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::StringDup(
const char* inString,
int allocLength)
//----------------------------------------------------------------------------------------
{
1998-12-12 02:07:11 +00:00
if (!allocLength && inString)
allocLength = strlen(inString);
1998-12-12 02:07:11 +00:00
char* newPath = inString || allocLength ? new char[allocLength + 1] : NULL;
if (!newPath)
return NULL;
strcpy(newPath, inString);
return newPath;
} // nsFileSpecHelpers::StringDup
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::AllocCat(
const char* inString1,
const char* inString2)
//----------------------------------------------------------------------------------------
{
1998-12-12 02:07:11 +00:00
if (!inString1)
return StringDup(inString2);
if (!inString2)
return StringDup(inString1);
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
if (outString)
strcat(outString, inString2);
return outString;
} // nsFileSpecHelpers::StringDup
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::StringAssign(
char*& ioString,
const char* inString2)
//----------------------------------------------------------------------------------------
{
1998-12-12 02:07:11 +00:00
if (!inString2)
{
delete [] ioString;
ioString = NULL;
}
else if (!ioString || (ioString && strlen(inString2) > strlen(ioString)))
{
delete [] ioString;
ioString = StringDup(inString2);
}
else
strcpy(ioString, inString2);
return ioString;
} // nsFileSpecHelpers::StringAssign
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::LeafReplace(
char*& ioPath,
1998-12-08 02:22:54 +00:00
char inSeparator,
const char* inLeafName)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
// Find the existing leaf name
if (!ioPath)
return;
1998-12-12 02:07:11 +00:00
if (!inLeafName)
{
*ioPath = '\0';
return;
}
char* lastSeparator = strrchr(ioPath, inSeparator);
int oldLength = strlen(ioPath);
*(++lastSeparator) = '\0'; // strip the current leaf name
int newLength = lastSeparator - ioPath + strlen(inLeafName);
if (newLength > oldLength)
{
char* newPath = StringDup(ioPath, newLength + 1);
delete [] ioPath;
ioPath = newPath;
}
strcat(ioPath, inLeafName);
1998-12-08 02:22:54 +00:00
} // nsNativeFileSpec::SetLeafName
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
// Returns a pointer to an allocated string representing the leaf.
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
1998-12-12 02:07:11 +00:00
if (!inPath)
return NULL;
char* lastSeparator = strrchr(inPath, inSeparator);
if (lastSeparator)
return StringDup(lastSeparator);
return StringDup(inPath);
} // nsNativeFileSpec::GetLeaf
1998-12-08 02:22:54 +00:00
1998-12-11 03:17:47 +00:00
#if defined(XP_PC)
1998-12-08 02:22:54 +00:00
#include "nsFileSpecWin.cpp" // Windows-specific implementations
1998-12-11 03:17:47 +00:00
#elif defined(XP_MAC)
#include "nsFileSpecMac.cpp" // Macintosh-specific implementations
1998-12-08 02:22:54 +00:00
#elif defined(XP_UNIX)
#include "nsFileSpecUnix.cpp" // Unix-specific implementations
#endif
//========================================================================================
// nsFileURL implementation
//========================================================================================
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const char* inString)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
: mURL(nsFileSpecHelpers::StringDup(inString))
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
, mNativeFileSpec(inString + kFileURLPrefixLength)
1998-12-08 02:22:54 +00:00
#endif
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
} // nsFileURL::nsFileURL
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFileURL& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
, mNativeFileSpec(inOther.GetNativeSpec())
1998-12-08 02:22:54 +00:00
#endif
{
} // nsFileURL::nsFileURL
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFilePath& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
, mNativeFileSpec(inOther.GetNativeSpec())
#endif
{
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
#ifdef XP_MAC
, mNativeFileSpec(inOther)
#endif
//----------------------------------------------------------------------------------------
{
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::~nsFileURL()
//----------------------------------------------------------------------------------------
{
delete [] mURL;
1998-12-08 02:22:54 +00:00
}
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const char* inString)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mURL, inString);
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inString + kFileURLPrefixLength;
1998-12-08 02:22:54 +00:00
#endif
} // nsFileURL::operator =
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsFileURL& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inOther.GetNativeSpec();
1998-12-08 02:22:54 +00:00
#endif
} // nsFileURL::operator =
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsFilePath& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
delete [] mURL;
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inOther.GetNativeSpec();
#endif
} // nsFileURL::operator =
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsNativeFileSpec& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
delete [] mURL;
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inOther;
#endif
} // nsFileURL::operator =
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
ostream& operator << (ostream& s, const nsFileURL& url)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
return (s << url.mURL);
1998-12-08 02:22:54 +00:00
}
//========================================================================================
// nsFilePath implementation
1998-12-08 02:22:54 +00:00
//========================================================================================
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const char* inString)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inString))
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
, mNativeFileSpec(inString)
#endif
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
1998-12-08 02:22:54 +00:00
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileURL& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
, mNativeFileSpec(inOther.GetNativeSpec())
#endif
{
}
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsNativeFileSpec& inOther)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inOther.mPath))
{
}
#endif // XP_UNIX
//----------------------------------------------------------------------------------------
nsFilePath::~nsFilePath()
//----------------------------------------------------------------------------------------
{
delete [] mPath;
}
#ifdef XP_UNIX
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsNativeFileSpec& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inOther.mPath);
}
#endif // XP_UNIX
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
nsFileSpecHelpers::StringAssign(mPath, inString);
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inString;
#endif
}
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsFileURL& inOther)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
1998-12-08 02:22:54 +00:00
#ifdef XP_MAC
mNativeFileSpec = inOther.GetNativeSpec();
#endif
}
//========================================================================================
// nsNativeFileSpec implementation
//========================================================================================
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsNativeFileSpec::nsNativeFileSpec()
//----------------------------------------------------------------------------------------
: mPath(NULL)
1998-12-08 02:22:54 +00:00
{
}
#endif
//----------------------------------------------------------------------------------------
nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
1998-12-08 02:22:54 +00:00
//----------------------------------------------------------------------------------------
#ifndef XP_MAC
: mPath(NULL)
#endif
1998-12-08 02:22:54 +00:00
{
*this = nsFilePath(inURL); // convert to unix path first
}
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::MakeUnique(const char* inSuggestedLeafName)
//----------------------------------------------------------------------------------------
{
if (inSuggestedLeafName && *inSuggestedLeafName)
1998-12-08 02:22:54 +00:00
SetLeafName(inSuggestedLeafName);
MakeUnique();
} // nsNativeFileSpec::MakeUnique
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::MakeUnique()
//----------------------------------------------------------------------------------------
{
if (!Exists())
return;
char* leafName = GetLeafName();
if (!leafName)
return;
char* lastDot = strrchr(leafName, '.');
char* suffix = "";
if (lastDot)
1998-12-08 02:22:54 +00:00
{
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
*lastDot = '\0'; // strip suffix and dot.
1998-12-08 02:22:54 +00:00
}
const int kMaxRootLength
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
if (strlen(leafName) > kMaxRootLength)
leafName[kMaxRootLength] = '\0';
for (short index = 1; index < 1000 && Exists(); index++)
1998-12-08 02:22:54 +00:00
{
// start with "Picture-1.jpg" after "Picture.jpg" exists
1998-12-08 02:22:54 +00:00
char buf[nsFileSpecHelpers::kMaxFilenameLength + 1];
ostrstream newName(buf, nsFileSpecHelpers::kMaxFilenameLength);
newName << leafName << "-" << index << suffix << '\0'; // should be: << std::ends;
1998-12-08 02:22:54 +00:00
SetLeafName(newName.str()); // or: SetLeafName(buf)
}
if (*suffix)
delete [] suffix;
delete [] leafName;
1998-12-08 02:22:54 +00:00
} // nsNativeFileSpec::MakeUnique
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::operator = (const nsFileURL& inURL)
//----------------------------------------------------------------------------------------
{
*this = nsFilePath(inURL); // convert to unix path first
}
//========================================================================================
// UNIX & WIN nsNativeFileSpec implementation
//========================================================================================
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup((const char*)inPath))
{
}
#endif // XP_UNIX
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
//----------------------------------------------------------------------------------------
1998-12-11 03:17:47 +00:00
: mPath(nsFileSpecHelpers::StringDup(inSpec.mPath))
{
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsNativeFileSpec::nsNativeFileSpec(const char* inString)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inString))
{
}
#endif //XP_UNIX,PC
//----------------------------------------------------------------------------------------
nsNativeFileSpec::~nsNativeFileSpec()
//----------------------------------------------------------------------------------------
{
#ifndef XP_MAC
delete [] mPath;
#endif
}
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsNativeFileSpec::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inString);
}
#endif //XP_UNIX
#if (defined(XP_UNIX) || defined(XP_PC))
//----------------------------------------------------------------------------------------
ostream& operator << (ostream& s, const nsNativeFileSpec& spec)
//----------------------------------------------------------------------------------------
{
return (s << (const char*)spec.mPath);
}
#endif // DEBUG && XP_UNIX