зеркало из https://github.com/mozilla/gecko-dev.git
Bug 995730 - Fix style violations in xpcom/io/. r=froydnj
This commit is contained in:
Родитель
0d2648eb80
Коммит
488f6b602e
|
@ -14,67 +14,66 @@
|
|||
namespace {
|
||||
|
||||
// BEGIN base64 encode code copied and modified from NSPR
|
||||
const unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const unsigned char* base =
|
||||
(unsigned char*)"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
Encode3to4(const unsigned char *src, T *dest)
|
||||
Encode3to4(const unsigned char* aSrc, T* aDest)
|
||||
{
|
||||
uint32_t b32 = (uint32_t)0;
|
||||
int i, j = 18;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
for (i = 0; i < 3; ++i) {
|
||||
b32 <<= 8;
|
||||
b32 |= (uint32_t)src[i];
|
||||
b32 |= (uint32_t)aSrc[i];
|
||||
}
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
dest[i] = base[ (uint32_t)((b32>>j) & 0x3F) ];
|
||||
for (i = 0; i < 4; ++i) {
|
||||
aDest[i] = base[(uint32_t)((b32 >> j) & 0x3F)];
|
||||
j -= 6;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
Encode2to4(const unsigned char *src, T *dest)
|
||||
Encode2to4(const unsigned char* aSrc, T* aDest)
|
||||
{
|
||||
dest[0] = base[ (uint32_t)((src[0]>>2) & 0x3F) ];
|
||||
dest[1] = base[ (uint32_t)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ];
|
||||
dest[2] = base[ (uint32_t)((src[1] & 0x0F) << 2) ];
|
||||
dest[3] = (unsigned char)'=';
|
||||
aDest[0] = base[(uint32_t)((aSrc[0] >> 2) & 0x3F)];
|
||||
aDest[1] = base[(uint32_t)(((aSrc[0] & 0x03) << 4) | ((aSrc[1] >> 4) & 0x0F))];
|
||||
aDest[2] = base[(uint32_t)((aSrc[1] & 0x0F) << 2)];
|
||||
aDest[3] = (unsigned char)'=';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
Encode1to4(const unsigned char *src, T *dest)
|
||||
Encode1to4(const unsigned char* aSrc, T* aDest)
|
||||
{
|
||||
dest[0] = base[ (uint32_t)((src[0]>>2) & 0x3F) ];
|
||||
dest[1] = base[ (uint32_t)((src[0] & 0x03) << 4) ];
|
||||
dest[2] = (unsigned char)'=';
|
||||
dest[3] = (unsigned char)'=';
|
||||
aDest[0] = base[(uint32_t)((aSrc[0] >> 2) & 0x3F)];
|
||||
aDest[1] = base[(uint32_t)((aSrc[0] & 0x03) << 4)];
|
||||
aDest[2] = (unsigned char)'=';
|
||||
aDest[3] = (unsigned char)'=';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
Encode(const unsigned char *src, uint32_t srclen, T *dest)
|
||||
Encode(const unsigned char* aSrc, uint32_t aSrcLen, T* aDest)
|
||||
{
|
||||
while( srclen >= 3 )
|
||||
{
|
||||
Encode3to4(src, dest);
|
||||
src += 3;
|
||||
dest += 4;
|
||||
srclen -= 3;
|
||||
while (aSrcLen >= 3) {
|
||||
Encode3to4(aSrc, aDest);
|
||||
aSrc += 3;
|
||||
aDest += 4;
|
||||
aSrcLen -= 3;
|
||||
}
|
||||
|
||||
switch( srclen )
|
||||
{
|
||||
switch (aSrcLen) {
|
||||
case 2:
|
||||
Encode2to4(src, dest);
|
||||
Encode2to4(aSrc, aDest);
|
||||
break;
|
||||
case 1:
|
||||
Encode1to4(src, dest);
|
||||
Encode1to4(aSrc, aDest);
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
|
@ -86,7 +85,8 @@ Encode(const unsigned char *src, uint32_t srclen, T *dest)
|
|||
// END base64 encode code copied and modified from NSPR.
|
||||
|
||||
template <typename T>
|
||||
struct EncodeInputStream_State {
|
||||
struct EncodeInputStream_State
|
||||
{
|
||||
unsigned char c[3];
|
||||
uint8_t charsOnStack;
|
||||
typename T::char_type* buffer;
|
||||
|
@ -94,12 +94,12 @@ struct EncodeInputStream_State {
|
|||
|
||||
template <typename T>
|
||||
NS_METHOD
|
||||
EncodeInputStream_Encoder(nsIInputStream *aStream,
|
||||
void *aClosure,
|
||||
const char *aFromSegment,
|
||||
EncodeInputStream_Encoder(nsIInputStream* aStream,
|
||||
void* aClosure,
|
||||
const char* aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount)
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
NS_ASSERTION(aCount > 0, "Er, what?");
|
||||
|
||||
|
@ -108,7 +108,7 @@ EncodeInputStream_Encoder(nsIInputStream *aStream,
|
|||
|
||||
// If we have any data left from last time, encode it now.
|
||||
uint32_t countRemaining = aCount;
|
||||
const unsigned char *src = (const unsigned char*)aFromSegment;
|
||||
const unsigned char* src = (const unsigned char*)aFromSegment;
|
||||
if (state->charsOnStack) {
|
||||
unsigned char firstSet[4];
|
||||
if (state->charsOnStack == 1) {
|
||||
|
@ -154,8 +154,8 @@ EncodeInputStream_Encoder(nsIInputStream *aStream,
|
|||
|
||||
template <typename T>
|
||||
nsresult
|
||||
EncodeInputStream(nsIInputStream *aInputStream,
|
||||
T &aDest,
|
||||
EncodeInputStream(nsIInputStream* aInputStream,
|
||||
T& aDest,
|
||||
uint32_t aCount,
|
||||
uint32_t aOffset)
|
||||
{
|
||||
|
@ -164,8 +164,9 @@ EncodeInputStream(nsIInputStream *aInputStream,
|
|||
|
||||
if (!aCount) {
|
||||
rv = aInputStream->Available(&count64);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
// if count64 is over 4GB, it will be failed at the below condition,
|
||||
// then will return NS_ERROR_OUT_OF_MEMORY
|
||||
aCount = (uint32_t)count64;
|
||||
|
@ -173,14 +174,16 @@ EncodeInputStream(nsIInputStream *aInputStream,
|
|||
|
||||
uint64_t countlong =
|
||||
(count64 + 2) / 3 * 4; // +2 due to integer math.
|
||||
if (countlong + aOffset > UINT32_MAX)
|
||||
if (countlong + aOffset > UINT32_MAX) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint32_t count = uint32_t(countlong);
|
||||
|
||||
aDest.SetLength(count + aOffset);
|
||||
if (aDest.Length() != count + aOffset)
|
||||
if (aDest.Length() != count + aOffset) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
EncodeInputStream_State<T> state;
|
||||
state.charsOnStack = 0;
|
||||
|
@ -195,25 +198,30 @@ EncodeInputStream(nsIInputStream *aInputStream,
|
|||
aCount,
|
||||
&read);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK)
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
NS_RUNTIMEABORT("Not implemented for async streams!");
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED)
|
||||
}
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
NS_RUNTIMEABORT("Requires a stream that implements ReadSegments!");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!read)
|
||||
if (!read) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finish encoding if anything is left
|
||||
if (state.charsOnStack)
|
||||
if (state.charsOnStack) {
|
||||
Encode(state.c, state.charsOnStack, state.buffer);
|
||||
}
|
||||
|
||||
if (aDest.Length())
|
||||
if (aDest.Length()) {
|
||||
// May belong to an nsCString with an unallocated buffer, so only null
|
||||
// terminate if there is a need to.
|
||||
*aDest.EndWriting() = '\0';
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -223,8 +231,8 @@ EncodeInputStream(nsIInputStream *aInputStream,
|
|||
namespace mozilla {
|
||||
|
||||
nsresult
|
||||
Base64EncodeInputStream(nsIInputStream *aInputStream,
|
||||
nsACString &aDest,
|
||||
Base64EncodeInputStream(nsIInputStream* aInputStream,
|
||||
nsACString& aDest,
|
||||
uint32_t aCount,
|
||||
uint32_t aOffset)
|
||||
{
|
||||
|
@ -232,8 +240,8 @@ Base64EncodeInputStream(nsIInputStream *aInputStream,
|
|||
}
|
||||
|
||||
nsresult
|
||||
Base64EncodeInputStream(nsIInputStream *aInputStream,
|
||||
nsAString &aDest,
|
||||
Base64EncodeInputStream(nsIInputStream* aInputStream,
|
||||
nsAString& aDest,
|
||||
uint32_t aCount,
|
||||
uint32_t aOffset)
|
||||
{
|
||||
|
@ -241,7 +249,7 @@ Base64EncodeInputStream(nsIInputStream *aInputStream,
|
|||
}
|
||||
|
||||
nsresult
|
||||
Base64Encode(const nsACString &aBinaryData, nsACString &aString)
|
||||
Base64Encode(const nsACString& aBinaryData, nsACString& aString)
|
||||
{
|
||||
// Check for overflow.
|
||||
if (aBinaryData.Length() > (UINT32_MAX / 4) * 3) {
|
||||
|
@ -256,7 +264,7 @@ Base64Encode(const nsACString &aBinaryData, nsACString &aString)
|
|||
|
||||
uint32_t stringLen = ((aBinaryData.Length() + 2) / 3) * 4;
|
||||
|
||||
char *buffer;
|
||||
char* buffer;
|
||||
|
||||
// Add one byte for null termination.
|
||||
if (aString.SetCapacity(stringLen + 1, fallible_t()) &&
|
||||
|
@ -275,7 +283,7 @@ Base64Encode(const nsACString &aBinaryData, nsACString &aString)
|
|||
}
|
||||
|
||||
nsresult
|
||||
Base64Encode(const nsAString &aString, nsAString &aBinaryData)
|
||||
Base64Encode(const nsAString& aString, nsAString& aBinaryData)
|
||||
{
|
||||
NS_LossyConvertUTF16toASCII string(aString);
|
||||
nsAutoCString binaryData;
|
||||
|
@ -291,7 +299,7 @@ Base64Encode(const nsAString &aString, nsAString &aBinaryData)
|
|||
}
|
||||
|
||||
nsresult
|
||||
Base64Decode(const nsACString &aString, nsACString &aBinaryData)
|
||||
Base64Decode(const nsACString& aString, nsACString& aBinaryData)
|
||||
{
|
||||
// Check for overflow.
|
||||
if (aString.Length() > UINT32_MAX / 3) {
|
||||
|
@ -306,7 +314,7 @@ Base64Decode(const nsACString &aString, nsACString &aBinaryData)
|
|||
|
||||
uint32_t binaryDataLen = ((aString.Length() * 3) / 4);
|
||||
|
||||
char *buffer;
|
||||
char* buffer;
|
||||
|
||||
// Add one byte for null termination.
|
||||
if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible_t()) &&
|
||||
|
@ -333,7 +341,7 @@ Base64Decode(const nsACString &aString, nsACString &aBinaryData)
|
|||
}
|
||||
|
||||
nsresult
|
||||
Base64Decode(const nsAString &aBinaryData, nsAString &aString)
|
||||
Base64Decode(const nsAString& aBinaryData, nsAString& aString)
|
||||
{
|
||||
NS_LossyConvertUTF16toASCII binaryData(aBinaryData);
|
||||
nsAutoCString string;
|
||||
|
|
|
@ -13,25 +13,25 @@ class nsIInputStream;
|
|||
namespace mozilla {
|
||||
|
||||
nsresult
|
||||
Base64EncodeInputStream(nsIInputStream *aInputStream,
|
||||
nsACString &aDest,
|
||||
Base64EncodeInputStream(nsIInputStream* aInputStream,
|
||||
nsACString& aDest,
|
||||
uint32_t aCount,
|
||||
uint32_t aOffset = 0);
|
||||
nsresult
|
||||
Base64EncodeInputStream(nsIInputStream *aInputStream,
|
||||
nsAString &aDest,
|
||||
Base64EncodeInputStream(nsIInputStream* aInputStream,
|
||||
nsAString& aDest,
|
||||
uint32_t aCount,
|
||||
uint32_t aOffset = 0);
|
||||
|
||||
nsresult
|
||||
Base64Encode(const nsACString &aString, nsACString &aBinary);
|
||||
Base64Encode(const nsACString& aString, nsACString& aBinary);
|
||||
nsresult
|
||||
Base64Encode(const nsAString &aString, nsAString &aBinaryData);
|
||||
Base64Encode(const nsAString& aString, nsAString& aBinaryData);
|
||||
|
||||
nsresult
|
||||
Base64Decode(const nsACString &aBinaryData, nsACString &aString);
|
||||
Base64Decode(const nsACString& aBinaryData, nsACString& aString);
|
||||
nsresult
|
||||
Base64Decode(const nsAString &aBinaryData, nsAString &aString);
|
||||
Base64Decode(const nsAString& aBinaryData, nsAString& aString);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
namespace CocoaFileUtils {
|
||||
|
||||
nsresult RevealFileInFinder(CFURLRef url);
|
||||
nsresult OpenURL(CFURLRef url);
|
||||
nsresult GetFileCreatorCode(CFURLRef url, OSType *creatorCode);
|
||||
nsresult SetFileCreatorCode(CFURLRef url, OSType creatorCode);
|
||||
nsresult GetFileTypeCode(CFURLRef url, OSType *typeCode);
|
||||
nsresult SetFileTypeCode(CFURLRef url, OSType typeCode);
|
||||
nsresult RevealFileInFinder(CFURLRef aUrl);
|
||||
nsresult OpenURL(CFURLRef aUrl);
|
||||
nsresult GetFileCreatorCode(CFURLRef aUrl, OSType* aCreatorCode);
|
||||
nsresult SetFileCreatorCode(CFURLRef aUrl, OSType aCreatorCode);
|
||||
nsresult GetFileTypeCode(CFURLRef aUrl, OSType* aTypeCode);
|
||||
nsresult SetFileTypeCode(CFURLRef aUrl, OSType aTypeCode);
|
||||
|
||||
} // namespace CocoaFileUtils
|
||||
|
||||
|
|
|
@ -17,8 +17,14 @@ namespace {
|
|||
struct ScopedMappedViewTraits
|
||||
{
|
||||
typedef void* type;
|
||||
static void* empty() { return nullptr; }
|
||||
static void release(void* ptr) { UnmapViewOfFile(ptr); }
|
||||
static void* empty()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
static void release(void* aPtr)
|
||||
{
|
||||
UnmapViewOfFile(aPtr);
|
||||
}
|
||||
};
|
||||
typedef mozilla::Scoped<ScopedMappedViewTraits> ScopedMappedView;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ NtPathToDosPath(const nsAString& aNtPath, nsAString& aDosPath)
|
|||
}
|
||||
nsAutoString logicalDrives;
|
||||
DWORD len = 0;
|
||||
while(true) {
|
||||
while (true) {
|
||||
len = GetLogicalDriveStringsW(len, reinterpret_cast<wchar_t*>(logicalDrives.BeginWriting()));
|
||||
if (!len) {
|
||||
return false;
|
||||
|
@ -56,7 +56,8 @@ NtPathToDosPath(const nsAString& aNtPath, nsAString& aDosPath)
|
|||
DWORD targetPathLen = 0;
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
while (true) {
|
||||
targetPathLen = QueryDosDeviceW(driveTemplate, reinterpret_cast<wchar_t*>(targetPath.BeginWriting()),
|
||||
targetPathLen = QueryDosDeviceW(driveTemplate,
|
||||
reinterpret_cast<wchar_t*>(targetPath.BeginWriting()),
|
||||
targetPath.Length());
|
||||
if (targetPathLen || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
break;
|
||||
|
|
|
@ -56,19 +56,19 @@ using mozilla::IsWin7OrLater;
|
|||
typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
|
||||
DWORD dwFlags,
|
||||
HANDLE hToken,
|
||||
PWSTR *ppszPath);
|
||||
PWSTR* ppszPath);
|
||||
|
||||
static nsGetKnownFolderPath gGetKnownFolderPath = nullptr;
|
||||
#endif
|
||||
|
||||
void StartupSpecialSystemDirectory()
|
||||
void
|
||||
StartupSpecialSystemDirectory()
|
||||
{
|
||||
#if defined (XP_WIN)
|
||||
// SHGetKnownFolderPath is only available on Windows Vista
|
||||
// so that we need to use GetProcAddress to get the pointer.
|
||||
HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
|
||||
if(hShell32DLLInst)
|
||||
{
|
||||
if (hShell32DLLInst) {
|
||||
gGetKnownFolderPath = (nsGetKnownFolderPath)
|
||||
GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
|
||||
}
|
||||
|
@ -77,16 +77,19 @@ void StartupSpecialSystemDirectory()
|
|||
|
||||
#if defined (XP_WIN)
|
||||
|
||||
static nsresult GetKnownFolder(GUID* guid, nsIFile** aFile)
|
||||
static nsresult
|
||||
GetKnownFolder(GUID* aGuid, nsIFile** aFile)
|
||||
{
|
||||
if (!guid || !gGetKnownFolderPath)
|
||||
if (!aGuid || !gGetKnownFolderPath) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PWSTR path = nullptr;
|
||||
gGetKnownFolderPath(*guid, 0, nullptr, &path);
|
||||
gGetKnownFolderPath(*aGuid, 0, nullptr, &path);
|
||||
|
||||
if (!path)
|
||||
if (!path) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = NS_NewLocalFile(nsDependentString(path),
|
||||
true,
|
||||
|
@ -97,19 +100,19 @@ static nsresult GetKnownFolder(GUID* guid, nsIFile** aFile)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
GetWindowsFolder(int folder, nsIFile** aFile)
|
||||
GetWindowsFolder(int aFolder, nsIFile** aFile)
|
||||
{
|
||||
WCHAR path_orig[MAX_PATH + 3];
|
||||
WCHAR *path = path_orig+1;
|
||||
HRESULT result = SHGetSpecialFolderPathW(nullptr, path, folder, true);
|
||||
WCHAR* path = path_orig + 1;
|
||||
HRESULT result = SHGetSpecialFolderPathW(nullptr, path, aFolder, true);
|
||||
|
||||
if (!SUCCEEDED(result))
|
||||
if (!SUCCEEDED(result)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Append the trailing slash
|
||||
int len = wcslen(path);
|
||||
if (len > 1 && path[len - 1] != L'\\')
|
||||
{
|
||||
if (len > 1 && path[len - 1] != L'\\') {
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
}
|
||||
|
@ -119,10 +122,10 @@ GetWindowsFolder(int folder, nsIFile** aFile)
|
|||
|
||||
__inline HRESULT
|
||||
SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
|
||||
REFIID riid, void **ppv)
|
||||
REFIID riid, void** ppv)
|
||||
{
|
||||
*ppv = nullptr;
|
||||
IShellLibrary *plib;
|
||||
IShellLibrary* plib;
|
||||
HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS(&plib));
|
||||
|
@ -146,8 +149,9 @@ GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
|
|||
nsIFile** aFile)
|
||||
{
|
||||
// Skip off checking for library support if the os is Vista or lower.
|
||||
if (!IsWin7OrLater())
|
||||
if (!IsWin7OrLater()) {
|
||||
return GetWindowsFolder(aFallbackFolderId, aFile);
|
||||
}
|
||||
|
||||
nsRefPtr<IShellLibrary> shellLib;
|
||||
nsRefPtr<IShellItem> savePath;
|
||||
|
@ -178,15 +182,17 @@ GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
|
|||
* querying the registry when the call to SHGetSpecialFolderPathW is unable to
|
||||
* provide these paths (Bug 513958).
|
||||
*/
|
||||
static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
|
||||
static nsresult
|
||||
GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
|
||||
{
|
||||
HKEY key;
|
||||
NS_NAMED_LITERAL_STRING(keyName,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
||||
DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, KEY_READ,
|
||||
&key);
|
||||
if (res != ERROR_SUCCESS)
|
||||
if (res != ERROR_SUCCESS) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
WCHAR path[MAX_PATH + 2];
|
||||
DWORD type, size;
|
||||
|
@ -195,13 +201,13 @@ static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
|
|||
::RegCloseKey(key);
|
||||
// The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
|
||||
// buffer size must not equal 0, and the buffer size be a multiple of 2.
|
||||
if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0)
|
||||
if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Append the trailing slash
|
||||
int len = wcslen(path);
|
||||
if (len > 1 && path[len - 1] != L'\\')
|
||||
{
|
||||
if (len > 1 && path[len - 1] != L'\\') {
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
}
|
||||
|
@ -216,7 +222,7 @@ static nsresult
|
|||
GetUnixHomeDir(nsIFile** aFile)
|
||||
{
|
||||
#ifdef VMS
|
||||
char *pHome;
|
||||
char* pHome;
|
||||
pHome = getenv("HOME");
|
||||
if (*pHome == '/') {
|
||||
return NS_NewNativeLocalFile(nsDependentCString(pHome),
|
||||
|
@ -262,124 +268,137 @@ GetUnixHomeDir(nsIFile** aFile)
|
|||
SOFTWARE.
|
||||
*/
|
||||
|
||||
static char *
|
||||
xdg_user_dir_lookup (const char *type)
|
||||
static char*
|
||||
xdg_user_dir_lookup(const char* aType)
|
||||
{
|
||||
FILE *file;
|
||||
char *home_dir, *config_home, *config_file;
|
||||
FILE* file;
|
||||
char* home_dir;
|
||||
char* config_home;
|
||||
char* config_file;
|
||||
char buffer[512];
|
||||
char *user_dir;
|
||||
char *p, *d;
|
||||
char* user_dir;
|
||||
char* p;
|
||||
char* d;
|
||||
int len;
|
||||
int relative;
|
||||
|
||||
home_dir = getenv ("HOME");
|
||||
home_dir = getenv("HOME");
|
||||
|
||||
if (home_dir == nullptr)
|
||||
if (!home_dir) {
|
||||
goto error;
|
||||
|
||||
config_home = getenv ("XDG_CONFIG_HOME");
|
||||
if (config_home == nullptr || config_home[0] == 0)
|
||||
{
|
||||
config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
|
||||
if (config_file == nullptr)
|
||||
goto error;
|
||||
|
||||
strcpy (config_file, home_dir);
|
||||
strcat (config_file, "/.config/user-dirs.dirs");
|
||||
}
|
||||
else
|
||||
{
|
||||
config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
|
||||
if (config_file == nullptr)
|
||||
goto error;
|
||||
|
||||
strcpy (config_file, config_home);
|
||||
strcat (config_file, "/user-dirs.dirs");
|
||||
}
|
||||
|
||||
file = fopen (config_file, "r");
|
||||
free (config_file);
|
||||
if (file == nullptr)
|
||||
config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (!config_home || config_home[0] == 0) {
|
||||
config_file = (char*)malloc(strlen(home_dir) +
|
||||
strlen("/.config/user-dirs.dirs") + 1);
|
||||
if (!config_file) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
strcpy(config_file, home_dir);
|
||||
strcat(config_file, "/.config/user-dirs.dirs");
|
||||
} else {
|
||||
config_file = (char*)malloc(strlen(config_home) +
|
||||
strlen("/user-dirs.dirs") + 1);
|
||||
if (!config_file) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
strcpy(config_file, config_home);
|
||||
strcat(config_file, "/user-dirs.dirs");
|
||||
}
|
||||
|
||||
file = fopen(config_file, "r");
|
||||
free(config_file);
|
||||
if (!file) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
user_dir = nullptr;
|
||||
while (fgets (buffer, sizeof (buffer), file))
|
||||
{
|
||||
while (fgets(buffer, sizeof(buffer), file)) {
|
||||
/* Remove newline at end */
|
||||
len = strlen (buffer);
|
||||
if (len > 0 && buffer[len-1] == '\n')
|
||||
buffer[len-1] = 0;
|
||||
len = strlen(buffer);
|
||||
if (len > 0 && buffer[len - 1] == '\n') {
|
||||
buffer[len - 1] = 0;
|
||||
}
|
||||
|
||||
p = buffer;
|
||||
while (*p == ' ' || *p == '\t')
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (strncmp (p, "XDG_", 4) != 0)
|
||||
if (strncmp(p, "XDG_", 4) != 0) {
|
||||
continue;
|
||||
}
|
||||
p += 4;
|
||||
if (strncmp (p, type, strlen (type)) != 0)
|
||||
if (strncmp(p, aType, strlen(aType)) != 0) {
|
||||
continue;
|
||||
p += strlen (type);
|
||||
if (strncmp (p, "_DIR", 4) != 0)
|
||||
}
|
||||
p += strlen(aType);
|
||||
if (strncmp(p, "_DIR", 4) != 0) {
|
||||
continue;
|
||||
}
|
||||
p += 4;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '=')
|
||||
if (*p != '=') {
|
||||
continue;
|
||||
}
|
||||
p++;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '"')
|
||||
if (*p != '"') {
|
||||
continue;
|
||||
}
|
||||
p++;
|
||||
|
||||
relative = 0;
|
||||
if (strncmp (p, "$HOME/", 6) == 0)
|
||||
{
|
||||
if (strncmp(p, "$HOME/", 6) == 0) {
|
||||
p += 6;
|
||||
relative = 1;
|
||||
}
|
||||
else if (*p != '/')
|
||||
} else if (*p != '/') {
|
||||
continue;
|
||||
|
||||
if (relative)
|
||||
{
|
||||
user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
|
||||
if (user_dir == nullptr)
|
||||
goto error2;
|
||||
|
||||
strcpy (user_dir, home_dir);
|
||||
strcat (user_dir, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
user_dir = (char*) malloc (strlen (p) + 1);
|
||||
if (user_dir == nullptr)
|
||||
|
||||
if (relative) {
|
||||
user_dir = (char*)malloc(strlen(home_dir) + 1 + strlen(p) + 1);
|
||||
if (!user_dir) {
|
||||
goto error2;
|
||||
}
|
||||
|
||||
strcpy(user_dir, home_dir);
|
||||
strcat(user_dir, "/");
|
||||
} else {
|
||||
user_dir = (char*)malloc(strlen(p) + 1);
|
||||
if (!user_dir) {
|
||||
goto error2;
|
||||
}
|
||||
|
||||
*user_dir = 0;
|
||||
}
|
||||
|
||||
d = user_dir + strlen (user_dir);
|
||||
while (*p && *p != '"')
|
||||
{
|
||||
if ((*p == '\\') && (*(p+1) != 0))
|
||||
d = user_dir + strlen(user_dir);
|
||||
while (*p && *p != '"') {
|
||||
if ((*p == '\\') && (*(p + 1) != 0)) {
|
||||
p++;
|
||||
}
|
||||
*d++ = *p++;
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
error2:
|
||||
fclose (file);
|
||||
fclose(file);
|
||||
|
||||
if (user_dir)
|
||||
if (user_dir) {
|
||||
return user_dir;
|
||||
}
|
||||
|
||||
error:
|
||||
return nullptr;
|
||||
|
@ -410,9 +429,8 @@ static nsresult
|
|||
GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
|
||||
nsIFile** aFile)
|
||||
{
|
||||
char *dir = xdg_user_dir_lookup
|
||||
(xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory -
|
||||
Unix_XDG_Desktop]);
|
||||
char* dir = xdg_user_dir_lookup(
|
||||
xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory - Unix_XDG_Desktop]);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> file;
|
||||
|
@ -424,27 +442,30 @@ GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
|
|||
// for the XDG desktop dir, fall back to HOME/Desktop
|
||||
// (for historical compatibility)
|
||||
rv = GetUnixHomeDir(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// no fallback for the other XDG dirs
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool exists;
|
||||
rv = file->Exists(&exists);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!exists) {
|
||||
rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*aFile = nullptr;
|
||||
|
@ -464,18 +485,19 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
char path[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
switch (aSystemSystemDirectory)
|
||||
{
|
||||
switch (aSystemSystemDirectory) {
|
||||
case OS_CurrentWorkingDirectory:
|
||||
#if defined(XP_WIN)
|
||||
if (!_wgetcwd(path, MAX_PATH))
|
||||
if (!_wgetcwd(path, MAX_PATH)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_NewLocalFile(nsDependentString(path),
|
||||
true,
|
||||
aFile);
|
||||
#else
|
||||
if(!getcwd(path, MAXPATHLEN))
|
||||
if (!getcwd(path, MAXPATHLEN)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
|
@ -488,10 +510,12 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
#if defined (XP_WIN)
|
||||
{
|
||||
int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
break;
|
||||
if (path[1] == char16_t(':') && path[2] == char16_t('\\'))
|
||||
}
|
||||
if (path[1] == char16_t(':') && path[2] == char16_t('\\')) {
|
||||
path[3] = 0;
|
||||
}
|
||||
|
||||
return NS_NewLocalFile(nsDependentString(path),
|
||||
true,
|
||||
|
@ -508,8 +532,9 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
#if defined (XP_WIN)
|
||||
{
|
||||
DWORD len = ::GetTempPathW(MAX_PATH, path);
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
return NS_NewLocalFile(nsDependentString(path, len),
|
||||
true,
|
||||
aFile);
|
||||
|
@ -521,7 +546,7 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
|
||||
#elif defined(XP_UNIX)
|
||||
{
|
||||
static const char *tPath = nullptr;
|
||||
static const char* tPath = nullptr;
|
||||
if (!tPath) {
|
||||
tPath = PR_GetEnv("TMPDIR");
|
||||
if (!tPath || !*tPath) {
|
||||
|
@ -542,13 +567,13 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
break;
|
||||
#endif
|
||||
#if defined (XP_WIN)
|
||||
case Win_SystemDirectory:
|
||||
{
|
||||
case Win_SystemDirectory: {
|
||||
int32_t len = ::GetSystemDirectoryW(path, MAX_PATH);
|
||||
|
||||
// Need enough space to add the trailing backslash
|
||||
if (!len || len > MAX_PATH - 2)
|
||||
if (!len || len > MAX_PATH - 2) {
|
||||
break;
|
||||
}
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
|
||||
|
@ -557,13 +582,13 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
aFile);
|
||||
}
|
||||
|
||||
case Win_WindowsDirectory:
|
||||
{
|
||||
case Win_WindowsDirectory: {
|
||||
int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
|
||||
|
||||
// Need enough space to add the trailing backslash
|
||||
if (!len || len > MAX_PATH - 2)
|
||||
if (!len || len > MAX_PATH - 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
|
@ -573,23 +598,22 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
aFile);
|
||||
}
|
||||
|
||||
case Win_ProgramFiles:
|
||||
{
|
||||
case Win_ProgramFiles: {
|
||||
return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
|
||||
}
|
||||
|
||||
case Win_HomeDirectory:
|
||||
{
|
||||
case Win_HomeDirectory: {
|
||||
nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int32_t len;
|
||||
if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0)
|
||||
{
|
||||
if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0) {
|
||||
// Need enough space to add the trailing backslash
|
||||
if (len > MAX_PATH - 2)
|
||||
if (len > MAX_PATH - 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
|
@ -597,23 +621,25 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
rv = NS_NewLocalFile(nsDependentString(path, len),
|
||||
true,
|
||||
aFile);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
|
||||
if (0 < len && len < MAX_PATH)
|
||||
{
|
||||
if (0 < len && len < MAX_PATH) {
|
||||
WCHAR temp[MAX_PATH];
|
||||
DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
|
||||
if (0 < len2 && len + len2 < MAX_PATH)
|
||||
if (0 < len2 && len + len2 < MAX_PATH) {
|
||||
wcsncat(path, temp, len2);
|
||||
}
|
||||
|
||||
len = wcslen(path);
|
||||
|
||||
// Need enough space to add the trailing backslash
|
||||
if (len > MAX_PATH - 2)
|
||||
if (len > MAX_PATH - 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
path[len] = L'\\';
|
||||
path[++len] = L'\0';
|
||||
|
@ -623,152 +649,124 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
aFile);
|
||||
}
|
||||
}
|
||||
case Win_Desktop:
|
||||
{
|
||||
case Win_Desktop: {
|
||||
return GetWindowsFolder(CSIDL_DESKTOP, aFile);
|
||||
}
|
||||
case Win_Programs:
|
||||
{
|
||||
case Win_Programs: {
|
||||
return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
|
||||
}
|
||||
|
||||
case Win_Downloads:
|
||||
{
|
||||
case Win_Downloads: {
|
||||
// Defined in KnownFolders.h.
|
||||
GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64,
|
||||
0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
|
||||
GUID folderid_downloads = {
|
||||
0x374de290, 0x123f, 0x4565,
|
||||
{ 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b }
|
||||
};
|
||||
nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
|
||||
// On WinXP, there is no downloads folder, default
|
||||
// to 'Desktop'.
|
||||
if(NS_ERROR_FAILURE == rv)
|
||||
{
|
||||
if (NS_ERROR_FAILURE == rv) {
|
||||
rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
case Win_Controls:
|
||||
{
|
||||
case Win_Controls: {
|
||||
return GetWindowsFolder(CSIDL_CONTROLS, aFile);
|
||||
}
|
||||
case Win_Printers:
|
||||
{
|
||||
case Win_Printers: {
|
||||
return GetWindowsFolder(CSIDL_PRINTERS, aFile);
|
||||
}
|
||||
case Win_Personal:
|
||||
{
|
||||
case Win_Personal: {
|
||||
return GetWindowsFolder(CSIDL_PERSONAL, aFile);
|
||||
}
|
||||
case Win_Favorites:
|
||||
{
|
||||
case Win_Favorites: {
|
||||
return GetWindowsFolder(CSIDL_FAVORITES, aFile);
|
||||
}
|
||||
case Win_Startup:
|
||||
{
|
||||
case Win_Startup: {
|
||||
return GetWindowsFolder(CSIDL_STARTUP, aFile);
|
||||
}
|
||||
case Win_Recent:
|
||||
{
|
||||
case Win_Recent: {
|
||||
return GetWindowsFolder(CSIDL_RECENT, aFile);
|
||||
}
|
||||
case Win_Sendto:
|
||||
{
|
||||
case Win_Sendto: {
|
||||
return GetWindowsFolder(CSIDL_SENDTO, aFile);
|
||||
}
|
||||
case Win_Bitbucket:
|
||||
{
|
||||
case Win_Bitbucket: {
|
||||
return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
|
||||
}
|
||||
case Win_Startmenu:
|
||||
{
|
||||
case Win_Startmenu: {
|
||||
return GetWindowsFolder(CSIDL_STARTMENU, aFile);
|
||||
}
|
||||
case Win_Desktopdirectory:
|
||||
{
|
||||
case Win_Desktopdirectory: {
|
||||
return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
|
||||
}
|
||||
case Win_Drives:
|
||||
{
|
||||
case Win_Drives: {
|
||||
return GetWindowsFolder(CSIDL_DRIVES, aFile);
|
||||
}
|
||||
case Win_Network:
|
||||
{
|
||||
case Win_Network: {
|
||||
return GetWindowsFolder(CSIDL_NETWORK, aFile);
|
||||
}
|
||||
case Win_Nethood:
|
||||
{
|
||||
case Win_Nethood: {
|
||||
return GetWindowsFolder(CSIDL_NETHOOD, aFile);
|
||||
}
|
||||
case Win_Fonts:
|
||||
{
|
||||
case Win_Fonts: {
|
||||
return GetWindowsFolder(CSIDL_FONTS, aFile);
|
||||
}
|
||||
case Win_Templates:
|
||||
{
|
||||
case Win_Templates: {
|
||||
return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
|
||||
}
|
||||
case Win_Common_Startmenu:
|
||||
{
|
||||
case Win_Common_Startmenu: {
|
||||
return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
|
||||
}
|
||||
case Win_Common_Programs:
|
||||
{
|
||||
case Win_Common_Programs: {
|
||||
return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
|
||||
}
|
||||
case Win_Common_Startup:
|
||||
{
|
||||
case Win_Common_Startup: {
|
||||
return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
|
||||
}
|
||||
case Win_Common_Desktopdirectory:
|
||||
{
|
||||
case Win_Common_Desktopdirectory: {
|
||||
return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
|
||||
}
|
||||
case Win_Common_AppData:
|
||||
{
|
||||
case Win_Common_AppData: {
|
||||
return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile);
|
||||
}
|
||||
case Win_Printhood:
|
||||
{
|
||||
case Win_Printhood: {
|
||||
return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
|
||||
}
|
||||
case Win_Cookies:
|
||||
{
|
||||
case Win_Cookies: {
|
||||
return GetWindowsFolder(CSIDL_COOKIES, aFile);
|
||||
}
|
||||
case Win_Appdata:
|
||||
{
|
||||
case Win_Appdata: {
|
||||
nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = GetRegWindowsAppDataFolder(false, aFile);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
case Win_LocalAppdata:
|
||||
{
|
||||
case Win_LocalAppdata: {
|
||||
nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = GetRegWindowsAppDataFolder(true, aFile);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
case Win_Documents:
|
||||
{
|
||||
case Win_Documents: {
|
||||
return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
|
||||
FOLDERID_DocumentsLibrary,
|
||||
aFile);
|
||||
}
|
||||
case Win_Pictures:
|
||||
{
|
||||
case Win_Pictures: {
|
||||
return GetLibrarySaveToPath(CSIDL_MYPICTURES,
|
||||
FOLDERID_PicturesLibrary,
|
||||
aFile);
|
||||
}
|
||||
case Win_Music:
|
||||
{
|
||||
case Win_Music: {
|
||||
return GetLibrarySaveToPath(CSIDL_MYMUSIC,
|
||||
FOLDERID_MusicLibrary,
|
||||
aFile);
|
||||
}
|
||||
case Win_Videos:
|
||||
{
|
||||
case Win_Videos: {
|
||||
return GetLibrarySaveToPath(CSIDL_MYVIDEO,
|
||||
FOLDERID_VideosLibrary,
|
||||
aFile);
|
||||
|
@ -807,19 +805,19 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
|
||||
#if defined (MOZ_WIDGET_COCOA)
|
||||
nsresult
|
||||
GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile **localFile)
|
||||
GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile** aLocalFile)
|
||||
{
|
||||
OSErr err;
|
||||
FSRef fsRef;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
|
||||
if (err == noErr)
|
||||
{
|
||||
NS_NewLocalFile(EmptyString(), true, localFile);
|
||||
nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*localFile));
|
||||
if (localMacFile)
|
||||
if (err == noErr) {
|
||||
NS_NewLocalFile(EmptyString(), true, aLocalFile);
|
||||
nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*aLocalFile));
|
||||
if (localMacFile) {
|
||||
rv = localMacFile->InitWithFSRef(&fsRef);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ extern void StartupSpecialSystemDirectory();
|
|||
enum SystemDirectories {
|
||||
OS_DriveDirectory = 1,
|
||||
OS_TemporaryDirectory = 2,
|
||||
OS_CurrentProcessDirectory= 3,
|
||||
OS_CurrentWorkingDirectory= 4,
|
||||
XPCOM_CurrentProcessComponentDirectory= 5,
|
||||
XPCOM_CurrentProcessComponentRegistry= 6,
|
||||
OS_CurrentProcessDirectory = 3,
|
||||
OS_CurrentWorkingDirectory = 4,
|
||||
XPCOM_CurrentProcessComponentDirectory = 5,
|
||||
XPCOM_CurrentProcessComponentRegistry = 6,
|
||||
|
||||
Moz_BinDirectory = 100 ,
|
||||
Mac_SystemDirectory = 101,
|
||||
|
@ -98,7 +98,7 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
nsIFile** aFile);
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
nsresult
|
||||
GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile **localFile);
|
||||
GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile** aLocalFile);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,23 +50,27 @@ using namespace mozilla;
|
|||
static nsresult
|
||||
GetTempDir(nsIFile** aTempDir)
|
||||
{
|
||||
if (NS_WARN_IF(!aTempDir))
|
||||
if (NS_WARN_IF(!aTempDir)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIFile> tmpFile;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// On windows DELETE_ON_CLOSE is unreliable, so we store temporary files
|
||||
// in a subdir of the temp dir and delete that in an idle service observer
|
||||
// to ensure it's been cleared.
|
||||
rv = tmpFile->AppendNative(nsDependentCString("mozilla-temp-files"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
tmpFile.forget(aTempDir);
|
||||
|
@ -77,14 +81,16 @@ GetTempDir(nsIFile** aTempDir)
|
|||
nsresult
|
||||
NS_OpenAnonymousTemporaryFile(PRFileDesc** aOutFileDesc)
|
||||
{
|
||||
if (NS_WARN_IF(!aOutFileDesc))
|
||||
if (NS_WARN_IF(!aOutFileDesc)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> tmpFile;
|
||||
rv = GetTempDir(getter_AddRefs(tmpFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Give the temp file a name with a random element. CreateUnique will also
|
||||
// append a counter to the name if it encounters a name collision. Adding
|
||||
|
@ -96,12 +102,14 @@ NS_OpenAnonymousTemporaryFile(PRFileDesc** aOutFileDesc)
|
|||
name.AppendInt(rand());
|
||||
|
||||
rv = tmpFile->AppendNative(name);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0700);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = tmpFile->OpenNSPRFileDesc(PR_RDWR | nsIFile::DELETE_ON_CLOSE,
|
||||
PR_IRWXU, aOutFileDesc);
|
||||
|
@ -135,42 +143,50 @@ NS_OpenAnonymousTemporaryFile(PRFileDesc** aOutFileDesc)
|
|||
// idle observer and its timer on shutdown. Note: the observer and idle
|
||||
// services hold references to instances of this object, and those references
|
||||
// are what keep this object alive.
|
||||
class nsAnonTempFileRemover MOZ_FINAL : public nsIObserver {
|
||||
class nsAnonTempFileRemover MOZ_FINAL : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsAnonTempFileRemover() {
|
||||
nsAnonTempFileRemover()
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsAnonTempFileRemover);
|
||||
}
|
||||
|
||||
~nsAnonTempFileRemover() {
|
||||
~nsAnonTempFileRemover()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsAnonTempFileRemover);
|
||||
}
|
||||
|
||||
nsresult Init() {
|
||||
nsresult Init()
|
||||
{
|
||||
// We add the idle observer in a timer, so that the app has enough
|
||||
// time to start up before we add the idle observer. If we register the
|
||||
// idle observer too early, it will be registered before the fake idle
|
||||
// service is installed when running in xpcshell, and this interferes with
|
||||
// the fake idle service, causing xpcshell-test failures.
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (NS_WARN_IF(!mTimer))
|
||||
if (NS_WARN_IF(!mTimer)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = mTimer->Init(this,
|
||||
SCHEDULE_TIMEOUT_MS,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Register shutdown observer so we can cancel the timer if we shutdown before
|
||||
// the timer runs.
|
||||
nsCOMPtr<nsIObserverService> obsSrv = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obsSrv))
|
||||
if (NS_WARN_IF(!obsSrv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return obsSrv->AddObserver(this, XPCOM_SHUTDOWN_TOPIC, false);
|
||||
}
|
||||
|
||||
void Cleanup() {
|
||||
void Cleanup()
|
||||
{
|
||||
// Cancel timer.
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
|
@ -189,9 +205,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
NS_IMETHODIMP Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (nsCRT::strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0 &&
|
||||
NS_FAILED(RegisterIdleObserver())) {
|
||||
|
@ -208,22 +224,26 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RegisterIdleObserver() {
|
||||
nsresult RegisterIdleObserver()
|
||||
{
|
||||
// Add this as an idle observer. When we've been idle for
|
||||
// TEMP_FILE_IDLE_TIME_S seconds, we'll get a notification, and we'll then
|
||||
// try to delete any stray temp files.
|
||||
nsCOMPtr<nsIIdleService> idleSvc =
|
||||
do_GetService("@mozilla.org/widget/idleservice;1");
|
||||
if (!idleSvc)
|
||||
if (!idleSvc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return idleSvc->AddIdleObserver(this, TEMP_FILE_IDLE_TIME_S);
|
||||
}
|
||||
|
||||
void RemoveAnonTempFileFiles() {
|
||||
void RemoveAnonTempFileFiles()
|
||||
{
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
nsresult rv = GetTempDir(getter_AddRefs(tmpDir));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the directory recursively.
|
||||
tmpDir->Remove(true);
|
||||
|
@ -235,7 +255,9 @@ private:
|
|||
|
||||
NS_IMPL_ISUPPORTS(nsAnonTempFileRemover, nsIObserver)
|
||||
|
||||
nsresult CreateAnonTempFileRemover() {
|
||||
nsresult
|
||||
CreateAnonTempFileRemover()
|
||||
{
|
||||
// Create a temp file remover. If Init() succeeds, the temp file remover is kept
|
||||
// alive by a reference held by the observer service, since the temp file remover
|
||||
// is a shutdown observer. We only create the temp file remover if we're running
|
||||
|
|
|
@ -75,137 +75,124 @@ nsAppFileLocationProvider::nsAppFileLocationProvider()
|
|||
// nsAppFileLocationProvider::nsISupports
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
||||
NS_IMPL_ISUPPORTS(nsAppFileLocationProvider,
|
||||
nsIDirectoryServiceProvider,
|
||||
nsIDirectoryServiceProvider2)
|
||||
|
||||
//*****************************************************************************
|
||||
// nsAppFileLocationProvider::nsIDirectoryServiceProvider
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
|
||||
nsAppFileLocationProvider::GetFile(const char* aProp, bool* aPersistent,
|
||||
nsIFile** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!prop))
|
||||
if (NS_WARN_IF(!aProp)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = nullptr;
|
||||
*persistent = true;
|
||||
*aResult = nullptr;
|
||||
*aPersistent = true;
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
FSRef fileRef;
|
||||
nsCOMPtr<nsILocalFileMac> macFile;
|
||||
#endif
|
||||
|
||||
if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
|
||||
{
|
||||
if (nsCRT::strcmp(aProp, NS_APP_APPLICATION_REGISTRY_DIR) == 0) {
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_APPLICATION_REGISTRY_FILE) == 0) {
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendNative(APP_REGISTRY_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
|
||||
{
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
|
||||
{
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_DEFAULTS_50_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_PREF_DEFAULTS_50_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
|
||||
nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
|
||||
nsCRT::strcmp(aProp, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_USER_PROFILES_ROOT_DIR) == 0) {
|
||||
rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0) {
|
||||
rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_RES_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
|
||||
{
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_CHROME_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
|
||||
{
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_PLUGINS_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
|
||||
}
|
||||
}
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
|
||||
{
|
||||
else if (nsCRT::strcmp(aProp, NS_MACOSX_USER_PLUGIN_DIR) == 0) {
|
||||
if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
|
||||
rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
localFile = macFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0) {
|
||||
if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
|
||||
rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
localFile = macFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0)
|
||||
{
|
||||
static const char *const java2PluginDirPath =
|
||||
} else if (nsCRT::strcmp(aProp, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0) {
|
||||
static const char* const java2PluginDirPath =
|
||||
"/System/Library/Java/Support/Deploy.bundle/Contents/Resources/";
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile));
|
||||
}
|
||||
#else
|
||||
else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
|
||||
{
|
||||
else if (nsCRT::strcmp(aProp, NS_ENV_PLUGINS_DIR) == 0) {
|
||||
NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
|
||||
"Use nsAppFileLocationProvider::GetFiles(...).");
|
||||
const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
|
||||
const char* pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
|
||||
if (pathVar && *pathVar)
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true,
|
||||
getter_AddRefs(localFile));
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
|
||||
{
|
||||
} else if (nsCRT::strcmp(aProp, NS_USER_PLUGINS_DIR) == 0) {
|
||||
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
|
||||
}
|
||||
#else
|
||||
rv = NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
#ifdef XP_UNIX
|
||||
else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) {
|
||||
else if (nsCRT::strcmp(aProp, NS_SYSTEM_PLUGINS_DIR) == 0) {
|
||||
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS
|
||||
static const char *const sysLPlgDir =
|
||||
static const char* const sysLPlgDir =
|
||||
#if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__)
|
||||
"/usr/lib64/mozilla/plugins";
|
||||
#elif defined(__OpenBSD__) || defined (__FreeBSD__)
|
||||
|
@ -221,61 +208,65 @@ nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile *
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
|
||||
{
|
||||
else if (nsCRT::strcmp(aProp, NS_APP_SEARCH_DIR) == 0) {
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0)
|
||||
{
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = (*_retval)->AppendNative(SEARCH_DIR_NAME);
|
||||
}
|
||||
else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
|
||||
{
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_USER_SEARCH_DIR) == 0) {
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = (*aResult)->AppendNative(SEARCH_DIR_NAME);
|
||||
}
|
||||
} else if (nsCRT::strcmp(aProp, NS_APP_INSTALL_CLEANUP_DIR) == 0) {
|
||||
// This is cloned so that embeddors will have a hook to override
|
||||
// with their own cleanup dir. See bugzilla bug #105087
|
||||
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
|
||||
if (localFile && NS_SUCCEEDED(rv))
|
||||
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
|
||||
if (localFile && NS_SUCCEEDED(rv)) {
|
||||
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile)
|
||||
NS_METHOD
|
||||
nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile)
|
||||
{
|
||||
if (NS_WARN_IF(!aLocalFile))
|
||||
if (NS_WARN_IF(!aLocalFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsresult rv;
|
||||
|
||||
if (!mMozBinDirectory)
|
||||
{
|
||||
if (!mMozBinDirectory) {
|
||||
// Get the mozilla bin directory
|
||||
// 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
|
||||
// This will be set if a directory was passed to NS_InitXPCOM
|
||||
// 2. If that doesn't work, set it to be the current process directory
|
||||
nsCOMPtr<nsIProperties>
|
||||
directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(mMozBinDirectory));
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(mMozBinDirectory));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> aFile;
|
||||
rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aLocalFile = aFile);
|
||||
return NS_OK;
|
||||
|
@ -289,10 +280,13 @@ NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile)
|
|||
// WIN : <Application Data folder on user's machine>\Mozilla
|
||||
// Mac : :Documents:Mozilla:
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, bool aLocal)
|
||||
NS_METHOD
|
||||
nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
|
||||
bool aLocal)
|
||||
{
|
||||
if (NS_WARN_IF(!aLocalFile))
|
||||
if (NS_WARN_IF(!aLocalFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
bool exists;
|
||||
|
@ -302,34 +296,51 @@ NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, b
|
|||
FSRef fsRef;
|
||||
OSType folderType = aLocal ? (OSType) kCachedDataFolderType : (OSType) kDomainLibraryFolderType;
|
||||
OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
|
||||
if (err) return NS_ERROR_FAILURE;
|
||||
if (err) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_NewLocalFile(EmptyString(), true, getter_AddRefs(localDir));
|
||||
if (!localDir) return NS_ERROR_FAILURE;
|
||||
if (!localDir) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
|
||||
rv = localDirMac->InitWithFSRef(&fsRef);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
nsCOMPtr<nsIProperties> directoryService =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR;
|
||||
rv = directoryService->Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(localDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
#elif defined(XP_UNIX)
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true, getter_AddRefs(localDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
#else
|
||||
#error dont_know_how_to_get_product_dir_on_your_platform
|
||||
#endif
|
||||
|
||||
rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = localDir->Exists(&exists);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !exists)
|
||||
if (NS_SUCCEEDED(rv) && !exists) {
|
||||
rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aLocalFile = localDir;
|
||||
NS_ADDREF(*aLocalFile);
|
||||
|
@ -345,27 +356,37 @@ NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, b
|
|||
// WIN : <Application Data folder on user's machine>\Mozilla\Profiles
|
||||
// Mac : :Documents:Mozilla:Profiles:
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalFile, bool aLocal)
|
||||
NS_METHOD
|
||||
nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile** aLocalFile,
|
||||
bool aLocal)
|
||||
{
|
||||
if (NS_WARN_IF(!aLocalFile))
|
||||
if (NS_WARN_IF(!aLocalFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> localDir;
|
||||
|
||||
rv = GetProductDirectory(getter_AddRefs(localDir), aLocal);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN)
|
||||
// These 3 platforms share this part of the path - do them as one
|
||||
rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool exists;
|
||||
rv = localDir->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && !exists)
|
||||
if (NS_SUCCEEDED(rv) && !exists) {
|
||||
rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
*aLocalFile = localDir;
|
||||
|
@ -387,45 +408,47 @@ public:
|
|||
* aKeyList is a null-terminated list of properties which are provided by aProvider
|
||||
* They do not need to be publicly defined keys.
|
||||
*/
|
||||
nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
|
||||
nsAppDirectoryEnumerator(nsIDirectoryServiceProvider* aProvider,
|
||||
const char* aKeyList[]) :
|
||||
mProvider(aProvider),
|
||||
mCurrentKey(aKeyList)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD HasMoreElements(bool *result)
|
||||
NS_IMETHOD HasMoreElements(bool* aResult)
|
||||
{
|
||||
while (!mNext && *mCurrentKey)
|
||||
{
|
||||
while (!mNext && *mCurrentKey) {
|
||||
bool dontCare;
|
||||
nsCOMPtr<nsIFile> testFile;
|
||||
(void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
|
||||
// Don't return a file which does not exist.
|
||||
bool exists;
|
||||
if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
|
||||
if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists) {
|
||||
mNext = testFile;
|
||||
}
|
||||
}
|
||||
*result = mNext != nullptr;
|
||||
*aResult = mNext != nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetNext(nsISupports **result)
|
||||
NS_IMETHOD GetNext(nsISupports** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!result))
|
||||
if (NS_WARN_IF(!aResult)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*result = nullptr;
|
||||
}
|
||||
*aResult = nullptr;
|
||||
|
||||
bool hasMore;
|
||||
HasMoreElements(&hasMore);
|
||||
if (!hasMore)
|
||||
if (!hasMore) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*result = mNext;
|
||||
NS_IF_ADDREF(*result);
|
||||
*aResult = mNext;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
mNext = nullptr;
|
||||
|
||||
return *result ? NS_OK : NS_ERROR_FAILURE;
|
||||
return *aResult ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Virtual destructor since subclass nsPathsDirectoryEnumerator
|
||||
|
@ -436,7 +459,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
nsIDirectoryServiceProvider *mProvider;
|
||||
nsIDirectoryServiceProvider* mProvider;
|
||||
const char** mCurrentKey;
|
||||
nsCOMPtr<nsIFile> mNext;
|
||||
};
|
||||
|
@ -461,60 +484,67 @@ public:
|
|||
* The remainder are properties provided by aProvider.
|
||||
* They do not need to be publicly defined keys.
|
||||
*/
|
||||
nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
|
||||
nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider* aProvider,
|
||||
const char* aKeyList[]) :
|
||||
nsAppDirectoryEnumerator(aProvider, aKeyList+1),
|
||||
nsAppDirectoryEnumerator(aProvider, aKeyList + 1),
|
||||
mEndPath(aKeyList[0])
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD HasMoreElements(bool *result)
|
||||
NS_IMETHOD HasMoreElements(bool* aResult)
|
||||
{
|
||||
if (mEndPath)
|
||||
while (!mNext && *mEndPath)
|
||||
{
|
||||
const char *pathVar = mEndPath;
|
||||
while (!mNext && *mEndPath) {
|
||||
const char* pathVar = mEndPath;
|
||||
|
||||
// skip PATH_SEPARATORs at the begining of the mEndPath
|
||||
while (*pathVar == PATH_SEPARATOR) pathVar++;
|
||||
while (*pathVar == PATH_SEPARATOR) {
|
||||
++pathVar;
|
||||
}
|
||||
|
||||
do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
|
||||
do {
|
||||
++mEndPath;
|
||||
} while (*mEndPath && *mEndPath != PATH_SEPARATOR);
|
||||
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
|
||||
true,
|
||||
getter_AddRefs(localFile));
|
||||
if (*mEndPath == PATH_SEPARATOR)
|
||||
if (*mEndPath == PATH_SEPARATOR) {
|
||||
++mEndPath;
|
||||
}
|
||||
// Don't return a "file" (directory) which does not exist.
|
||||
bool exists;
|
||||
if (localFile &&
|
||||
NS_SUCCEEDED(localFile->Exists(&exists)) &&
|
||||
exists)
|
||||
exists) {
|
||||
mNext = localFile;
|
||||
}
|
||||
}
|
||||
if (mNext)
|
||||
*result = true;
|
||||
else
|
||||
nsAppDirectoryEnumerator::HasMoreElements(result);
|
||||
if (mNext) {
|
||||
*aResult = true;
|
||||
} else {
|
||||
nsAppDirectoryEnumerator::HasMoreElements(aResult);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
const char *mEndPath;
|
||||
const char* mEndPath;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
|
||||
nsAppFileLocationProvider::GetFiles(const char* aProp,
|
||||
nsISimpleEnumerator** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!_retval))
|
||||
if (NS_WARN_IF(!aResult)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*_retval = nullptr;
|
||||
}
|
||||
*aResult = nullptr;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
|
||||
{
|
||||
if (!nsCRT::strcmp(aProp, NS_APP_PLUGINS_DIR_LIST)) {
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
// As of Java for Mac OS X 10.5 Update 10, Apple has (in effect) deprecated Java Plugin2 on
|
||||
// on OS X 10.5, and removed the soft link to it from /Library/Internet Plug-Ins/. Java
|
||||
|
@ -523,10 +553,14 @@ nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_ret
|
|||
// location where it actually is. Safari can use the WebKit-specific JavaPluginCocoa.bundle,
|
||||
// which (of course) is still fully supported on OS X 10.5. But we have no alternative to
|
||||
// using Java Plugin2. For more information see bug 668639.
|
||||
static const char* keys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR,
|
||||
NS_MACOSX_LOCAL_PLUGIN_DIR,
|
||||
IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nullptr, nullptr };
|
||||
*_retval = new nsAppDirectoryEnumerator(this, keys);
|
||||
static const char* keys[] = {
|
||||
NS_APP_PLUGINS_DIR,
|
||||
NS_MACOSX_USER_PLUGIN_DIR,
|
||||
NS_MACOSX_LOCAL_PLUGIN_DIR,
|
||||
IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nullptr,
|
||||
nullptr
|
||||
};
|
||||
*aResult = new nsAppDirectoryEnumerator(this, keys);
|
||||
#else
|
||||
#ifdef XP_UNIX
|
||||
static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nullptr };
|
||||
|
@ -537,21 +571,20 @@ nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_ret
|
|||
static const char nullstr = 0;
|
||||
keys[0] = &nullstr;
|
||||
}
|
||||
*_retval = new nsPathsDirectoryEnumerator(this, keys);
|
||||
*aResult = new nsPathsDirectoryEnumerator(this, keys);
|
||||
#endif
|
||||
NS_IF_ADDREF(*_retval);
|
||||
rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
rv = *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST))
|
||||
{
|
||||
if (!nsCRT::strcmp(aProp, NS_APP_SEARCH_DIR_LIST)) {
|
||||
static const char* keys[] = { nullptr, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nullptr };
|
||||
if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) {
|
||||
static const char nullstr = 0;
|
||||
keys[0] = &nullstr;
|
||||
}
|
||||
*_retval = new nsPathsDirectoryEnumerator(this, keys);
|
||||
NS_IF_ADDREF(*_retval);
|
||||
rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
*aResult = new nsPathsDirectoryEnumerator(this, keys);
|
||||
NS_IF_ADDREF(*aResult);
|
||||
rv = *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ public:
|
|||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
|
||||
private:
|
||||
~nsAppFileLocationProvider() {}
|
||||
~nsAppFileLocationProvider()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
NS_METHOD CloneMozBinDirectory(nsIFile **aLocalFile);
|
||||
NS_METHOD CloneMozBinDirectory(nsIFile** aLocalFile);
|
||||
/**
|
||||
* Get the product directory. This is a user-specific directory for storing
|
||||
* application settings (e.g. the Application Data directory on windows
|
||||
|
@ -38,9 +40,9 @@ protected:
|
|||
* @param aLocal If true, should try to get a directory that is only stored
|
||||
* locally (ie not transferred with roaming profiles)
|
||||
*/
|
||||
NS_METHOD GetProductDirectory(nsIFile **aLocalFile,
|
||||
NS_METHOD GetProductDirectory(nsIFile** aLocalFile,
|
||||
bool aLocal = false);
|
||||
NS_METHOD GetDefaultUserProfileRoot(nsIFile **aLocalFile,
|
||||
NS_METHOD GetDefaultUserProfileRoot(nsIFile** aLocalFile,
|
||||
bool aLocal = false);
|
||||
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
|
|
|
@ -30,75 +30,90 @@
|
|||
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsBinaryOutputStream, nsIObjectOutputStream, nsIBinaryOutputStream, nsIOutputStream)
|
||||
NS_IMPL_ISUPPORTS(nsBinaryOutputStream,
|
||||
nsIObjectOutputStream,
|
||||
nsIBinaryOutputStream,
|
||||
nsIOutputStream)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Flush()
|
||||
{
|
||||
if (NS_WARN_IF(!mOutputStream))
|
||||
if (NS_WARN_IF(!mOutputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mOutputStream->Flush();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Close()
|
||||
{
|
||||
if (NS_WARN_IF(!mOutputStream))
|
||||
if (NS_WARN_IF(!mOutputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mOutputStream->Close();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Write(const char *aBuf, uint32_t aCount, uint32_t *aActualBytes)
|
||||
nsBinaryOutputStream::Write(const char* aBuf, uint32_t aCount,
|
||||
uint32_t* aActualBytes)
|
||||
{
|
||||
if (NS_WARN_IF(!mOutputStream))
|
||||
if (NS_WARN_IF(!mOutputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mOutputStream->Write(aBuf, aCount, aActualBytes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteFrom(nsIInputStream *inStr, uint32_t count, uint32_t *_retval)
|
||||
nsBinaryOutputStream::WriteFrom(nsIInputStream* aInStr, uint32_t aCount,
|
||||
uint32_t* aResult)
|
||||
{
|
||||
NS_NOTREACHED("WriteFrom");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, uint32_t count, uint32_t *_retval)
|
||||
nsBinaryOutputStream::WriteSegments(nsReadSegmentFun aReader, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
NS_NOTREACHED("WriteSegments");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsBinaryOutputStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
if (NS_WARN_IF(!mOutputStream))
|
||||
if (NS_WARN_IF(!mOutputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mOutputStream->IsNonBlocking(aNonBlocking);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBinaryOutputStream::WriteFully(const char *aBuf, uint32_t aCount)
|
||||
nsBinaryOutputStream::WriteFully(const char* aBuf, uint32_t aCount)
|
||||
{
|
||||
if (NS_WARN_IF(!mOutputStream))
|
||||
if (NS_WARN_IF(!mOutputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
uint32_t bytesWritten;
|
||||
|
||||
rv = mOutputStream->Write(aBuf, aCount, &bytesWritten);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesWritten != aCount)
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesWritten != aCount) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::SetOutputStream(nsIOutputStream *aOutputStream)
|
||||
nsBinaryOutputStream::SetOutputStream(nsIOutputStream* aOutputStream)
|
||||
{
|
||||
if (NS_WARN_IF(!aOutputStream))
|
||||
if (NS_WARN_IF(!aOutputStream)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mOutputStream = aOutputStream;
|
||||
mBufferAccess = do_QueryInterface(aOutputStream);
|
||||
return NS_OK;
|
||||
|
@ -113,41 +128,44 @@ nsBinaryOutputStream::WriteBoolean(bool aBoolean)
|
|||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Write8(uint8_t aByte)
|
||||
{
|
||||
return WriteFully((const char*)&aByte, sizeof aByte);
|
||||
return WriteFully((const char*)&aByte, sizeof(aByte));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Write16(uint16_t a16)
|
||||
nsBinaryOutputStream::Write16(uint16_t aNum)
|
||||
{
|
||||
a16 = mozilla::NativeEndian::swapToBigEndian(a16);
|
||||
return WriteFully((const char*)&a16, sizeof a16);
|
||||
aNum = mozilla::NativeEndian::swapToBigEndian(aNum);
|
||||
return WriteFully((const char*)&aNum, sizeof(aNum));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Write32(uint32_t a32)
|
||||
nsBinaryOutputStream::Write32(uint32_t aNum)
|
||||
{
|
||||
a32 = mozilla::NativeEndian::swapToBigEndian(a32);
|
||||
return WriteFully((const char*)&a32, sizeof a32);
|
||||
aNum = mozilla::NativeEndian::swapToBigEndian(aNum);
|
||||
return WriteFully((const char*)&aNum, sizeof(aNum));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::Write64(uint64_t a64)
|
||||
nsBinaryOutputStream::Write64(uint64_t aNum)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesWritten;
|
||||
|
||||
a64 = mozilla::NativeEndian::swapToBigEndian(a64);
|
||||
rv = Write(reinterpret_cast<char*>(&a64), sizeof a64, &bytesWritten);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesWritten != sizeof a64)
|
||||
aNum = mozilla::NativeEndian::swapToBigEndian(aNum);
|
||||
rv = Write(reinterpret_cast<char*>(&aNum), sizeof(aNum), &bytesWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesWritten != sizeof(aNum)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteFloat(float aFloat)
|
||||
{
|
||||
NS_ASSERTION(sizeof(float) == sizeof (uint32_t),
|
||||
NS_ASSERTION(sizeof(float) == sizeof(uint32_t),
|
||||
"False assumption about sizeof(float)");
|
||||
return Write32(*reinterpret_cast<uint32_t*>(&aFloat));
|
||||
}
|
||||
|
@ -161,14 +179,16 @@ nsBinaryOutputStream::WriteDouble(double aDouble)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteStringZ(const char *aString)
|
||||
nsBinaryOutputStream::WriteStringZ(const char* aString)
|
||||
{
|
||||
uint32_t length;
|
||||
nsresult rv;
|
||||
|
||||
length = strlen(aString);
|
||||
rv = Write32(length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return WriteFully(aString, length);
|
||||
}
|
||||
|
||||
|
@ -180,29 +200,35 @@ nsBinaryOutputStream::WriteWStringZ(const char16_t* aString)
|
|||
|
||||
length = NS_strlen(aString);
|
||||
rv = Write32(length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
if (length == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
byteCount = length * sizeof(char16_t);
|
||||
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
rv = WriteBytes(reinterpret_cast<const char*>(aString), byteCount);
|
||||
#else
|
||||
// XXX use WriteSegments here to avoid copy!
|
||||
char16_t *copy, temp[64];
|
||||
char16_t* copy;
|
||||
char16_t temp[64];
|
||||
if (length <= 64) {
|
||||
copy = temp;
|
||||
} else {
|
||||
copy = reinterpret_cast<char16_t*>(moz_malloc(byteCount));
|
||||
if (!copy)
|
||||
if (!copy) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION((uintptr_t(aString) & 0x1) == 0, "aString not properly aligned");
|
||||
mozilla::NativeEndian::copyAndSwapToBigEndian(copy, aString, length);
|
||||
rv = WriteBytes(reinterpret_cast<const char*>(copy), byteCount);
|
||||
if (copy != temp)
|
||||
if (copy != temp) {
|
||||
moz_free(copy);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
|
@ -215,22 +241,25 @@ nsBinaryOutputStream::WriteUtf8Z(const char16_t* aString)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteBytes(const char *aString, uint32_t aLength)
|
||||
nsBinaryOutputStream::WriteBytes(const char* aString, uint32_t aLength)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesWritten;
|
||||
|
||||
rv = Write(aString, aLength, &bytesWritten);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesWritten != aLength)
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesWritten != aLength) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryOutputStream::WriteByteArray(uint8_t *aBytes, uint32_t aLength)
|
||||
nsBinaryOutputStream::WriteByteArray(uint8_t* aBytes, uint32_t aLength)
|
||||
{
|
||||
return WriteBytes(reinterpret_cast<char *>(aBytes), aLength);
|
||||
return WriteBytes(reinterpret_cast<char*>(aBytes), aLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -256,17 +285,19 @@ nsBinaryOutputStream::WriteCompoundObject(nsISupports* aObject,
|
|||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aObject);
|
||||
|
||||
// Can't deal with weak refs
|
||||
if (NS_WARN_IF(!aIsStrongRef))
|
||||
if (NS_WARN_IF(!aIsStrongRef)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
if (NS_WARN_IF(!classInfo) || NS_WARN_IF(!serializable))
|
||||
}
|
||||
if (NS_WARN_IF(!classInfo) || NS_WARN_IF(!serializable)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCID cid;
|
||||
nsresult rv = classInfo->GetClassIDNoAlloc(&cid);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = WriteID(cid);
|
||||
} else {
|
||||
nsCID *cidptr = nullptr;
|
||||
nsCID* cidptr = nullptr;
|
||||
rv = classInfo->GetClassID(&cidptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
|
@ -277,12 +308,14 @@ nsBinaryOutputStream::WriteCompoundObject(nsISupports* aObject,
|
|||
NS_Free(cidptr);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = WriteID(aIID);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return serializable->Write(this);
|
||||
}
|
||||
|
@ -291,21 +324,25 @@ NS_IMETHODIMP
|
|||
nsBinaryOutputStream::WriteID(const nsIID& aIID)
|
||||
{
|
||||
nsresult rv = Write32(aIID.m0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Write16(aIID.m1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Write16(aIID.m2);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
rv = Write8(aIID.m3[i]);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -314,33 +351,40 @@ nsBinaryOutputStream::WriteID(const nsIID& aIID)
|
|||
NS_IMETHODIMP_(char*)
|
||||
nsBinaryOutputStream::GetBuffer(uint32_t aLength, uint32_t aAlignMask)
|
||||
{
|
||||
if (mBufferAccess)
|
||||
if (mBufferAccess) {
|
||||
return mBufferAccess->GetBuffer(aLength, aAlignMask);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsBinaryOutputStream::PutBuffer(char* aBuffer, uint32_t aLength)
|
||||
{
|
||||
if (mBufferAccess)
|
||||
if (mBufferAccess) {
|
||||
mBufferAccess->PutBuffer(aBuffer, aLength);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsBinaryInputStream, nsIObjectInputStream, nsIBinaryInputStream, nsIInputStream)
|
||||
NS_IMPL_ISUPPORTS(nsBinaryInputStream,
|
||||
nsIObjectInputStream,
|
||||
nsIBinaryInputStream,
|
||||
nsIInputStream)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Available(uint64_t* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!mInputStream))
|
||||
if (NS_WARN_IF(!mInputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mInputStream->Available(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t *aNumRead)
|
||||
nsBinaryInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aNumRead)
|
||||
{
|
||||
if (NS_WARN_IF(!mInputStream))
|
||||
if (NS_WARN_IF(!mInputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// mInputStream might give us short reads, so deal with that.
|
||||
uint32_t totalRead = 0;
|
||||
|
@ -373,7 +417,8 @@ nsBinaryInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t *aNumRead)
|
|||
// a thunking function which keeps the real input stream around.
|
||||
|
||||
// the closure wrapper
|
||||
struct ReadSegmentsClosure {
|
||||
struct ReadSegmentsClosure
|
||||
{
|
||||
nsIInputStream* mRealInputStream;
|
||||
void* mRealClosure;
|
||||
nsWriteSegmentFun mRealWriter;
|
||||
|
@ -384,11 +429,11 @@ struct ReadSegmentsClosure {
|
|||
// the thunking function
|
||||
static NS_METHOD
|
||||
ReadSegmentForwardingThunk(nsIInputStream* aStream,
|
||||
void *aClosure,
|
||||
void* aClosure,
|
||||
const char* aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount)
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
ReadSegmentsClosure* thunkClosure =
|
||||
reinterpret_cast<ReadSegmentsClosure*>(aClosure);
|
||||
|
@ -408,19 +453,21 @@ ReadSegmentForwardingThunk(nsIInputStream* aStream,
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uint32_t count, uint32_t *_retval)
|
||||
nsBinaryInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!mInputStream))
|
||||
if (NS_WARN_IF(!mInputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ReadSegmentsClosure thunkClosure = { this, closure, writer, NS_OK, 0 };
|
||||
ReadSegmentsClosure thunkClosure = { this, aClosure, aWriter, NS_OK, 0 };
|
||||
|
||||
// mInputStream might give us short reads, so deal with that.
|
||||
uint32_t bytesRead;
|
||||
do {
|
||||
nsresult rv = mInputStream->ReadSegments(ReadSegmentForwardingThunk,
|
||||
&thunkClosure,
|
||||
count, &bytesRead);
|
||||
aCount, &bytesRead);
|
||||
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK && thunkClosure.mBytesRead != 0) {
|
||||
// We already read some data. Return it.
|
||||
|
@ -432,36 +479,39 @@ nsBinaryInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uint
|
|||
}
|
||||
|
||||
thunkClosure.mBytesRead += bytesRead;
|
||||
count -= bytesRead;
|
||||
} while (count != 0 && bytesRead != 0 &&
|
||||
aCount -= bytesRead;
|
||||
} while (aCount != 0 && bytesRead != 0 &&
|
||||
NS_SUCCEEDED(thunkClosure.mRealResult));
|
||||
|
||||
*_retval = thunkClosure.mBytesRead;
|
||||
*aResult = thunkClosure.mBytesRead;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsBinaryInputStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
if (NS_WARN_IF(!mInputStream))
|
||||
if (NS_WARN_IF(!mInputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mInputStream->IsNonBlocking(aNonBlocking);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Close()
|
||||
{
|
||||
if (NS_WARN_IF(!mInputStream))
|
||||
if (NS_WARN_IF(!mInputStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mInputStream->Close();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::SetInputStream(nsIInputStream *aInputStream)
|
||||
nsBinaryInputStream::SetInputStream(nsIInputStream* aInputStream)
|
||||
{
|
||||
if (NS_WARN_IF(!aInputStream))
|
||||
if (NS_WARN_IF(!aInputStream)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mInputStream = aInputStream;
|
||||
mBufferAccess = do_QueryInterface(aInputStream);
|
||||
return NS_OK;
|
||||
|
@ -472,7 +522,9 @@ nsBinaryInputStream::ReadBoolean(bool* aBoolean)
|
|||
{
|
||||
uint8_t byteResult;
|
||||
nsresult rv = Read8(&byteResult);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
*aBoolean = !!byteResult;
|
||||
return rv;
|
||||
}
|
||||
|
@ -484,58 +536,64 @@ nsBinaryInputStream::Read8(uint8_t* aByte)
|
|||
uint32_t bytesRead;
|
||||
|
||||
rv = Read(reinterpret_cast<char*>(aByte), sizeof(*aByte), &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesRead != 1)
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesRead != 1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Read16(uint16_t* a16)
|
||||
nsBinaryInputStream::Read16(uint16_t* aNum)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesRead;
|
||||
|
||||
rv = Read(reinterpret_cast<char*>(a16), sizeof *a16, &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesRead != sizeof *a16)
|
||||
nsresult rv = Read(reinterpret_cast<char*>(aNum), sizeof(*aNum), &bytesRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesRead != sizeof(*aNum)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
*a16 = mozilla::NativeEndian::swapFromBigEndian(*a16);
|
||||
}
|
||||
*aNum = mozilla::NativeEndian::swapFromBigEndian(*aNum);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Read32(uint32_t* a32)
|
||||
nsBinaryInputStream::Read32(uint32_t* aNum)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesRead;
|
||||
|
||||
rv = Read(reinterpret_cast<char*>(a32), sizeof *a32, &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesRead != sizeof *a32)
|
||||
nsresult rv = Read(reinterpret_cast<char*>(aNum), sizeof(*aNum), &bytesRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesRead != sizeof(*aNum)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
*a32 = mozilla::NativeEndian::swapFromBigEndian(*a32);
|
||||
}
|
||||
*aNum = mozilla::NativeEndian::swapFromBigEndian(*aNum);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::Read64(uint64_t* a64)
|
||||
nsBinaryInputStream::Read64(uint64_t* aNum)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesRead;
|
||||
|
||||
rv = Read(reinterpret_cast<char*>(a64), sizeof *a64, &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (bytesRead != sizeof *a64)
|
||||
nsresult rv = Read(reinterpret_cast<char*>(aNum), sizeof(*aNum), &bytesRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesRead != sizeof(*aNum)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
*a64 = mozilla::NativeEndian::swapFromBigEndian(*a64);
|
||||
}
|
||||
*aNum = mozilla::NativeEndian::swapFromBigEndian(*aNum);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadFloat(float* aFloat)
|
||||
{
|
||||
NS_ASSERTION(sizeof(float) == sizeof (uint32_t),
|
||||
NS_ASSERTION(sizeof(float) == sizeof(uint32_t),
|
||||
"False assumption about sizeof(float)");
|
||||
return Read32(reinterpret_cast<uint32_t*>(aFloat));
|
||||
}
|
||||
|
@ -550,11 +608,11 @@ nsBinaryInputStream::ReadDouble(double* aDouble)
|
|||
|
||||
static NS_METHOD
|
||||
WriteSegmentToCString(nsIInputStream* aStream,
|
||||
void *aClosure,
|
||||
void* aClosure,
|
||||
const char* aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount)
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
nsACString* outString = static_cast<nsACString*>(aClosure);
|
||||
|
||||
|
@ -572,14 +630,19 @@ nsBinaryInputStream::ReadCString(nsACString& aString)
|
|||
uint32_t length, bytesRead;
|
||||
|
||||
rv = Read32(&length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
aString.Truncate();
|
||||
rv = ReadSegments(WriteSegmentToCString, &aString, length, &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (bytesRead != length)
|
||||
if (bytesRead != length) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -587,8 +650,9 @@ nsBinaryInputStream::ReadCString(nsACString& aString)
|
|||
|
||||
// sometimes, WriteSegmentToString will be handed an odd-number of
|
||||
// bytes, which means we only have half of the last char16_t
|
||||
struct WriteStringClosure {
|
||||
char16_t *mWriteCursor;
|
||||
struct WriteStringClosure
|
||||
{
|
||||
char16_t* mWriteCursor;
|
||||
bool mHasCarryoverByte;
|
||||
char mCarryoverByte;
|
||||
};
|
||||
|
@ -611,17 +675,17 @@ struct WriteStringClosure {
|
|||
// same version of the above, but with correct casting and endian swapping
|
||||
static NS_METHOD
|
||||
WriteSegmentToString(nsIInputStream* aStream,
|
||||
void *aClosure,
|
||||
void* aClosure,
|
||||
const char* aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount)
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
NS_PRECONDITION(aCount > 0, "Why are we being told to write 0 bytes?");
|
||||
NS_PRECONDITION(sizeof(char16_t) == 2, "We can't handle other sizes!");
|
||||
|
||||
WriteStringClosure* closure = static_cast<WriteStringClosure*>(aClosure);
|
||||
char16_t *cursor = closure->mWriteCursor;
|
||||
char16_t* cursor = closure->mWriteCursor;
|
||||
|
||||
// we're always going to consume the whole buffer no matter what
|
||||
// happens, so take care of that right now.. that allows us to
|
||||
|
@ -647,7 +711,7 @@ WriteSegmentToString(nsIInputStream* aStream,
|
|||
}
|
||||
|
||||
// this array is possibly unaligned... be careful how we access it!
|
||||
const char16_t *unicodeSegment =
|
||||
const char16_t* unicodeSegment =
|
||||
reinterpret_cast<const char16_t*>(aFromSegment);
|
||||
|
||||
// calculate number of full characters in segment (aCount could be odd!)
|
||||
|
@ -656,7 +720,7 @@ WriteSegmentToString(nsIInputStream* aStream,
|
|||
// copy all data into our aligned buffer. byte swap if necessary.
|
||||
// cursor may be unaligned, so we cannot use copyAndSwapToBigEndian directly
|
||||
memcpy(cursor, unicodeSegment, segmentLength * sizeof(char16_t));
|
||||
char16_t *end = cursor + segmentLength;
|
||||
char16_t* end = cursor + segmentLength;
|
||||
mozilla::NativeEndian::swapToBigEndianInPlace(cursor, segmentLength);
|
||||
closure->mWriteCursor = end;
|
||||
|
||||
|
@ -681,7 +745,9 @@ nsBinaryInputStream::ReadString(nsAString& aString)
|
|||
uint32_t length, bytesRead;
|
||||
|
||||
rv = Read32(&length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
aString.Truncate();
|
||||
|
@ -689,8 +755,9 @@ nsBinaryInputStream::ReadString(nsAString& aString)
|
|||
}
|
||||
|
||||
// pre-allocate output buffer, and get direct access to buffer...
|
||||
if (!aString.SetLength(length, mozilla::fallible_t()))
|
||||
if (!aString.SetLength(length, mozilla::fallible_t())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsAString::iterator start;
|
||||
aString.BeginWriting(start);
|
||||
|
@ -700,27 +767,31 @@ nsBinaryInputStream::ReadString(nsAString& aString)
|
|||
closure.mHasCarryoverByte = false;
|
||||
|
||||
rv = ReadSegments(WriteSegmentToString, &closure,
|
||||
length*sizeof(char16_t), &bytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
length * sizeof(char16_t), &bytesRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!closure.mHasCarryoverByte, "some strange stream corruption!");
|
||||
|
||||
if (bytesRead != length*sizeof(char16_t))
|
||||
if (bytesRead != length * sizeof(char16_t)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadBytes(uint32_t aLength, char* *_rval)
|
||||
nsBinaryInputStream::ReadBytes(uint32_t aLength, char** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t bytesRead;
|
||||
char* s;
|
||||
|
||||
s = reinterpret_cast<char*>(moz_malloc(aLength));
|
||||
if (!s)
|
||||
if (!s) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = Read(s, aLength, &bytesRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -732,36 +803,39 @@ nsBinaryInputStream::ReadBytes(uint32_t aLength, char* *_rval)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*_rval = s;
|
||||
*aResult = s;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadByteArray(uint32_t aLength, uint8_t* *_rval)
|
||||
nsBinaryInputStream::ReadByteArray(uint32_t aLength, uint8_t** aResult)
|
||||
{
|
||||
return ReadBytes(aLength, reinterpret_cast<char **>(_rval));
|
||||
return ReadBytes(aLength, reinterpret_cast<char**>(aResult));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, JS::Handle<JS::Value> aBuffer, JSContext* cx)
|
||||
nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength,
|
||||
JS::Handle<JS::Value> aBuffer,
|
||||
JSContext* aCx)
|
||||
{
|
||||
if (!aBuffer.isObject()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
JS::RootedObject buffer(cx, &aBuffer.toObject());
|
||||
JS::RootedObject buffer(aCx, &aBuffer.toObject());
|
||||
if (!JS_IsArrayBufferObject(buffer) ||
|
||||
JS_GetArrayBufferByteLength(buffer) < aLength) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
uint8_t* data = JS_GetStableArrayBufferData(cx, buffer);
|
||||
uint8_t* data = JS_GetStableArrayBufferData(aCx, buffer);
|
||||
if (!data) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t bytesRead;
|
||||
nsresult rv = Read(reinterpret_cast<char*>(data), aLength, &bytesRead);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (bytesRead != aLength) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -769,35 +843,40 @@ nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, JS::Handle<JS::Value> aBu
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadObject(bool aIsStrongRef, nsISupports* *aObject)
|
||||
nsBinaryInputStream::ReadObject(bool aIsStrongRef, nsISupports** aObject)
|
||||
{
|
||||
nsCID cid;
|
||||
nsIID iid;
|
||||
nsresult rv = ReadID(&cid);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = ReadID(&iid);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// HACK: Intercept old (pre-gecko6) nsIURI IID, and replace with
|
||||
// the updated IID, so that we're QI'ing to an actual interface.
|
||||
// (As soon as we drop support for upgrading from pre-gecko6, we can
|
||||
// remove this chunk.)
|
||||
static const nsIID oldURIiid =
|
||||
{ 0x7a22cc0, 0xce5, 0x11d3,
|
||||
{ 0x93, 0x31, 0x0, 0x10, 0x4b, 0xa0, 0xfd, 0x40 }};
|
||||
static const nsIID oldURIiid = {
|
||||
0x7a22cc0, 0xce5, 0x11d3,
|
||||
{ 0x93, 0x31, 0x0, 0x10, 0x4b, 0xa0, 0xfd, 0x40 }
|
||||
};
|
||||
|
||||
// hackaround for bug 670542
|
||||
static const nsIID oldURIiid2 =
|
||||
{ 0xd6d04c36, 0x0fa4, 0x4db3,
|
||||
{ 0xbe, 0x05, 0x4a, 0x18, 0x39, 0x71, 0x03, 0xe2 }};
|
||||
static const nsIID oldURIiid2 = {
|
||||
0xd6d04c36, 0x0fa4, 0x4db3,
|
||||
{ 0xbe, 0x05, 0x4a, 0x18, 0x39, 0x71, 0x03, 0xe2 }
|
||||
};
|
||||
|
||||
// hackaround for bug 682031
|
||||
static const nsIID oldURIiid3 =
|
||||
{ 0x12120b20, 0x0929, 0x40e9,
|
||||
{ 0x88, 0xcf, 0x6e, 0x08, 0x76, 0x6e, 0x8b, 0x23 }};
|
||||
static const nsIID oldURIiid3 = {
|
||||
0x12120b20, 0x0929, 0x40e9,
|
||||
{ 0x88, 0xcf, 0x6e, 0x08, 0x76, 0x6e, 0x8b, 0x23 }
|
||||
};
|
||||
|
||||
if (iid.Equals(oldURIiid) ||
|
||||
iid.Equals(oldURIiid2) ||
|
||||
|
@ -808,39 +887,46 @@ nsBinaryInputStream::ReadObject(bool aIsStrongRef, nsISupports* *aObject)
|
|||
// END HACK
|
||||
|
||||
nsCOMPtr<nsISupports> object = do_CreateInstance(cid, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(object);
|
||||
if (NS_WARN_IF(!serializable))
|
||||
if (NS_WARN_IF(!serializable)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
rv = serializable->Read(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return object->QueryInterface(iid, reinterpret_cast<void**>(aObject));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBinaryInputStream::ReadID(nsID *aResult)
|
||||
nsBinaryInputStream::ReadID(nsID* aResult)
|
||||
{
|
||||
nsresult rv = Read32(&aResult->m0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Read16(&aResult->m1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Read16(&aResult->m2);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
rv = Read8(&aResult->m3[i]);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -849,14 +935,16 @@ nsBinaryInputStream::ReadID(nsID *aResult)
|
|||
NS_IMETHODIMP_(char*)
|
||||
nsBinaryInputStream::GetBuffer(uint32_t aLength, uint32_t aAlignMask)
|
||||
{
|
||||
if (mBufferAccess)
|
||||
if (mBufferAccess) {
|
||||
return mBufferAccess->GetBuffer(aLength, aAlignMask);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsBinaryInputStream::PutBuffer(char* aBuffer, uint32_t aLength)
|
||||
{
|
||||
if (mBufferAccess)
|
||||
if (mBufferAccess) {
|
||||
mBufferAccess->PutBuffer(aBuffer, aLength);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,13 @@
|
|||
class nsBinaryOutputStream : public nsIObjectOutputStream
|
||||
{
|
||||
public:
|
||||
nsBinaryOutputStream() {}
|
||||
nsBinaryOutputStream()
|
||||
{
|
||||
}
|
||||
// virtual dtor since subclasses call our Release()
|
||||
virtual ~nsBinaryOutputStream() {}
|
||||
virtual ~nsBinaryOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// nsISupports methods
|
||||
|
@ -46,7 +50,7 @@ protected:
|
|||
NS_DECL_NSIOBJECTOUTPUTSTREAM
|
||||
|
||||
// Call Write(), ensuring that all proffered data is written
|
||||
nsresult WriteFully(const char *aBuf, uint32_t aCount);
|
||||
nsresult WriteFully(const char* aBuf, uint32_t aCount);
|
||||
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
nsCOMPtr<nsIStreamBufferAccess> mBufferAccess;
|
||||
|
@ -67,9 +71,13 @@ protected:
|
|||
class nsBinaryInputStream : public nsIObjectInputStream
|
||||
{
|
||||
public:
|
||||
nsBinaryInputStream() {}
|
||||
nsBinaryInputStream()
|
||||
{
|
||||
}
|
||||
// virtual dtor since subclasses call our Release()
|
||||
virtual ~nsBinaryInputStream() {}
|
||||
virtual ~nsBinaryInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// nsISupports methods
|
||||
|
|
|
@ -55,13 +55,15 @@ nsresult
|
|||
nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (NS_WARN_IF(!aFile))
|
||||
if (NS_WARN_IF(!aFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*aFile = nullptr;
|
||||
|
||||
// Set the component registry location:
|
||||
if (!gService)
|
||||
if (!gService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
@ -69,15 +71,14 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
rv = nsDirectoryService::Create(nullptr,
|
||||
NS_GET_IID(nsIProperties),
|
||||
getter_AddRefs(dirService)); // needs to be around for life of product
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (dirService)
|
||||
{
|
||||
if (dirService) {
|
||||
nsCOMPtr <nsIFile> aLocalFile;
|
||||
dirService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(aLocalFile));
|
||||
if (aLocalFile)
|
||||
{
|
||||
if (aLocalFile) {
|
||||
*aFile = aLocalFile;
|
||||
NS_ADDREF(*aFile);
|
||||
return NS_OK;
|
||||
|
@ -85,13 +86,10 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
}
|
||||
|
||||
nsLocalFile* localFile = new nsLocalFile;
|
||||
|
||||
if (localFile == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(localFile);
|
||||
|
||||
|
||||
|
||||
#ifdef XP_WIN
|
||||
wchar_t buf[MAX_PATH + 1];
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
@ -99,8 +97,9 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
// chop off the executable name by finding the rightmost backslash
|
||||
wchar_t* lastSlash = wcsrchr(buf, L'\\');
|
||||
if (lastSlash)
|
||||
if (lastSlash) {
|
||||
*(lastSlash + 1) = L'\0';
|
||||
}
|
||||
|
||||
localFile->InitWithPath(nsDependentString(buf));
|
||||
*aFile = localFile;
|
||||
|
@ -110,26 +109,25 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
#elif defined(MOZ_WIDGET_COCOA)
|
||||
// Works even if we're not bundled.
|
||||
CFBundleRef appBundle = CFBundleGetMainBundle();
|
||||
if (appBundle != nullptr)
|
||||
{
|
||||
if (appBundle) {
|
||||
CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
|
||||
if (bundleURL != nullptr)
|
||||
{
|
||||
CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL);
|
||||
if (parentURL)
|
||||
{
|
||||
if (bundleURL) {
|
||||
CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(
|
||||
kCFAllocatorDefault, bundleURL);
|
||||
if (parentURL) {
|
||||
// Pass true for the "resolveAgainstBase" arg to CFURLGetFileSystemRepresentation.
|
||||
// This will resolve the relative portion of the CFURL against it base, giving a full
|
||||
// path, which CFURLCopyFileSystemPath doesn't do.
|
||||
char buffer[PATH_MAX];
|
||||
if (CFURLGetFileSystemRepresentation(parentURL, true, (UInt8 *)buffer, sizeof(buffer)))
|
||||
{
|
||||
if (CFURLGetFileSystemRepresentation(parentURL, true,
|
||||
(UInt8*)buffer, sizeof(buffer))) {
|
||||
#ifdef DEBUG_conrad
|
||||
printf("nsDirectoryService - CurrentProcessDir is: %s\n", buffer);
|
||||
#endif
|
||||
rv = localFile->InitWithNativePath(nsDependentCString(buffer));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aFile = localFile;
|
||||
}
|
||||
}
|
||||
CFRelease(parentURL);
|
||||
}
|
||||
|
@ -138,8 +136,9 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
}
|
||||
|
||||
NS_ASSERTION(*aFile, "nsDirectoryService - Could not determine CurrentProcessDir.\n");
|
||||
if (*aFile)
|
||||
if (*aFile) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
|
@ -159,16 +158,14 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
// We do this by putenv()ing the default value into the environment. Note that
|
||||
// we only do this if it is not already set.
|
||||
#ifdef MOZ_DEFAULT_MOZILLA_FIVE_HOME
|
||||
const char *home = PR_GetEnv("MOZILLA_FIVE_HOME");
|
||||
if (!home || !*home)
|
||||
{
|
||||
const char* home = PR_GetEnv("MOZILLA_FIVE_HOME");
|
||||
if (!home || !*home) {
|
||||
putenv("MOZILLA_FIVE_HOME=" MOZ_DEFAULT_MOZILLA_FIVE_HOME);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
|
||||
if (moz5 && *moz5)
|
||||
{
|
||||
char* moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
|
||||
if (moz5 && *moz5) {
|
||||
if (realpath(moz5, buf)) {
|
||||
localFile->InitWithNativePath(nsDependentCString(buf));
|
||||
*aFile = localFile;
|
||||
|
@ -178,7 +175,7 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
#if defined(DEBUG)
|
||||
static bool firstWarning = true;
|
||||
|
||||
if((!moz5 || !*moz5) && firstWarning) {
|
||||
if ((!moz5 || !*moz5) && firstWarning) {
|
||||
// Warn that MOZILLA_FIVE_HOME not set, once.
|
||||
printf("Warning: MOZILLA_FIVE_HOME not set.\n");
|
||||
firstWarning = false;
|
||||
|
@ -186,8 +183,7 @@ nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
|||
#endif /* DEBUG */
|
||||
|
||||
// Fall back to current directory.
|
||||
if (getcwd(buf, sizeof(buf)))
|
||||
{
|
||||
if (getcwd(buf, sizeof(buf))) {
|
||||
localFile->InitWithNativePath(nsDependentCString(buf));
|
||||
*aFile = localFile;
|
||||
return NS_OK;
|
||||
|
@ -209,15 +205,16 @@ nsDirectoryService::nsDirectoryService()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
|
||||
nsDirectoryService::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!aResult))
|
||||
if (NS_WARN_IF(!aResult)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
if (NS_WARN_IF(outer))
|
||||
}
|
||||
if (NS_WARN_IF(aOuter)) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
if (!gService)
|
||||
{
|
||||
if (!gService) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -256,7 +253,7 @@ nsDirectoryService::RealInit()
|
|||
NS_RegisterStaticAtoms(directory_atoms);
|
||||
|
||||
// Let the list hold the only reference to the provider.
|
||||
nsAppFileLocationProvider *defaultProvider = new nsAppFileLocationProvider;
|
||||
nsAppFileLocationProvider* defaultProvider = new nsAppFileLocationProvider;
|
||||
self->mProviders.AppendElement(defaultProvider);
|
||||
|
||||
self.swap(gService);
|
||||
|
@ -266,37 +263,44 @@ nsDirectoryService::~nsDirectoryService()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
||||
NS_IMPL_ISUPPORTS(nsDirectoryService,
|
||||
nsIProperties,
|
||||
nsIDirectoryService,
|
||||
nsIDirectoryServiceProvider,
|
||||
nsIDirectoryServiceProvider2)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Undefine(const char* prop)
|
||||
nsDirectoryService::Undefine(const char* aProp)
|
||||
{
|
||||
if (NS_WARN_IF(!prop))
|
||||
if (NS_WARN_IF(!aProp)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsDependentCString key(prop);
|
||||
if (!mHashtable.Get(key, nullptr))
|
||||
nsDependentCString key(aProp);
|
||||
if (!mHashtable.Get(key, nullptr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mHashtable.Remove(key);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::GetKeys(uint32_t *count, char ***keys)
|
||||
nsDirectoryService::GetKeys(uint32_t* aCount, char*** aKeys)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct FileData
|
||||
{
|
||||
FileData(const char* aProperty,
|
||||
const nsIID& aUUID) :
|
||||
property(aProperty),
|
||||
data(nullptr),
|
||||
persistent(true),
|
||||
uuid(aUUID) {}
|
||||
FileData(const char* aProperty, const nsIID& aUUID)
|
||||
: property(aProperty)
|
||||
, data(nullptr)
|
||||
, persistent(true)
|
||||
, uuid(aUUID)
|
||||
{
|
||||
}
|
||||
|
||||
const char* property;
|
||||
nsISupports* data;
|
||||
|
@ -304,15 +308,14 @@ struct FileData
|
|||
const nsIID& uuid;
|
||||
};
|
||||
|
||||
static bool FindProviderFile(nsIDirectoryServiceProvider* aElement,
|
||||
FileData* aData)
|
||||
static bool
|
||||
FindProviderFile(nsIDirectoryServiceProvider* aElement, FileData* aData)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator))) {
|
||||
// Not all providers implement this iface
|
||||
nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
|
||||
if (prov2)
|
||||
{
|
||||
if (prov2) {
|
||||
nsCOMPtr<nsISimpleEnumerator> newFiles;
|
||||
rv = prov2->GetFiles(aData->property, getter_AddRefs(newFiles));
|
||||
if (NS_SUCCEEDED(rv) && newFiles) {
|
||||
|
@ -320,13 +323,12 @@ static bool FindProviderFile(nsIDirectoryServiceProvider* aElement,
|
|||
nsCOMPtr<nsISimpleEnumerator> unionFiles;
|
||||
|
||||
NS_NewUnionEnumerator(getter_AddRefs(unionFiles),
|
||||
(nsISimpleEnumerator*) aData->data, newFiles);
|
||||
(nsISimpleEnumerator*)aData->data, newFiles);
|
||||
|
||||
if (unionFiles)
|
||||
unionFiles.swap(* (nsISimpleEnumerator**) &aData->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unionFiles) {
|
||||
unionFiles.swap(*(nsISimpleEnumerator**)&aData->data);
|
||||
}
|
||||
} else {
|
||||
NS_ADDREF(aData->data = newFiles);
|
||||
}
|
||||
|
||||
|
@ -334,61 +336,57 @@ static bool FindProviderFile(nsIDirectoryServiceProvider* aElement,
|
|||
return rv == NS_SUCCESS_AGGREGATE_RESULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
rv = aElement->GetFile(aData->property, &aData->persistent,
|
||||
(nsIFile **)&aData->data);
|
||||
if (NS_SUCCEEDED(rv) && aData->data)
|
||||
(nsIFile**)&aData->data);
|
||||
if (NS_SUCCEEDED(rv) && aData->data) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
|
||||
nsDirectoryService::Get(const char* aProp, const nsIID& aUuid, void** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!prop))
|
||||
if (NS_WARN_IF(!aProp)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsDependentCString key(prop);
|
||||
nsDependentCString key(aProp);
|
||||
|
||||
nsCOMPtr<nsIFile> cachedFile = mHashtable.Get(key);
|
||||
|
||||
if (cachedFile) {
|
||||
nsCOMPtr<nsIFile> cloneFile;
|
||||
cachedFile->Clone(getter_AddRefs(cloneFile));
|
||||
return cloneFile->QueryInterface(uuid, result);
|
||||
return cloneFile->QueryInterface(aUuid, aResult);
|
||||
}
|
||||
|
||||
// it is not one of our defaults, lets check any providers
|
||||
FileData fileData(prop, uuid);
|
||||
FileData fileData(aProp, aUuid);
|
||||
|
||||
for (int32_t i = mProviders.Length() - 1; i >= 0; i--) {
|
||||
if (!FindProviderFile(mProviders[i], &fileData)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fileData.data)
|
||||
{
|
||||
if (fileData.persistent)
|
||||
{
|
||||
Set(prop, static_cast<nsIFile*>(fileData.data));
|
||||
if (fileData.data) {
|
||||
if (fileData.persistent) {
|
||||
Set(aProp, static_cast<nsIFile*>(fileData.data));
|
||||
}
|
||||
nsresult rv = (fileData.data)->QueryInterface(uuid, result);
|
||||
nsresult rv = (fileData.data)->QueryInterface(aUuid, aResult);
|
||||
NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
|
||||
return rv;
|
||||
}
|
||||
|
||||
FindProviderFile(static_cast<nsIDirectoryServiceProvider*>(this), &fileData);
|
||||
if (fileData.data)
|
||||
{
|
||||
if (fileData.persistent)
|
||||
{
|
||||
Set(prop, static_cast<nsIFile*>(fileData.data));
|
||||
if (fileData.data) {
|
||||
if (fileData.persistent) {
|
||||
Set(aProp, static_cast<nsIFile*>(fileData.data));
|
||||
}
|
||||
nsresult rv = (fileData.data)->QueryInterface(uuid, result);
|
||||
nsresult rv = (fileData.data)->QueryInterface(aUuid, aResult);
|
||||
NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
|
||||
return rv;
|
||||
}
|
||||
|
@ -397,20 +395,21 @@ nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Set(const char* prop, nsISupports* value)
|
||||
nsDirectoryService::Set(const char* aProp, nsISupports* aValue)
|
||||
{
|
||||
if (NS_WARN_IF(!prop))
|
||||
if (NS_WARN_IF(!aProp)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsDependentCString key(prop);
|
||||
if (mHashtable.Get(key, nullptr) || !value) {
|
||||
nsDependentCString key(aProp);
|
||||
if (mHashtable.Get(key, nullptr) || !aValue) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> ourFile = do_QueryInterface(value);
|
||||
nsCOMPtr<nsIFile> ourFile = do_QueryInterface(aValue);
|
||||
if (ourFile) {
|
||||
nsCOMPtr<nsIFile> cloneFile;
|
||||
ourFile->Clone (getter_AddRefs (cloneFile));
|
||||
ourFile->Clone(getter_AddRefs(cloneFile));
|
||||
mHashtable.Put(key, cloneFile);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -420,32 +419,34 @@ nsDirectoryService::Set(const char* prop, nsISupports* value)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Has(const char *prop, bool *_retval)
|
||||
nsDirectoryService::Has(const char* aProp, bool* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!prop))
|
||||
if (NS_WARN_IF(!aProp)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*_retval = false;
|
||||
*aResult = false;
|
||||
nsCOMPtr<nsIFile> value;
|
||||
nsresult rv = Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(value));
|
||||
if (NS_FAILED(rv))
|
||||
nsresult rv = Get(aProp, NS_GET_IID(nsIFile), getter_AddRefs(value));
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
*_retval = true;
|
||||
if (value) {
|
||||
*aResult = true;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
|
||||
nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider* aProv)
|
||||
{
|
||||
if (!prov)
|
||||
if (!aProv) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mProviders.AppendElement(prov);
|
||||
mProviders.AppendElement(aProv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -454,16 +455,18 @@ nsDirectoryService::RegisterCategoryProviders()
|
|||
{
|
||||
nsCOMPtr<nsICategoryManager> catman
|
||||
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
||||
if (!catman)
|
||||
if (!catman) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
catman->EnumerateCategory(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
|
||||
getter_AddRefs(entries));
|
||||
|
||||
nsCOMPtr<nsIUTF8StringEnumerator> strings(do_QueryInterface(entries));
|
||||
if (!strings)
|
||||
if (!strings) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool more;
|
||||
while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
|
||||
|
@ -475,19 +478,21 @@ nsDirectoryService::RegisterCategoryProviders()
|
|||
|
||||
if (contractID) {
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> provider = do_GetService(contractID.get());
|
||||
if (provider)
|
||||
if (provider) {
|
||||
RegisterProvider(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
|
||||
nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv)
|
||||
{
|
||||
if (!prov)
|
||||
if (!aProv) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mProviders.RemoveElement(prov);
|
||||
mProviders.RemoveElement(aProv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -497,102 +502,66 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
|
|||
// your application.
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
|
||||
nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
|
||||
nsIFile** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = nullptr;
|
||||
*persistent = true;
|
||||
*aResult = nullptr;
|
||||
*aPersistent = true;
|
||||
|
||||
nsCOMPtr<nsIAtom> inAtom = do_GetAtom(prop);
|
||||
nsCOMPtr<nsIAtom> inAtom = do_GetAtom(aProp);
|
||||
|
||||
// check to see if it is one of our defaults
|
||||
|
||||
if (inAtom == nsDirectoryService::sCurrentProcess ||
|
||||
inAtom == nsDirectoryService::sOS_CurrentProcessDirectory )
|
||||
{
|
||||
inAtom == nsDirectoryService::sOS_CurrentProcessDirectory) {
|
||||
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
|
||||
// Unless otherwise set, the core pieces of the GRE exist
|
||||
// in the current process directory.
|
||||
else if (inAtom == nsDirectoryService::sGRE_Directory)
|
||||
{
|
||||
else if (inAtom == nsDirectoryService::sGRE_Directory) {
|
||||
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_DriveDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_DriveDirectory) {
|
||||
rv = GetSpecialSystemDirectory(OS_DriveDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory) {
|
||||
rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory) {
|
||||
rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory) {
|
||||
rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
else if (inAtom == nsDirectoryService::sDirectory)
|
||||
{
|
||||
else if (inAtom == nsDirectoryService::sDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kSystemFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sTrashDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sTrashDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kTrashFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sStartupDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sStartupDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kStartupFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sShutdownDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sShutdownDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kShutdownFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sAppleMenuDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sAppleMenuDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kAppleMenuFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sControlPanelDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sControlPanelDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kControlPanelFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sExtensionDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sExtensionDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kExtensionFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sFontsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sFontsDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kFontsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPreferencesDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPreferencesDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kPreferencesFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sInternetSearchDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sInternetSearchDirectory) {
|
||||
rv = GetOSXFolderType(kClassicDomain, kInternetSearchSitesFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserLibDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserLibDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kDomainLibraryFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_HomeDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kDomainTopLevelFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory) {
|
||||
// 10.5 and later, we can use kDownloadsFolderType which is defined in
|
||||
// Folders.h as "down". However, in order to support 10.4 still, we
|
||||
// cannot use the named constant. We'll use it's value, and if it
|
||||
|
@ -607,288 +576,169 @@ nsDirectoryService::GetFile(const char *prop, bool *persistent, nsIFile **_retva
|
|||
rv = GetOSXFolderType(kUserDomain, kDesktopFolderType,
|
||||
getter_AddRefs(localFile));
|
||||
}
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserDesktopDirectory ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserDesktopDirectory ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalDesktopDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalDesktopDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kDesktopFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserApplicationsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserApplicationsDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kApplicationsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalApplicationsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalApplicationsDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kApplicationsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserInternetPlugInDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserInternetPlugInDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalInternetPlugInDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalInternetPlugInDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserFrameworksDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserFrameworksDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kFrameworksFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalFrameworksDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalFrameworksDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kFrameworksFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sUserPreferencesDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sUserPreferencesDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kPreferencesFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalPreferencesDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalPreferencesDirectory) {
|
||||
rv = GetOSXFolderType(kLocalDomain, kPreferencesFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPictureDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPictureDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kPictureDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sMovieDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sMovieDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kMovieDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sMusicDocumentsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sMusicDocumentsDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kMusicDocumentsFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sInternetSitesDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sInternetSitesDirectory) {
|
||||
rv = GetOSXFolderType(kUserDomain, kInternetSitesFolderType, getter_AddRefs(localFile));
|
||||
}
|
||||
#elif defined (XP_WIN)
|
||||
else if (inAtom == nsDirectoryService::sSystemDirectory)
|
||||
{
|
||||
else if (inAtom == nsDirectoryService::sSystemDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_SystemDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sWindowsDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sWindowsDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_WindowsDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sWindowsProgramFiles)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sWindowsProgramFiles) {
|
||||
rv = GetSpecialSystemDirectory(Win_ProgramFiles, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_HomeDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_HomeDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDesktop)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDesktop) {
|
||||
rv = GetSpecialSystemDirectory(Win_Desktop, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPrograms)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPrograms) {
|
||||
rv = GetSpecialSystemDirectory(Win_Programs, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sControls)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sControls) {
|
||||
rv = GetSpecialSystemDirectory(Win_Controls, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPrinters)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPrinters) {
|
||||
rv = GetSpecialSystemDirectory(Win_Printers, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPersonal)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPersonal) {
|
||||
rv = GetSpecialSystemDirectory(Win_Personal, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sFavorites)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sFavorites) {
|
||||
rv = GetSpecialSystemDirectory(Win_Favorites, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sStartup)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sStartup) {
|
||||
rv = GetSpecialSystemDirectory(Win_Startup, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sRecent)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sRecent) {
|
||||
rv = GetSpecialSystemDirectory(Win_Recent, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sSendto)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sSendto) {
|
||||
rv = GetSpecialSystemDirectory(Win_Sendto, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sBitbucket)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sBitbucket) {
|
||||
rv = GetSpecialSystemDirectory(Win_Bitbucket, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sStartmenu)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sStartmenu) {
|
||||
rv = GetSpecialSystemDirectory(Win_Startmenu, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDesktopdirectory ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDesktopdirectory ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_Desktopdirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDrives)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDrives) {
|
||||
rv = GetSpecialSystemDirectory(Win_Drives, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sNetwork)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sNetwork) {
|
||||
rv = GetSpecialSystemDirectory(Win_Network, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sNethood)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sNethood) {
|
||||
rv = GetSpecialSystemDirectory(Win_Nethood, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sFonts)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sFonts) {
|
||||
rv = GetSpecialSystemDirectory(Win_Fonts, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sTemplates)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sTemplates) {
|
||||
rv = GetSpecialSystemDirectory(Win_Templates, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sCommon_Startmenu)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sCommon_Startmenu) {
|
||||
rv = GetSpecialSystemDirectory(Win_Common_Startmenu, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sCommon_Programs)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sCommon_Programs) {
|
||||
rv = GetSpecialSystemDirectory(Win_Common_Programs, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sCommon_Startup)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sCommon_Startup) {
|
||||
rv = GetSpecialSystemDirectory(Win_Common_Startup, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sCommon_Desktopdirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sCommon_Desktopdirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_Common_Desktopdirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sCommon_AppData)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sCommon_AppData) {
|
||||
rv = GetSpecialSystemDirectory(Win_Common_AppData, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sAppdata)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sAppdata) {
|
||||
rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLocalAppdata)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLocalAppdata) {
|
||||
rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPrinthood)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPrinthood) {
|
||||
rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sWinCookiesDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sWinCookiesDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_Cookies, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Win_Downloads, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sDocs)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sDocs) {
|
||||
rv = GetSpecialSystemDirectory(Win_Documents, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sPictures)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sPictures) {
|
||||
rv = GetSpecialSystemDirectory(Win_Pictures, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sMusic)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sMusic) {
|
||||
rv = GetSpecialSystemDirectory(Win_Music, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sVideos)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sVideos) {
|
||||
rv = GetSpecialSystemDirectory(Win_Videos, getter_AddRefs(localFile));
|
||||
}
|
||||
#elif defined (XP_UNIX)
|
||||
|
||||
else if (inAtom == nsDirectoryService::sLocalDirectory)
|
||||
{
|
||||
else if (inAtom == nsDirectoryService::sLocalDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Unix_LocalDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sLibDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sLibDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Unix_LibDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sOS_HomeDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGDesktop ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory)
|
||||
{
|
||||
} else if (inAtom == nsDirectoryService::sXDGDesktop ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Desktop, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGDocuments)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGDocuments) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Documents, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGDownload ||
|
||||
inAtom == nsDirectoryService::sDefaultDownloadDirectory)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGDownload ||
|
||||
inAtom == nsDirectoryService::sDefaultDownloadDirectory) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Download, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGMusic)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGMusic) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Music, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGPictures)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGPictures) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Pictures, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGPublicShare)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGPublicShare) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_PublicShare, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGTemplates)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGTemplates) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Templates, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGVideos)
|
||||
{
|
||||
*aPersistent = false;
|
||||
} else if (inAtom == nsDirectoryService::sXDGVideos) {
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Videos, getter_AddRefs(localFile));
|
||||
*persistent = false;
|
||||
*aPersistent = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!localFile)
|
||||
if (!localFile) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
localFile.forget(_retval);
|
||||
localFile.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
|
||||
nsDirectoryService::GetFiles(const char* aProp, nsISimpleEnumerator** aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!_retval))
|
||||
if (NS_WARN_IF(!aResult)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*_retval = nullptr;
|
||||
}
|
||||
*aResult = nullptr;
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
// CANNOT be used to GET a location
|
||||
#define NS_DIRECTORY_SERVICE_CID {0xf00152d0,0xb40b,0x11d3,{0x8c, 0x9c, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74}}
|
||||
|
||||
class nsDirectoryService MOZ_FINAL : public nsIDirectoryService,
|
||||
public nsIProperties,
|
||||
public nsIDirectoryServiceProvider2
|
||||
class nsDirectoryService MOZ_FINAL
|
||||
: public nsIDirectoryService
|
||||
, public nsIProperties
|
||||
, public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -42,7 +43,7 @@ public:
|
|||
void RegisterCategoryProviders();
|
||||
|
||||
static nsresult
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||
|
||||
static nsDirectoryService* gService;
|
||||
|
||||
|
@ -50,7 +51,7 @@ private:
|
|||
nsresult GetCurrentProcessDirectory(nsIFile** aFile);
|
||||
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsIFile> mHashtable;
|
||||
nsTArray<nsCOMPtr<nsIDirectoryServiceProvider> > mProviders;
|
||||
nsTArray<nsCOMPtr<nsIDirectoryServiceProvider>> mProviders;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -15,15 +15,16 @@
|
|||
#include "nsIFile.h"
|
||||
|
||||
inline nsresult
|
||||
NS_GetSpecialDirectory(const char* specialDirName, nsIFile* *result)
|
||||
NS_GetSpecialDirectory(const char* aSpecialDirName, nsIFile** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> serv(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return serv->Get(specialDirName, NS_GET_IID(nsIFile),
|
||||
reinterpret_cast<void**>(result));
|
||||
return serv->Get(aSpecialDirName, NS_GET_IID(nsIFile),
|
||||
reinterpret_cast<void**>(aResult));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,79 +38,76 @@ const int netCharType[256] =
|
|||
((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))
|
||||
|
||||
|
||||
#define IS_OK(C) (netCharType[((unsigned int) (C))] & (flags))
|
||||
#define IS_OK(C) (netCharType[((unsigned int)(C))] & (aFlags))
|
||||
#define HEX_ESCAPE '%'
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
static char* nsEscapeCount(
|
||||
const char * str,
|
||||
nsEscapeMask flags,
|
||||
size_t* out_len)
|
||||
static char*
|
||||
nsEscapeCount(const char* aStr, nsEscapeMask aFlags, size_t* aOutLen)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!str)
|
||||
if (!aStr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t i, len = 0, charsToEscape = 0;
|
||||
size_t len = 0;
|
||||
size_t charsToEscape = 0;
|
||||
static const char hexChars[] = "0123456789ABCDEF";
|
||||
|
||||
const unsigned char* src = (const unsigned char *) str;
|
||||
while (*src)
|
||||
{
|
||||
const unsigned char* src = (const unsigned char*)aStr;
|
||||
while (*src) {
|
||||
len++;
|
||||
if (!IS_OK(*src++))
|
||||
if (!IS_OK(*src++)) {
|
||||
charsToEscape++;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate how much memory should be allocated
|
||||
// original length + 2 bytes for each escaped character + terminating '\0'
|
||||
// do the sum in steps to check for overflow
|
||||
size_t dstSize = len + 1 + charsToEscape;
|
||||
if (dstSize <= len)
|
||||
if (dstSize <= len) {
|
||||
return 0;
|
||||
}
|
||||
dstSize += charsToEscape;
|
||||
if (dstSize < len)
|
||||
if (dstSize < len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if we need more than 4GB
|
||||
// size_t is likely to be long unsigned int but nsMemory::Alloc(size_t)
|
||||
// calls NS_Alloc_P(size_t) which calls PR_Malloc(uint32_t), so there is
|
||||
// no chance to allocate more than 4GB using nsMemory::Alloc()
|
||||
if (dstSize > UINT32_MAX)
|
||||
if (dstSize > UINT32_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* result = (char *)nsMemory::Alloc(dstSize);
|
||||
if (!result)
|
||||
char* result = (char*)nsMemory::Alloc(dstSize);
|
||||
if (!result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char* dst = (unsigned char *) result;
|
||||
src = (const unsigned char *) str;
|
||||
if (flags == url_XPAlphas)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)result;
|
||||
src = (const unsigned char*)aStr;
|
||||
if (aFlags == url_XPAlphas) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
unsigned char c = *src++;
|
||||
if (IS_OK(c))
|
||||
if (IS_OK(c)) {
|
||||
*dst++ = c;
|
||||
else if (c == ' ')
|
||||
*dst++ = '+'; /* convert spaces to pluses */
|
||||
else
|
||||
{
|
||||
} else if (c == ' ') {
|
||||
*dst++ = '+'; /* convert spaces to pluses */
|
||||
} else {
|
||||
*dst++ = HEX_ESCAPE;
|
||||
*dst++ = hexChars[c >> 4]; /* high nibble */
|
||||
*dst++ = hexChars[c & 0x0f]; /* low nibble */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
} else {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
unsigned char c = *src++;
|
||||
if (IS_OK(c))
|
||||
if (IS_OK(c)) {
|
||||
*dst++ = c;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*dst++ = HEX_ESCAPE;
|
||||
*dst++ = hexChars[c >> 4]; /* high nibble */
|
||||
*dst++ = hexChars[c & 0x0f]; /* low nibble */
|
||||
|
@ -119,34 +116,39 @@ static char* nsEscapeCount(
|
|||
}
|
||||
|
||||
*dst = '\0'; /* tack on eos */
|
||||
if(out_len)
|
||||
*out_len = dst - (unsigned char *) result;
|
||||
if (aOutLen) {
|
||||
*aOutLen = dst - (unsigned char*)result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsEscape(const char * str, nsEscapeMask flags)
|
||||
char*
|
||||
nsEscape(const char* aStr, nsEscapeMask aFlags)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if(!str)
|
||||
if (!aStr) {
|
||||
return nullptr;
|
||||
return nsEscapeCount(str, flags, nullptr);
|
||||
}
|
||||
return nsEscapeCount(aStr, aFlags, nullptr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsUnescape(char * str)
|
||||
char*
|
||||
nsUnescape(char* aStr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsUnescapeCount(str);
|
||||
return str;
|
||||
nsUnescapeCount(aStr);
|
||||
return aStr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int32_t nsUnescapeCount(char * str)
|
||||
int32_t
|
||||
nsUnescapeCount(char* aStr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char *src = str;
|
||||
char *dst = str;
|
||||
char* src = aStr;
|
||||
char* dst = aStr;
|
||||
static const char hexChars[] = "0123456789ABCDEFabcdef";
|
||||
|
||||
char c1[] = " ";
|
||||
|
@ -161,27 +163,24 @@ int32_t nsUnescapeCount(char * str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
while (*src)
|
||||
{
|
||||
c1[0] = *(src+1);
|
||||
if (*(src+1) == '\0')
|
||||
while (*src) {
|
||||
c1[0] = *(src + 1);
|
||||
if (*(src + 1) == '\0') {
|
||||
c2[0] = '\0';
|
||||
else
|
||||
c2[0] = *(src+2);
|
||||
} else {
|
||||
c2[0] = *(src + 2);
|
||||
}
|
||||
|
||||
if (*src != HEX_ESCAPE || PL_strpbrk(pc1, hexChars) == 0 ||
|
||||
PL_strpbrk(pc2, hexChars) == 0 )
|
||||
PL_strpbrk(pc2, hexChars) == 0) {
|
||||
*dst++ = *src++;
|
||||
else
|
||||
{
|
||||
} else {
|
||||
src++; /* walk over escape */
|
||||
if (*src)
|
||||
{
|
||||
if (*src) {
|
||||
*dst = UNHEX(*src) << 4;
|
||||
src++;
|
||||
}
|
||||
if (*src)
|
||||
{
|
||||
if (*src) {
|
||||
*dst = (*dst + UNHEX(*src));
|
||||
src++;
|
||||
}
|
||||
|
@ -190,79 +189,67 @@ int32_t nsUnescapeCount(char * str)
|
|||
}
|
||||
|
||||
*dst = 0;
|
||||
return (int)(dst - str);
|
||||
return (int)(dst - aStr);
|
||||
|
||||
} /* NET_UnEscapeCnt */
|
||||
|
||||
|
||||
char *
|
||||
nsEscapeHTML(const char * string)
|
||||
char*
|
||||
nsEscapeHTML(const char* aString)
|
||||
{
|
||||
char *rv = nullptr;
|
||||
char* rv = nullptr;
|
||||
/* XXX Hardcoded max entity len. The +1 is for the trailing null. */
|
||||
uint32_t len = strlen(string);
|
||||
if (len >= (UINT32_MAX / 6))
|
||||
uint32_t len = strlen(aString);
|
||||
if (len >= (UINT32_MAX / 6)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = (char *)NS_Alloc( (6 * len) + 1 );
|
||||
char *ptr = rv;
|
||||
rv = (char*)NS_Alloc((6 * len) + 1);
|
||||
char* ptr = rv;
|
||||
|
||||
if(rv)
|
||||
{
|
||||
for(; *string != '\0'; string++)
|
||||
{
|
||||
if(*string == '<')
|
||||
{
|
||||
if (rv) {
|
||||
for (; *aString != '\0'; ++aString) {
|
||||
if (*aString == '<') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'l';
|
||||
*ptr++ = 't';
|
||||
*ptr++ = ';';
|
||||
}
|
||||
else if(*string == '>')
|
||||
{
|
||||
} else if (*aString == '>') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'g';
|
||||
*ptr++ = 't';
|
||||
*ptr++ = ';';
|
||||
}
|
||||
else if(*string == '&')
|
||||
{
|
||||
} else if (*aString == '&') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'a';
|
||||
*ptr++ = 'm';
|
||||
*ptr++ = 'p';
|
||||
*ptr++ = ';';
|
||||
}
|
||||
else if (*string == '"')
|
||||
{
|
||||
} else if (*aString == '"') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'q';
|
||||
*ptr++ = 'u';
|
||||
*ptr++ = 'o';
|
||||
*ptr++ = 't';
|
||||
*ptr++ = ';';
|
||||
}
|
||||
else if (*string == '\'')
|
||||
{
|
||||
} else if (*aString == '\'') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = '#';
|
||||
*ptr++ = '3';
|
||||
*ptr++ = '9';
|
||||
*ptr++ = ';';
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = *string;
|
||||
} else {
|
||||
*ptr++ = *aString;
|
||||
}
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
return(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
char16_t *
|
||||
nsEscapeHTML2(const char16_t *aSourceBuffer, int32_t aSourceBufferLen)
|
||||
char16_t*
|
||||
nsEscapeHTML2(const char16_t* aSourceBuffer, int32_t aSourceBufferLen)
|
||||
{
|
||||
// Calculate the length, if the caller didn't.
|
||||
if (aSourceBufferLen < 0) {
|
||||
|
@ -271,28 +258,29 @@ nsEscapeHTML2(const char16_t *aSourceBuffer, int32_t aSourceBufferLen)
|
|||
|
||||
/* XXX Hardcoded max entity len. */
|
||||
if (uint32_t(aSourceBufferLen) >=
|
||||
((UINT32_MAX - sizeof(char16_t)) / (6 * sizeof(char16_t))) )
|
||||
((UINT32_MAX - sizeof(char16_t)) / (6 * sizeof(char16_t)))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char16_t *resultBuffer = (char16_t *)nsMemory::Alloc(aSourceBufferLen *
|
||||
6 * sizeof(char16_t) + sizeof(char16_t('\0')));
|
||||
char16_t *ptr = resultBuffer;
|
||||
char16_t* resultBuffer = (char16_t*)nsMemory::Alloc(
|
||||
aSourceBufferLen * 6 * sizeof(char16_t) + sizeof(char16_t('\0')));
|
||||
char16_t* ptr = resultBuffer;
|
||||
|
||||
if (resultBuffer) {
|
||||
int32_t i;
|
||||
|
||||
for(i = 0; i < aSourceBufferLen; i++) {
|
||||
if(aSourceBuffer[i] == '<') {
|
||||
for (i = 0; i < aSourceBufferLen; ++i) {
|
||||
if (aSourceBuffer[i] == '<') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'l';
|
||||
*ptr++ = 't';
|
||||
*ptr++ = ';';
|
||||
} else if(aSourceBuffer[i] == '>') {
|
||||
} else if (aSourceBuffer[i] == '>') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'g';
|
||||
*ptr++ = 't';
|
||||
*ptr++ = ';';
|
||||
} else if(aSourceBuffer[i] == '&') {
|
||||
} else if (aSourceBuffer[i] == '&') {
|
||||
*ptr++ = '&';
|
||||
*ptr++ = 'a';
|
||||
*ptr++ = 'm';
|
||||
|
@ -337,7 +325,7 @@ const int EscapeChars[256] =
|
|||
0 /* 8x DEL */
|
||||
};
|
||||
|
||||
#define NO_NEED_ESC(C) (EscapeChars[((unsigned int) (C))] & (flags))
|
||||
#define NO_NEED_ESC(C) (EscapeChars[((unsigned int)(C))] & (aFlags))
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -367,34 +355,32 @@ const int EscapeChars[256] =
|
|||
esc_Forced = 1024
|
||||
*/
|
||||
|
||||
bool NS_EscapeURL(const char *part,
|
||||
int32_t partLen,
|
||||
uint32_t flags,
|
||||
nsACString &result)
|
||||
bool
|
||||
NS_EscapeURL(const char* aPart, int32_t aPartLen, uint32_t aFlags,
|
||||
nsACString& aResult)
|
||||
{
|
||||
if (!part) {
|
||||
if (!aPart) {
|
||||
NS_NOTREACHED("null pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
static const char hexChars[] = "0123456789ABCDEF";
|
||||
if (partLen < 0)
|
||||
partLen = strlen(part);
|
||||
bool forced = !!(flags & esc_Forced);
|
||||
bool ignoreNonAscii = !!(flags & esc_OnlyASCII);
|
||||
bool ignoreAscii = !!(flags & esc_OnlyNonASCII);
|
||||
bool writing = !!(flags & esc_AlwaysCopy);
|
||||
bool colon = !!(flags & esc_Colon);
|
||||
if (aPartLen < 0) {
|
||||
aPartLen = strlen(aPart);
|
||||
}
|
||||
bool forced = !!(aFlags & esc_Forced);
|
||||
bool ignoreNonAscii = !!(aFlags & esc_OnlyASCII);
|
||||
bool ignoreAscii = !!(aFlags & esc_OnlyNonASCII);
|
||||
bool writing = !!(aFlags & esc_AlwaysCopy);
|
||||
bool colon = !!(aFlags & esc_Colon);
|
||||
|
||||
const unsigned char* src = (const unsigned char *) part;
|
||||
const unsigned char* src = (const unsigned char*)aPart;
|
||||
|
||||
char tempBuffer[100];
|
||||
unsigned int tempBufferPos = 0;
|
||||
|
||||
bool previousIsNonASCII = false;
|
||||
for (i = 0; i < partLen; i++)
|
||||
{
|
||||
for (int i = 0; i < aPartLen; ++i) {
|
||||
unsigned char c = *src++;
|
||||
|
||||
// if the char has not to be escaped or whatever follows % is
|
||||
|
@ -409,7 +395,7 @@ bool NS_EscapeURL(const char *part,
|
|||
// ignoreAscii is not honored for control characters (C0 and DEL)
|
||||
//
|
||||
// And, we should escape the '|' character when it occurs after any
|
||||
// non-ASCII character as it may be part of a multi-byte character.
|
||||
// non-ASCII character as it may be aPart of a multi-byte character.
|
||||
//
|
||||
// 0x20..0x7e are the valid ASCII characters. We also escape spaces
|
||||
// (0x20) since they are not legal in URLs.
|
||||
|
@ -417,16 +403,13 @@ bool NS_EscapeURL(const char *part,
|
|||
|| (c > 0x7f && ignoreNonAscii)
|
||||
|| (c > 0x20 && c < 0x7f && ignoreAscii))
|
||||
&& !(c == ':' && colon)
|
||||
&& !(previousIsNonASCII && c == '|' && !ignoreNonAscii))
|
||||
{
|
||||
if (writing)
|
||||
&& !(previousIsNonASCII && c == '|' && !ignoreNonAscii)) {
|
||||
if (writing) {
|
||||
tempBuffer[tempBufferPos++] = c;
|
||||
}
|
||||
else /* do the escape magic */
|
||||
{
|
||||
if (!writing)
|
||||
{
|
||||
result.Append(part, i);
|
||||
}
|
||||
} else { /* do the escape magic */
|
||||
if (!writing) {
|
||||
aResult.Append(aPart, i);
|
||||
writing = true;
|
||||
}
|
||||
tempBuffer[tempBufferPos++] = HEX_ESCAPE;
|
||||
|
@ -434,11 +417,10 @@ bool NS_EscapeURL(const char *part,
|
|||
tempBuffer[tempBufferPos++] = hexChars[c & 0x0f]; /* low nibble */
|
||||
}
|
||||
|
||||
if (tempBufferPos >= sizeof(tempBuffer) - 4)
|
||||
{
|
||||
if (tempBufferPos >= sizeof(tempBuffer) - 4) {
|
||||
NS_ASSERTION(writing, "should be writing");
|
||||
tempBuffer[tempBufferPos] = '\0';
|
||||
result += tempBuffer;
|
||||
aResult += tempBuffer;
|
||||
tempBufferPos = 0;
|
||||
}
|
||||
|
||||
|
@ -446,38 +428,41 @@ bool NS_EscapeURL(const char *part,
|
|||
}
|
||||
if (writing) {
|
||||
tempBuffer[tempBufferPos] = '\0';
|
||||
result += tempBuffer;
|
||||
aResult += tempBuffer;
|
||||
}
|
||||
return writing;
|
||||
}
|
||||
|
||||
#define ISHEX(c) memchr(hexChars, c, sizeof(hexChars)-1)
|
||||
|
||||
bool NS_UnescapeURL(const char *str, int32_t len, uint32_t flags, nsACString &result)
|
||||
bool
|
||||
NS_UnescapeURL(const char* aStr, int32_t aLen, uint32_t aFlags,
|
||||
nsACString& aResult)
|
||||
{
|
||||
if (!str) {
|
||||
if (!aStr) {
|
||||
NS_NOTREACHED("null pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len < 0)
|
||||
len = strlen(str);
|
||||
if (aLen < 0) {
|
||||
aLen = strlen(aStr);
|
||||
}
|
||||
|
||||
bool ignoreNonAscii = !!(flags & esc_OnlyASCII);
|
||||
bool ignoreAscii = !!(flags & esc_OnlyNonASCII);
|
||||
bool writing = !!(flags & esc_AlwaysCopy);
|
||||
bool skipControl = !!(flags & esc_SkipControl);
|
||||
bool ignoreNonAscii = !!(aFlags & esc_OnlyASCII);
|
||||
bool ignoreAscii = !!(aFlags & esc_OnlyNonASCII);
|
||||
bool writing = !!(aFlags & esc_AlwaysCopy);
|
||||
bool skipControl = !!(aFlags & esc_SkipControl);
|
||||
|
||||
static const char hexChars[] = "0123456789ABCDEFabcdef";
|
||||
|
||||
const char *last = str;
|
||||
const char *p = str;
|
||||
const char* last = aStr;
|
||||
const char* p = aStr;
|
||||
|
||||
for (int i=0; i<len; ++i, ++p) {
|
||||
//printf("%c [i=%d of len=%d]\n", *p, i, len);
|
||||
if (*p == HEX_ESCAPE && i < len-2) {
|
||||
unsigned char *p1 = ((unsigned char *) p) + 1;
|
||||
unsigned char *p2 = ((unsigned char *) p) + 2;
|
||||
for (int i = 0; i < aLen; ++i, ++p) {
|
||||
//printf("%c [i=%d of aLen=%d]\n", *p, i, aLen);
|
||||
if (*p == HEX_ESCAPE && i < aLen - 2) {
|
||||
unsigned char* p1 = (unsigned char*)p + 1;
|
||||
unsigned char* p2 = (unsigned char*)p + 2;
|
||||
if (ISHEX(*p1) && ISHEX(*p2) &&
|
||||
((*p1 < '8' && !ignoreAscii) || (*p1 >= '8' && !ignoreNonAscii)) &&
|
||||
!(skipControl &&
|
||||
|
@ -486,20 +471,21 @@ bool NS_UnescapeURL(const char *str, int32_t len, uint32_t flags, nsACString &re
|
|||
writing = true;
|
||||
if (p > last) {
|
||||
//printf("- p=%p, last=%p\n", p, last);
|
||||
result.Append(last, p - last);
|
||||
aResult.Append(last, p - last);
|
||||
last = p;
|
||||
}
|
||||
char u = (UNHEX(*p1) << 4) + UNHEX(*p2);
|
||||
//printf("- u=%c\n", u);
|
||||
result.Append(u);
|
||||
aResult.Append(u);
|
||||
i += 2;
|
||||
p += 2;
|
||||
last += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (writing && last < str + len)
|
||||
result.Append(last, str + len - last);
|
||||
if (writing && last < aStr + aLen) {
|
||||
aResult.Append(last, aStr + aLen - last);
|
||||
}
|
||||
|
||||
return writing;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
* in sync.
|
||||
*/
|
||||
typedef enum {
|
||||
url_All = 0 /**< %-escape every byte unconditionally */
|
||||
, url_XAlphas = 1u << 0 /**< Normal escape - leave alphas intact, escape the rest */
|
||||
, url_XPAlphas = 1u << 1 /**< As url_XAlphas, but convert spaces (0x20) to '+' and plus to %2B */
|
||||
, url_Path = 1u << 2 /**< As url_XAlphas, but don't escape slash ('/') */
|
||||
url_All = 0, // %-escape every byte unconditionally
|
||||
url_XAlphas = 1u << 0, // Normal escape - leave alphas intact, escape the rest
|
||||
url_XPAlphas = 1u << 1, // As url_XAlphas, but convert spaces (0x20) to '+' and plus to %2B
|
||||
url_Path = 1u << 2 // As url_XAlphas, but don't escape slash ('/')
|
||||
} nsEscapeMask;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -36,24 +36,24 @@ extern "C" {
|
|||
* @return A newly allocated escaped string that must be free'd with
|
||||
* nsCRT::free, or null on failure
|
||||
*/
|
||||
char * nsEscape(const char * str, nsEscapeMask mask);
|
||||
char* nsEscape(const char* aStr, nsEscapeMask aMask);
|
||||
|
||||
char * nsUnescape(char * str);
|
||||
char* nsUnescape(char* aStr);
|
||||
/* decode % escaped hex codes into character values,
|
||||
* modifies the parameter, returns the same buffer
|
||||
*/
|
||||
|
||||
int32_t nsUnescapeCount (char * str);
|
||||
int32_t nsUnescapeCount(char* aStr);
|
||||
/* decode % escaped hex codes into character values,
|
||||
* modifies the parameter buffer, returns the length of the result
|
||||
* (result may contain \0's).
|
||||
*/
|
||||
|
||||
char *
|
||||
nsEscapeHTML(const char * string);
|
||||
char*
|
||||
nsEscapeHTML(const char* aString);
|
||||
|
||||
char16_t *
|
||||
nsEscapeHTML2(const char16_t *aSourceBuffer,
|
||||
char16_t*
|
||||
nsEscapeHTML2(const char16_t* aSourceBuffer,
|
||||
int32_t aSourceBufferLen = -1);
|
||||
/*
|
||||
* Escape problem char's for HTML display
|
||||
|
@ -110,10 +110,10 @@ enum EscapeMask {
|
|||
*
|
||||
* @return TRUE if escaping was performed, FALSE otherwise.
|
||||
*/
|
||||
bool NS_EscapeURL(const char *str,
|
||||
int32_t len,
|
||||
uint32_t flags,
|
||||
nsACString &result);
|
||||
bool NS_EscapeURL(const char* aStr,
|
||||
int32_t aLen,
|
||||
uint32_t aFlags,
|
||||
nsACString& aResult);
|
||||
|
||||
/**
|
||||
* Expands URL escape sequences... beware embedded null bytes!
|
||||
|
@ -126,30 +126,36 @@ bool NS_EscapeURL(const char *str,
|
|||
*
|
||||
* @return TRUE if unescaping was performed, FALSE otherwise.
|
||||
*/
|
||||
bool NS_UnescapeURL(const char *str,
|
||||
int32_t len,
|
||||
uint32_t flags,
|
||||
nsACString &result);
|
||||
bool NS_UnescapeURL(const char* aStr,
|
||||
int32_t aLen,
|
||||
uint32_t aFlags,
|
||||
nsACString& aResult);
|
||||
|
||||
/** returns resultant string length **/
|
||||
inline int32_t NS_UnescapeURL(char *str) {
|
||||
return nsUnescapeCount(str);
|
||||
inline int32_t
|
||||
NS_UnescapeURL(char* aStr)
|
||||
{
|
||||
return nsUnescapeCount(aStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* String friendly versions...
|
||||
*/
|
||||
inline const nsCSubstring &
|
||||
NS_EscapeURL(const nsCSubstring &str, uint32_t flags, nsCSubstring &result) {
|
||||
if (NS_EscapeURL(str.Data(), str.Length(), flags, result))
|
||||
return result;
|
||||
return str;
|
||||
inline const nsCSubstring&
|
||||
NS_EscapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult)
|
||||
{
|
||||
if (NS_EscapeURL(aStr.Data(), aStr.Length(), aFlags, aResult)) {
|
||||
return aResult;
|
||||
}
|
||||
return aStr;
|
||||
}
|
||||
inline const nsCSubstring &
|
||||
NS_UnescapeURL(const nsCSubstring &str, uint32_t flags, nsCSubstring &result) {
|
||||
if (NS_UnescapeURL(str.Data(), str.Length(), flags, result))
|
||||
return result;
|
||||
return str;
|
||||
inline const nsCSubstring&
|
||||
NS_UnescapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult)
|
||||
{
|
||||
if (NS_UnescapeURL(aStr.Data(), aStr.Length(), aFlags, aResult)) {
|
||||
return aResult;
|
||||
}
|
||||
return aStr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,8 +167,9 @@ NS_Escape(const nsCString& aOriginal, nsCString& aEscaped,
|
|||
nsEscapeMask aMask)
|
||||
{
|
||||
char* esc = nsEscape(aOriginal.get(), aMask);
|
||||
if (! esc)
|
||||
if (! esc) {
|
||||
return false;
|
||||
}
|
||||
aEscaped.Adopt(esc);
|
||||
return true;
|
||||
}
|
||||
|
@ -170,11 +177,11 @@ NS_Escape(const nsCString& aOriginal, nsCString& aEscaped,
|
|||
/**
|
||||
* Inline unescape of mutable string object.
|
||||
*/
|
||||
inline nsCString &
|
||||
NS_UnescapeURL(nsCString &str)
|
||||
inline nsCString&
|
||||
NS_UnescapeURL(nsCString& aStr)
|
||||
{
|
||||
str.SetLength(nsUnescapeCount(str.BeginWriting()));
|
||||
return str;
|
||||
aStr.SetLength(nsUnescapeCount(aStr.BeginWriting()));
|
||||
return aStr;
|
||||
}
|
||||
|
||||
#endif // _ESCAPE_H_
|
||||
|
|
|
@ -11,19 +11,21 @@
|
|||
NS_IMPL_ISUPPORTS(nsIOUtil, nsIIOUtil)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOUtil::InputStreamIsBuffered(nsIInputStream* aStream, bool* _retval)
|
||||
nsIOUtil::InputStreamIsBuffered(nsIInputStream* aStream, bool* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!aStream))
|
||||
if (NS_WARN_IF(!aStream)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*_retval = NS_InputStreamIsBuffered(aStream);
|
||||
}
|
||||
*aResult = NS_InputStreamIsBuffered(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOUtil::OutputStreamIsBuffered(nsIOutputStream* aStream, bool* _retval)
|
||||
nsIOUtil::OutputStreamIsBuffered(nsIOutputStream* aStream, bool* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!aStream))
|
||||
if (NS_WARN_IF(!aStream)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*_retval = NS_OutputStreamIsBuffered(aStream);
|
||||
}
|
||||
*aResult = NS_OutputStreamIsBuffered(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -26,9 +26,10 @@ using namespace mozilla;
|
|||
static PRLogModuleInfo*
|
||||
GetTeeLog()
|
||||
{
|
||||
static PRLogModuleInfo *sLog;
|
||||
if (!sLog)
|
||||
static PRLogModuleInfo* sLog;
|
||||
if (!sLog) {
|
||||
sLog = PR_NewLogModule("nsInputStreamTee");
|
||||
}
|
||||
return sLog;
|
||||
}
|
||||
#define LOG(args) PR_LOG(GetTeeLog(), PR_LOG_DEBUG, args)
|
||||
|
@ -48,33 +49,37 @@ public:
|
|||
void InvalidateSink();
|
||||
|
||||
private:
|
||||
~nsInputStreamTee() {}
|
||||
~nsInputStreamTee()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult TeeSegment(const char *buf, uint32_t count);
|
||||
nsresult TeeSegment(const char* aBuf, uint32_t aCount);
|
||||
|
||||
static NS_METHOD WriteSegmentFun(nsIInputStream *, void *, const char *,
|
||||
uint32_t, uint32_t, uint32_t *);
|
||||
static NS_METHOD WriteSegmentFun(nsIInputStream*, void*, const char*,
|
||||
uint32_t, uint32_t, uint32_t*);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIInputStream> mSource;
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
nsWriteSegmentFun mWriter; // for implementing ReadSegments
|
||||
void *mClosure; // for implementing ReadSegments
|
||||
void* mClosure; // for implementing ReadSegments
|
||||
nsAutoPtr<Mutex> mLock; // synchronize access to mSinkIsValid
|
||||
bool mSinkIsValid; // False if TeeWriteEvent fails
|
||||
};
|
||||
|
||||
class nsInputStreamTeeWriteEvent : public nsRunnable {
|
||||
class nsInputStreamTeeWriteEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
// aTee's lock is held across construction of this object
|
||||
nsInputStreamTeeWriteEvent(const char *aBuf, uint32_t aCount,
|
||||
nsIOutputStream *aSink,
|
||||
nsInputStreamTee *aTee)
|
||||
nsInputStreamTeeWriteEvent(const char* aBuf, uint32_t aCount,
|
||||
nsIOutputStream* aSink, nsInputStreamTee* aTee)
|
||||
{
|
||||
// copy the buffer - will be free'd by dtor
|
||||
mBuf = (char *)malloc(aCount);
|
||||
if (mBuf) memcpy(mBuf, (char *)aBuf, aCount);
|
||||
mBuf = (char*)malloc(aCount);
|
||||
if (mBuf) {
|
||||
memcpy(mBuf, (char*)aBuf, aCount);
|
||||
}
|
||||
mCount = aCount;
|
||||
mSink = aSink;
|
||||
bool isNonBlocking;
|
||||
|
@ -109,7 +114,7 @@ public:
|
|||
rv = mSink->Write(mBuf + totalBytesWritten, mCount, &bytesWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("nsInputStreamTeeWriteEvent::Run[%p] error %x in writing",
|
||||
this,rv));
|
||||
this, rv));
|
||||
mTee->InvalidateSink();
|
||||
break;
|
||||
}
|
||||
|
@ -123,12 +128,14 @@ public:
|
|||
protected:
|
||||
virtual ~nsInputStreamTeeWriteEvent()
|
||||
{
|
||||
if (mBuf) free(mBuf);
|
||||
if (mBuf) {
|
||||
free(mBuf);
|
||||
}
|
||||
mBuf = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
char *mBuf;
|
||||
char* mBuf;
|
||||
uint32_t mCount;
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
// back pointer to the tee that created this runnable
|
||||
|
@ -136,7 +143,7 @@ private:
|
|||
};
|
||||
|
||||
nsInputStreamTee::nsInputStreamTee(): mLock(nullptr)
|
||||
, mSinkIsValid(true)
|
||||
, mSinkIsValid(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -155,26 +162,28 @@ nsInputStreamTee::InvalidateSink()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsInputStreamTee::TeeSegment(const char *buf, uint32_t count)
|
||||
nsInputStreamTee::TeeSegment(const char* aBuf, uint32_t aCount)
|
||||
{
|
||||
if (!mSink) return NS_OK; // nothing to do
|
||||
if (!mSink) {
|
||||
return NS_OK; // nothing to do
|
||||
}
|
||||
if (mLock) { // asynchronous case
|
||||
NS_ASSERTION(mEventTarget, "mEventTarget is null, mLock is not null.");
|
||||
if (!SinkIsValid()) {
|
||||
return NS_OK; // nothing to do
|
||||
}
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
new nsInputStreamTeeWriteEvent(buf, count, mSink, this);
|
||||
new nsInputStreamTeeWriteEvent(aBuf, aCount, mSink, this);
|
||||
LOG(("nsInputStreamTee::TeeSegment [%p] dispatching write %u bytes\n",
|
||||
this, count));
|
||||
this, aCount));
|
||||
return mEventTarget->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
} else { // synchronous case
|
||||
NS_ASSERTION(!mEventTarget, "mEventTarget is not null, mLock is null.");
|
||||
nsresult rv;
|
||||
uint32_t totalBytesWritten = 0;
|
||||
while (count) {
|
||||
while (aCount) {
|
||||
uint32_t bytesWritten = 0;
|
||||
rv = mSink->Write(buf + totalBytesWritten, count, &bytesWritten);
|
||||
rv = mSink->Write(aBuf + totalBytesWritten, aCount, &bytesWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
// ok, this is not a fatal error... just drop our reference to mSink
|
||||
// and continue on as if nothing happened.
|
||||
|
@ -185,27 +194,28 @@ nsInputStreamTee::TeeSegment(const char *buf, uint32_t count)
|
|||
break;
|
||||
}
|
||||
totalBytesWritten += bytesWritten;
|
||||
NS_ASSERTION(bytesWritten <= count, "wrote too much");
|
||||
count -= bytesWritten;
|
||||
NS_ASSERTION(bytesWritten <= aCount, "wrote too much");
|
||||
aCount -= bytesWritten;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsInputStreamTee::WriteSegmentFun(nsIInputStream *in, void *closure, const char *fromSegment,
|
||||
uint32_t offset, uint32_t count, uint32_t *writeCount)
|
||||
nsInputStreamTee::WriteSegmentFun(nsIInputStream* aIn, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount)
|
||||
{
|
||||
nsInputStreamTee *tee = reinterpret_cast<nsInputStreamTee *>(closure);
|
||||
|
||||
nsresult rv = tee->mWriter(in, tee->mClosure, fromSegment, offset, count, writeCount);
|
||||
if (NS_FAILED(rv) || (*writeCount == 0)) {
|
||||
NS_ASSERTION((NS_FAILED(rv) ? (*writeCount == 0) : true),
|
||||
nsInputStreamTee* tee = reinterpret_cast<nsInputStreamTee*>(aClosure);
|
||||
nsresult rv = tee->mWriter(aIn, tee->mClosure, aFromSegment, aOffset,
|
||||
aCount, aWriteCount);
|
||||
if (NS_FAILED(rv) || (*aWriteCount == 0)) {
|
||||
NS_ASSERTION((NS_FAILED(rv) ? (*aWriteCount == 0) : true),
|
||||
"writer returned an error with non-zero writeCount");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return tee->TeeSegment(fromSegment, *writeCount);
|
||||
return tee->TeeSegment(aFromSegment, *aWriteCount);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsInputStreamTee,
|
||||
|
@ -214,8 +224,9 @@ NS_IMPL_ISUPPORTS(nsInputStreamTee,
|
|||
NS_IMETHODIMP
|
||||
nsInputStreamTee::Close()
|
||||
{
|
||||
if (NS_WARN_IF(!mSource))
|
||||
if (NS_WARN_IF(!mSource)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
nsresult rv = mSource->Close();
|
||||
mSource = 0;
|
||||
mSink = 0;
|
||||
|
@ -223,89 +234,95 @@ nsInputStreamTee::Close()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::Available(uint64_t *avail)
|
||||
nsInputStreamTee::Available(uint64_t* aAvail)
|
||||
{
|
||||
if (NS_WARN_IF(!mSource))
|
||||
if (NS_WARN_IF(!mSource)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
return mSource->Available(avail);
|
||||
}
|
||||
return mSource->Available(aAvail);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::Read(char *buf, uint32_t count, uint32_t *bytesRead)
|
||||
nsInputStreamTee::Read(char* aBuf, uint32_t aCount, uint32_t* aBytesRead)
|
||||
{
|
||||
if (NS_WARN_IF(!mSource))
|
||||
if (NS_WARN_IF(!mSource)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsresult rv = mSource->Read(buf, count, bytesRead);
|
||||
if (NS_FAILED(rv) || (*bytesRead == 0))
|
||||
nsresult rv = mSource->Read(aBuf, aCount, aBytesRead);
|
||||
if (NS_FAILED(rv) || (*aBytesRead == 0)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return TeeSegment(buf, *bytesRead);
|
||||
return TeeSegment(aBuf, *aBytesRead);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::ReadSegments(nsWriteSegmentFun writer,
|
||||
void *closure,
|
||||
uint32_t count,
|
||||
uint32_t *bytesRead)
|
||||
nsInputStreamTee::ReadSegments(nsWriteSegmentFun aWriter,
|
||||
void* aClosure,
|
||||
uint32_t aCount,
|
||||
uint32_t* aBytesRead)
|
||||
{
|
||||
if (NS_WARN_IF(!mSource))
|
||||
if (NS_WARN_IF(!mSource)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mWriter = writer;
|
||||
mClosure = closure;
|
||||
mWriter = aWriter;
|
||||
mClosure = aClosure;
|
||||
|
||||
return mSource->ReadSegments(WriteSegmentFun, this, count, bytesRead);
|
||||
return mSource->ReadSegments(WriteSegmentFun, this, aCount, aBytesRead);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::IsNonBlocking(bool *result)
|
||||
nsInputStreamTee::IsNonBlocking(bool* aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!mSource))
|
||||
if (NS_WARN_IF(!mSource)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
return mSource->IsNonBlocking(result);
|
||||
}
|
||||
return mSource->IsNonBlocking(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::SetSource(nsIInputStream *source)
|
||||
nsInputStreamTee::SetSource(nsIInputStream* aSource)
|
||||
{
|
||||
mSource = source;
|
||||
mSource = aSource;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::GetSource(nsIInputStream **source)
|
||||
nsInputStreamTee::GetSource(nsIInputStream** aSource)
|
||||
{
|
||||
NS_IF_ADDREF(*source = mSource);
|
||||
NS_IF_ADDREF(*aSource = mSource);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::SetSink(nsIOutputStream *sink)
|
||||
nsInputStreamTee::SetSink(nsIOutputStream* aSink)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (sink) {
|
||||
if (aSink) {
|
||||
bool nonBlocking;
|
||||
nsresult rv = sink->IsNonBlocking(&nonBlocking);
|
||||
if (NS_FAILED(rv) || nonBlocking)
|
||||
NS_ERROR("sink should be a blocking stream");
|
||||
nsresult rv = aSink->IsNonBlocking(&nonBlocking);
|
||||
if (NS_FAILED(rv) || nonBlocking) {
|
||||
NS_ERROR("aSink should be a blocking stream");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mSink = sink;
|
||||
mSink = aSink;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::GetSink(nsIOutputStream **sink)
|
||||
nsInputStreamTee::GetSink(nsIOutputStream** aSink)
|
||||
{
|
||||
NS_IF_ADDREF(*sink = mSink);
|
||||
NS_IF_ADDREF(*aSink = mSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::SetEventTarget(nsIEventTarget *anEventTarget)
|
||||
nsInputStreamTee::SetEventTarget(nsIEventTarget* aEventTarget)
|
||||
{
|
||||
mEventTarget = anEventTarget;
|
||||
mEventTarget = aEventTarget;
|
||||
if (mEventTarget) {
|
||||
// Only need synchronization if this is an async tee
|
||||
mLock = new Mutex("nsInputStreamTee.mLock");
|
||||
|
@ -314,44 +331,51 @@ nsInputStreamTee::SetEventTarget(nsIEventTarget *anEventTarget)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::GetEventTarget(nsIEventTarget **anEventTarget)
|
||||
nsInputStreamTee::GetEventTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
NS_IF_ADDREF(*anEventTarget = mEventTarget);
|
||||
NS_IF_ADDREF(*aEventTarget = mEventTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewInputStreamTeeAsync(nsIInputStream **result,
|
||||
nsIInputStream *source,
|
||||
nsIOutputStream *sink,
|
||||
nsIEventTarget *anEventTarget)
|
||||
NS_NewInputStreamTeeAsync(nsIInputStream** aResult,
|
||||
nsIInputStream* aSource,
|
||||
nsIOutputStream* aSink,
|
||||
nsIEventTarget* aEventTarget)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIInputStreamTee> tee = new nsInputStreamTee();
|
||||
if (!tee)
|
||||
if (!tee) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = tee->SetSource(source);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = tee->SetSource(aSource);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = tee->SetSink(sink);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = tee->SetSink(aSink);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = tee->SetEventTarget(anEventTarget);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = tee->SetEventTarget(aEventTarget);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(*result = tee);
|
||||
NS_ADDREF(*aResult = tee);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewInputStreamTee(nsIInputStream **result,
|
||||
nsIInputStream *source,
|
||||
nsIOutputStream *sink)
|
||||
NS_NewInputStreamTee(nsIInputStream** aResult,
|
||||
nsIInputStream* aSource,
|
||||
nsIOutputStream* aSink)
|
||||
{
|
||||
return NS_NewInputStreamTeeAsync(result, source, sink, nullptr);
|
||||
return NS_NewInputStreamTeeAsync(aResult, aSource, aSink, nullptr);
|
||||
}
|
||||
|
||||
#undef LOG
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
Could make this inline
|
||||
----------------------------------------------------------------------------*/
|
||||
static const char* GetLinebreakString(nsLinebreakConverter::ELinebreakType aBreakType)
|
||||
static const char*
|
||||
GetLinebreakString(nsLinebreakConverter::ELinebreakType aBreakType)
|
||||
{
|
||||
static const char* const sLinebreaks[] = {
|
||||
"", // any
|
||||
|
@ -38,12 +39,14 @@ static const char* GetLinebreakString(nsLinebreakConverter::ELinebreakType aBrea
|
|||
Wee inline method to append a line break. Modifies ioDest.
|
||||
----------------------------------------------------------------------------*/
|
||||
template<class T>
|
||||
void AppendLinebreak(T*& ioDest, const char* lineBreakStr)
|
||||
void
|
||||
AppendLinebreak(T*& aIoDest, const char* aLineBreakStr)
|
||||
{
|
||||
*ioDest++ = *lineBreakStr;
|
||||
*aIoDest++ = *aLineBreakStr;
|
||||
|
||||
if (lineBreakStr[1])
|
||||
*ioDest++ = lineBreakStr[1];
|
||||
if (aLineBreakStr[1]) {
|
||||
*aIoDest++ = aLineBreakStr[1];
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -52,33 +55,26 @@ void AppendLinebreak(T*& ioDest, const char* lineBreakStr)
|
|||
Counts occurrences of breakStr in aSrc
|
||||
----------------------------------------------------------------------------*/
|
||||
template<class T>
|
||||
int32_t CountLinebreaks(const T* aSrc, int32_t inLen, const char* breakStr)
|
||||
int32_t
|
||||
CountLinebreaks(const T* aSrc, int32_t aInLen, const char* aBreakStr)
|
||||
{
|
||||
const T* src = aSrc;
|
||||
const T* srcEnd = aSrc + inLen;
|
||||
const T* srcEnd = aSrc + aInLen;
|
||||
int32_t theCount = 0;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == *breakStr)
|
||||
{
|
||||
while (src < srcEnd) {
|
||||
if (*src == *aBreakStr) {
|
||||
src++;
|
||||
|
||||
if (breakStr[1])
|
||||
{
|
||||
if (src < srcEnd && *src == breakStr[1])
|
||||
{
|
||||
if (aBreakStr[1]) {
|
||||
if (src < srcEnd && *src == aBreakStr[1]) {
|
||||
src++;
|
||||
theCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
theCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
@ -93,87 +89,86 @@ int32_t CountLinebreaks(const T* aSrc, int32_t inLen, const char* breakStr)
|
|||
ioLen *includes* a terminating null, if any
|
||||
----------------------------------------------------------------------------*/
|
||||
template<class T>
|
||||
static T* ConvertBreaks(const T* inSrc, int32_t& ioLen, const char* srcBreak, const char* destBreak)
|
||||
static T*
|
||||
ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak,
|
||||
const char* aDestBreak)
|
||||
{
|
||||
NS_ASSERTION(inSrc && srcBreak && destBreak, "Got a null string");
|
||||
NS_ASSERTION(aInSrc && aSrcBreak && aDestBreak, "Got a null string");
|
||||
|
||||
T* resultString = nullptr;
|
||||
|
||||
// handle the no conversion case
|
||||
if (nsCRT::strcmp(srcBreak, destBreak) == 0)
|
||||
{
|
||||
resultString = (T *)nsMemory::Alloc(sizeof(T) * ioLen);
|
||||
if (!resultString) return nullptr;
|
||||
memcpy(resultString, inSrc, sizeof(T) * ioLen); // includes the null, if any
|
||||
if (nsCRT::strcmp(aSrcBreak, aDestBreak) == 0) {
|
||||
resultString = (T*)nsMemory::Alloc(sizeof(T) * aIoLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(resultString, aInSrc, sizeof(T) * aIoLen); // includes the null, if any
|
||||
return resultString;
|
||||
}
|
||||
|
||||
int32_t srcBreakLen = strlen(srcBreak);
|
||||
int32_t destBreakLen = strlen(destBreak);
|
||||
int32_t srcBreakLen = strlen(aSrcBreak);
|
||||
int32_t destBreakLen = strlen(aDestBreak);
|
||||
|
||||
// handle the easy case, where the string length does not change, and the
|
||||
// breaks are only 1 char long, i.e. CR <-> LF
|
||||
if (srcBreakLen == destBreakLen && srcBreakLen == 1)
|
||||
{
|
||||
resultString = (T *)nsMemory::Alloc(sizeof(T) * ioLen);
|
||||
if (!resultString) return nullptr;
|
||||
if (srcBreakLen == destBreakLen && srcBreakLen == 1) {
|
||||
resultString = (T*)nsMemory::Alloc(sizeof(T) * aIoLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const T* src = inSrc;
|
||||
const T* srcEnd = inSrc + ioLen; // includes null, if any
|
||||
T* dst = resultString;
|
||||
const T* src = aInSrc;
|
||||
const T* srcEnd = aInSrc + aIoLen; // includes null, if any
|
||||
T* dst = resultString;
|
||||
|
||||
char srcBreakChar = *srcBreak; // we know it's one char long already
|
||||
char dstBreakChar = *destBreak;
|
||||
char srcBreakChar = *aSrcBreak; // we know it's one char long already
|
||||
char dstBreakChar = *aDestBreak;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == srcBreakChar)
|
||||
{
|
||||
while (src < srcEnd) {
|
||||
if (*src == srcBreakChar) {
|
||||
*dst++ = dstBreakChar;
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
// ioLen does not change
|
||||
}
|
||||
else
|
||||
{
|
||||
// aIoLen does not change
|
||||
} else {
|
||||
// src and dest termination is different length. Do it a slower way.
|
||||
|
||||
// count linebreaks in src. Assumes that chars in 2-char linebreaks are unique.
|
||||
int32_t numLinebreaks = CountLinebreaks(inSrc, ioLen, srcBreak);
|
||||
int32_t numLinebreaks = CountLinebreaks(aInSrc, aIoLen, aSrcBreak);
|
||||
|
||||
int32_t newBufLen = ioLen - (numLinebreaks * srcBreakLen) + (numLinebreaks * destBreakLen);
|
||||
resultString = (T *)nsMemory::Alloc(sizeof(T) * newBufLen);
|
||||
if (!resultString) return nullptr;
|
||||
int32_t newBufLen =
|
||||
aIoLen - (numLinebreaks * srcBreakLen) + (numLinebreaks * destBreakLen);
|
||||
resultString = (T*)nsMemory::Alloc(sizeof(T) * newBufLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const T* src = inSrc;
|
||||
const T* srcEnd = inSrc + ioLen; // includes null, if any
|
||||
T* dst = resultString;
|
||||
const T* src = aInSrc;
|
||||
const T* srcEnd = aInSrc + aIoLen; // includes null, if any
|
||||
T* dst = resultString;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == *srcBreak)
|
||||
{
|
||||
*dst++ = *destBreak;
|
||||
if (destBreak[1])
|
||||
*dst++ = destBreak[1];
|
||||
while (src < srcEnd) {
|
||||
if (*src == *aSrcBreak) {
|
||||
*dst++ = *aDestBreak;
|
||||
if (aDestBreak[1]) {
|
||||
*dst++ = aDestBreak[1];
|
||||
}
|
||||
|
||||
src++;
|
||||
if (src < srcEnd && srcBreak[1] && *src == srcBreak[1])
|
||||
if (src < srcEnd && aSrcBreak[1] && *src == aSrcBreak[1]) {
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
} else {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
ioLen = newBufLen;
|
||||
aIoLen = newBufLen;
|
||||
}
|
||||
|
||||
return resultString;
|
||||
|
@ -187,15 +182,16 @@ static T* ConvertBreaks(const T* inSrc, int32_t& ioLen, const char* srcBreak, co
|
|||
does not change.
|
||||
----------------------------------------------------------------------------*/
|
||||
template<class T>
|
||||
static void ConvertBreaksInSitu(T* inSrc, int32_t inLen, char srcBreak, char destBreak)
|
||||
static void
|
||||
ConvertBreaksInSitu(T* aInSrc, int32_t aInLen, char aSrcBreak, char aDestBreak)
|
||||
{
|
||||
T* src = inSrc;
|
||||
T* srcEnd = inSrc + inLen;
|
||||
T* src = aInSrc;
|
||||
T* srcEnd = aInSrc + aInLen;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == srcBreak)
|
||||
*src = destBreak;
|
||||
while (src < srcEnd) {
|
||||
if (*src == aSrcBreak) {
|
||||
*src = aDestBreak;
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
|
@ -210,79 +206,64 @@ static void ConvertBreaksInSitu(T* inSrc, int32_t inLen, char srcBreak, char des
|
|||
This will convert CRLF pairs to one break, and single CR or LF to a break.
|
||||
----------------------------------------------------------------------------*/
|
||||
template<class T>
|
||||
static T* ConvertUnknownBreaks(const T* inSrc, int32_t& ioLen, const char* destBreak)
|
||||
static T*
|
||||
ConvertUnknownBreaks(const T* aInSrc, int32_t& aIoLen, const char* aDestBreak)
|
||||
{
|
||||
const T* src = inSrc;
|
||||
const T* srcEnd = inSrc + ioLen; // includes null, if any
|
||||
const T* src = aInSrc;
|
||||
const T* srcEnd = aInSrc + aIoLen; // includes null, if any
|
||||
|
||||
int32_t destBreakLen = strlen(destBreak);
|
||||
int32_t destBreakLen = strlen(aDestBreak);
|
||||
int32_t finalLen = 0;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == nsCRT::CR)
|
||||
{
|
||||
if (src < srcEnd && src[1] == nsCRT::LF)
|
||||
{
|
||||
while (src < srcEnd) {
|
||||
if (*src == nsCRT::CR) {
|
||||
if (src < srcEnd && src[1] == nsCRT::LF) {
|
||||
// CRLF
|
||||
finalLen += destBreakLen;
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Lone CR
|
||||
finalLen += destBreakLen;
|
||||
}
|
||||
}
|
||||
else if (*src == nsCRT::LF)
|
||||
{
|
||||
} else if (*src == nsCRT::LF) {
|
||||
// Lone LF
|
||||
finalLen += destBreakLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
finalLen++;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
|
||||
T* resultString = (T *)nsMemory::Alloc(sizeof(T) * finalLen);
|
||||
if (!resultString) return nullptr;
|
||||
T* resultString = (T*)nsMemory::Alloc(sizeof(T) * finalLen);
|
||||
if (!resultString) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
src = inSrc;
|
||||
srcEnd = inSrc + ioLen; // includes null, if any
|
||||
src = aInSrc;
|
||||
srcEnd = aInSrc + aIoLen; // includes null, if any
|
||||
|
||||
T* dst = resultString;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
if (*src == nsCRT::CR)
|
||||
{
|
||||
if (src < srcEnd && src[1] == nsCRT::LF)
|
||||
{
|
||||
while (src < srcEnd) {
|
||||
if (*src == nsCRT::CR) {
|
||||
if (src < srcEnd && src[1] == nsCRT::LF) {
|
||||
// CRLF
|
||||
AppendLinebreak(dst, destBreak);
|
||||
AppendLinebreak(dst, aDestBreak);
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Lone CR
|
||||
AppendLinebreak(dst, destBreak);
|
||||
AppendLinebreak(dst, aDestBreak);
|
||||
}
|
||||
}
|
||||
else if (*src == nsCRT::LF)
|
||||
{
|
||||
} else if (*src == nsCRT::LF) {
|
||||
// Lone LF
|
||||
AppendLinebreak(dst, destBreak);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendLinebreak(dst, aDestBreak);
|
||||
} else {
|
||||
*dst++ = *src;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
|
||||
ioLen = finalLen;
|
||||
aIoLen = finalLen;
|
||||
return resultString;
|
||||
}
|
||||
|
||||
|
@ -291,23 +272,31 @@ static T* ConvertUnknownBreaks(const T* inSrc, int32_t& ioLen, const char* destB
|
|||
ConvertLineBreaks
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
char* nsLinebreakConverter::ConvertLineBreaks(const char* aSrc,
|
||||
ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks, int32_t aSrcLen, int32_t* outLen)
|
||||
char*
|
||||
nsLinebreakConverter::ConvertLineBreaks(const char* aSrc,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen, int32_t* aOutLen)
|
||||
{
|
||||
NS_ASSERTION(aDestBreaks != eLinebreakAny &&
|
||||
aSrcBreaks != eLinebreakSpace, "Invalid parameter");
|
||||
if (!aSrc) return nullptr;
|
||||
if (!aSrc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t sourceLen = (aSrcLen == kIgnoreLen) ? strlen(aSrc) + 1 : aSrcLen;
|
||||
|
||||
char* resultString;
|
||||
if (aSrcBreaks == eLinebreakAny)
|
||||
if (aSrcBreaks == eLinebreakAny) {
|
||||
resultString = ConvertUnknownBreaks(aSrc, sourceLen, GetLinebreakString(aDestBreaks));
|
||||
else
|
||||
resultString = ConvertBreaks(aSrc, sourceLen, GetLinebreakString(aSrcBreaks), GetLinebreakString(aDestBreaks));
|
||||
} else
|
||||
resultString = ConvertBreaks(aSrc, sourceLen,
|
||||
GetLinebreakString(aSrcBreaks),
|
||||
GetLinebreakString(aDestBreaks));
|
||||
|
||||
if (outLen)
|
||||
*outLen = sourceLen;
|
||||
if (aOutLen) {
|
||||
*aOutLen = sourceLen;
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
|
@ -316,42 +305,49 @@ char* nsLinebreakConverter::ConvertLineBreaks(const char* aSrc,
|
|||
ConvertLineBreaksInSitu
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
nsresult nsLinebreakConverter::ConvertLineBreaksInSitu(char **ioBuffer, ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks, int32_t aSrcLen, int32_t* outLen)
|
||||
nsresult
|
||||
nsLinebreakConverter::ConvertLineBreaksInSitu(char** aIoBuffer,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen, int32_t* aOutLen)
|
||||
{
|
||||
NS_ASSERTION(ioBuffer && *ioBuffer, "Null pointer passed");
|
||||
if (!ioBuffer || !*ioBuffer) return NS_ERROR_NULL_POINTER;
|
||||
NS_ASSERTION(aIoBuffer && *aIoBuffer, "Null pointer passed");
|
||||
if (!aIoBuffer || !*aIoBuffer) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aDestBreaks != eLinebreakAny &&
|
||||
aSrcBreaks != eLinebreakSpace, "Invalid parameter");
|
||||
|
||||
int32_t sourceLen = (aSrcLen == kIgnoreLen) ? strlen(*ioBuffer) + 1 : aSrcLen;
|
||||
int32_t sourceLen = (aSrcLen == kIgnoreLen) ? strlen(*aIoBuffer) + 1 : aSrcLen;
|
||||
|
||||
// can we convert in-place?
|
||||
const char* srcBreaks = GetLinebreakString(aSrcBreaks);
|
||||
const char* dstBreaks = GetLinebreakString(aDestBreaks);
|
||||
|
||||
if ( (aSrcBreaks != eLinebreakAny) &&
|
||||
(strlen(srcBreaks) == 1) &&
|
||||
(strlen(dstBreaks) == 1) )
|
||||
{
|
||||
ConvertBreaksInSitu(*ioBuffer, sourceLen, *srcBreaks, *dstBreaks);
|
||||
if (outLen)
|
||||
*outLen = sourceLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aSrcBreaks != eLinebreakAny &&
|
||||
strlen(srcBreaks) == 1 &&
|
||||
strlen(dstBreaks) == 1) {
|
||||
ConvertBreaksInSitu(*aIoBuffer, sourceLen, *srcBreaks, *dstBreaks);
|
||||
if (aOutLen) {
|
||||
*aOutLen = sourceLen;
|
||||
}
|
||||
} else {
|
||||
char* destBuffer;
|
||||
|
||||
if (aSrcBreaks == eLinebreakAny)
|
||||
destBuffer = ConvertUnknownBreaks(*ioBuffer, sourceLen, dstBreaks);
|
||||
else
|
||||
destBuffer = ConvertBreaks(*ioBuffer, sourceLen, srcBreaks, dstBreaks);
|
||||
if (aSrcBreaks == eLinebreakAny) {
|
||||
destBuffer = ConvertUnknownBreaks(*aIoBuffer, sourceLen, dstBreaks);
|
||||
} else {
|
||||
destBuffer = ConvertBreaks(*aIoBuffer, sourceLen, srcBreaks, dstBreaks);
|
||||
}
|
||||
|
||||
if (!destBuffer) return NS_ERROR_OUT_OF_MEMORY;
|
||||
*ioBuffer = destBuffer;
|
||||
if (outLen)
|
||||
*outLen = sourceLen;
|
||||
if (!destBuffer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aIoBuffer = destBuffer;
|
||||
if (aOutLen) {
|
||||
*aOutLen = sourceLen;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -362,23 +358,31 @@ nsresult nsLinebreakConverter::ConvertLineBreaksInSitu(char **ioBuffer, ELinebre
|
|||
ConvertUnicharLineBreaks
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
char16_t* nsLinebreakConverter::ConvertUnicharLineBreaks(const char16_t* aSrc,
|
||||
ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks, int32_t aSrcLen, int32_t* outLen)
|
||||
char16_t*
|
||||
nsLinebreakConverter::ConvertUnicharLineBreaks(const char16_t* aSrc,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen,
|
||||
int32_t* aOutLen)
|
||||
{
|
||||
NS_ASSERTION(aDestBreaks != eLinebreakAny &&
|
||||
aSrcBreaks != eLinebreakSpace, "Invalid parameter");
|
||||
if (!aSrc) return nullptr;
|
||||
if (!aSrc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t bufLen = (aSrcLen == kIgnoreLen) ? NS_strlen(aSrc) + 1 : aSrcLen;
|
||||
|
||||
char16_t* resultString;
|
||||
if (aSrcBreaks == eLinebreakAny)
|
||||
if (aSrcBreaks == eLinebreakAny) {
|
||||
resultString = ConvertUnknownBreaks(aSrc, bufLen, GetLinebreakString(aDestBreaks));
|
||||
else
|
||||
resultString = ConvertBreaks(aSrc, bufLen, GetLinebreakString(aSrcBreaks), GetLinebreakString(aDestBreaks));
|
||||
} else
|
||||
resultString = ConvertBreaks(aSrc, bufLen, GetLinebreakString(aSrcBreaks),
|
||||
GetLinebreakString(aDestBreaks));
|
||||
|
||||
if (outLen)
|
||||
*outLen = bufLen;
|
||||
if (aOutLen) {
|
||||
*aOutLen = bufLen;
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
|
@ -387,41 +391,48 @@ char16_t* nsLinebreakConverter::ConvertUnicharLineBreaks(const char16_t* aSrc,
|
|||
ConvertStringLineBreaks
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
nsresult nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(char16_t **ioBuffer,
|
||||
ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks, int32_t aSrcLen, int32_t* outLen)
|
||||
nsresult
|
||||
nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(
|
||||
char16_t** aIoBuffer, ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen, int32_t* aOutLen)
|
||||
{
|
||||
NS_ASSERTION(ioBuffer && *ioBuffer, "Null pointer passed");
|
||||
if (!ioBuffer || !*ioBuffer) return NS_ERROR_NULL_POINTER;
|
||||
NS_ASSERTION(aIoBuffer && *aIoBuffer, "Null pointer passed");
|
||||
if (!aIoBuffer || !*aIoBuffer) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_ASSERTION(aDestBreaks != eLinebreakAny &&
|
||||
aSrcBreaks != eLinebreakSpace, "Invalid parameter");
|
||||
|
||||
int32_t sourceLen = (aSrcLen == kIgnoreLen) ? NS_strlen(*ioBuffer) + 1 : aSrcLen;
|
||||
int32_t sourceLen =
|
||||
(aSrcLen == kIgnoreLen) ? NS_strlen(*aIoBuffer) + 1 : aSrcLen;
|
||||
|
||||
// can we convert in-place?
|
||||
const char* srcBreaks = GetLinebreakString(aSrcBreaks);
|
||||
const char* dstBreaks = GetLinebreakString(aDestBreaks);
|
||||
|
||||
if ( (aSrcBreaks != eLinebreakAny) &&
|
||||
(strlen(srcBreaks) == 1) &&
|
||||
(strlen(dstBreaks) == 1) )
|
||||
{
|
||||
ConvertBreaksInSitu(*ioBuffer, sourceLen, *srcBreaks, *dstBreaks);
|
||||
if (outLen)
|
||||
*outLen = sourceLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((aSrcBreaks != eLinebreakAny) &&
|
||||
(strlen(srcBreaks) == 1) &&
|
||||
(strlen(dstBreaks) == 1)) {
|
||||
ConvertBreaksInSitu(*aIoBuffer, sourceLen, *srcBreaks, *dstBreaks);
|
||||
if (aOutLen) {
|
||||
*aOutLen = sourceLen;
|
||||
}
|
||||
} else {
|
||||
char16_t* destBuffer;
|
||||
|
||||
if (aSrcBreaks == eLinebreakAny)
|
||||
destBuffer = ConvertUnknownBreaks(*ioBuffer, sourceLen, dstBreaks);
|
||||
else
|
||||
destBuffer = ConvertBreaks(*ioBuffer, sourceLen, srcBreaks, dstBreaks);
|
||||
if (aSrcBreaks == eLinebreakAny) {
|
||||
destBuffer = ConvertUnknownBreaks(*aIoBuffer, sourceLen, dstBreaks);
|
||||
} else {
|
||||
destBuffer = ConvertBreaks(*aIoBuffer, sourceLen, srcBreaks, dstBreaks);
|
||||
}
|
||||
|
||||
if (!destBuffer) return NS_ERROR_OUT_OF_MEMORY;
|
||||
*ioBuffer = destBuffer;
|
||||
if (outLen)
|
||||
*outLen = sourceLen;
|
||||
if (!destBuffer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aIoBuffer = destBuffer;
|
||||
if (aOutLen) {
|
||||
*aOutLen = sourceLen;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -431,32 +442,39 @@ nsresult nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(char16_t **ioBuffe
|
|||
ConvertStringLineBreaks
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
nsresult nsLinebreakConverter::ConvertStringLineBreaks(nsString& ioString,
|
||||
ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks)
|
||||
nsresult
|
||||
nsLinebreakConverter::ConvertStringLineBreaks(nsString& aIoString,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks)
|
||||
{
|
||||
|
||||
NS_ASSERTION(aDestBreaks != eLinebreakAny &&
|
||||
aSrcBreaks != eLinebreakSpace, "Invalid parameter");
|
||||
|
||||
// nothing to do
|
||||
if (ioString.IsEmpty()) return NS_OK;
|
||||
if (aIoString.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// remember the old buffer in case
|
||||
// we blow it away later
|
||||
nsString::char_iterator stringBuf;
|
||||
ioString.BeginWriting(stringBuf);
|
||||
aIoString.BeginWriting(stringBuf);
|
||||
|
||||
int32_t newLen;
|
||||
|
||||
rv = ConvertUnicharLineBreaksInSitu(&stringBuf,
|
||||
aSrcBreaks, aDestBreaks,
|
||||
ioString.Length() + 1, &newLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aIoString.Length() + 1, &newLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (stringBuf != ioString.get())
|
||||
ioString.Adopt(stringBuf);
|
||||
if (stringBuf != aIoString.get()) {
|
||||
aIoString.Adopt(stringBuf);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,9 @@ public:
|
|||
* @param aSrcLen: length of the source, in characters. If -1, the source is assumed to be a null-
|
||||
* terminated string.
|
||||
*/
|
||||
static nsresult ConvertStringLineBreaks(nsString& ioString, ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks);
|
||||
static nsresult ConvertStringLineBreaks(nsString& aIoString,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks);
|
||||
|
||||
|
||||
/* ConvertLineBreaksInSitu
|
||||
|
@ -96,8 +98,11 @@ public:
|
|||
* terminated string.
|
||||
* @param aOutLen: used to return character length of returned buffer, if not null.
|
||||
*/
|
||||
static nsresult ConvertLineBreaksInSitu(char **ioBuffer, ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen = kIgnoreLen, int32_t* aOutLen = nullptr);
|
||||
static nsresult ConvertLineBreaksInSitu(char** aIoBuffer,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen = kIgnoreLen,
|
||||
int32_t* aOutLen = nullptr);
|
||||
|
||||
|
||||
/* ConvertUnicharLineBreaksInSitu
|
||||
|
@ -114,8 +119,11 @@ public:
|
|||
* terminated string.
|
||||
* @param aOutLen: used to return character length of returned buffer, if not null.
|
||||
*/
|
||||
static nsresult ConvertUnicharLineBreaksInSitu(char16_t **ioBuffer, ELinebreakType aSrcBreaks, ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen = kIgnoreLen, int32_t* aOutLen = nullptr);
|
||||
static nsresult ConvertUnicharLineBreaksInSitu(char16_t** aIoBuffer,
|
||||
ELinebreakType aSrcBreaks,
|
||||
ELinebreakType aDestBreaks,
|
||||
int32_t aSrcLen = kIgnoreLen,
|
||||
int32_t* aOutLen = nullptr);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@
|
|||
#define NSRESULT_FOR_RETURN(ret) (((ret) < 0) ? NSRESULT_FOR_ERRNO() : NS_OK)
|
||||
|
||||
inline nsresult
|
||||
nsresultForErrno(int err)
|
||||
nsresultForErrno(int aErr)
|
||||
{
|
||||
switch (err) {
|
||||
switch (aErr) {
|
||||
case 0:
|
||||
return NS_OK;
|
||||
#ifdef EDQUOT
|
||||
|
|
|
@ -21,27 +21,31 @@
|
|||
#endif
|
||||
|
||||
|
||||
void NS_StartupLocalFile()
|
||||
void
|
||||
NS_StartupLocalFile()
|
||||
{
|
||||
nsLocalFile::GlobalInit();
|
||||
}
|
||||
|
||||
void NS_ShutdownLocalFile()
|
||||
void
|
||||
NS_ShutdownLocalFile()
|
||||
{
|
||||
nsLocalFile::GlobalShutdown();
|
||||
}
|
||||
|
||||
#if !defined(MOZ_WIDGET_COCOA) && !defined(XP_WIN)
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::InitWithFile(nsIFile *aFile)
|
||||
nsLocalFile::InitWithFile(nsIFile* aFile)
|
||||
{
|
||||
if (NS_WARN_IF(!aFile))
|
||||
if (NS_WARN_IF(!aFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsAutoCString path;
|
||||
aFile->GetNativePath(path);
|
||||
if (path.IsEmpty())
|
||||
if (path.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return InitWithNativePath(path);
|
||||
}
|
||||
#endif
|
||||
|
@ -52,7 +56,7 @@ nsLocalFile::InitWithFile(nsIFile *aFile)
|
|||
// requirement: kMaxExtensionLength < kMaxFilenameLength - kMaxSequenceNumberLength
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
|
||||
nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes)
|
||||
{
|
||||
nsresult rv;
|
||||
bool longName;
|
||||
|
@ -64,44 +68,43 @@ nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
|
|||
nsAutoCString pathName, leafName, rootName, suffix;
|
||||
rv = GetNativePath(pathName);
|
||||
#endif
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
longName = (pathName.Length() + kMaxSequenceNumberLength >
|
||||
kMaxFilenameLength);
|
||||
if (!longName)
|
||||
{
|
||||
rv = Create(type, attributes);
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
|
||||
if (!longName) {
|
||||
rv = Create(aType, aAttributes);
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
rv = GetLeafName(leafName);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
const int32_t lastDot = leafName.RFindChar(char16_t('.'));
|
||||
#else
|
||||
rv = GetNativeLeafName(leafName);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
const int32_t lastDot = leafName.RFindChar('.');
|
||||
#endif
|
||||
|
||||
if (lastDot == kNotFound)
|
||||
{
|
||||
if (lastDot == kNotFound) {
|
||||
rootName = leafName;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
suffix = Substring(leafName, lastDot); // include '.'
|
||||
rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
|
||||
}
|
||||
|
||||
if (longName)
|
||||
{
|
||||
if (longName) {
|
||||
int32_t maxRootLength = (kMaxFilenameLength -
|
||||
(pathName.Length() - leafName.Length()) -
|
||||
suffix.Length() - kMaxSequenceNumberLength);
|
||||
|
@ -109,8 +112,9 @@ nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
|
|||
// We cannot create an item inside a directory whose name is too long.
|
||||
// Also, ensure that at least one character remains after we truncate
|
||||
// the root name, as we don't want to end up with an empty leaf name.
|
||||
if (maxRootLength < 2)
|
||||
if (maxRootLength < 2) {
|
||||
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// ensure that we don't cut the name in mid-UTF16-character
|
||||
|
@ -118,28 +122,29 @@ nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
|
|||
maxRootLength - 1 : maxRootLength);
|
||||
SetLeafName(rootName + suffix);
|
||||
#else
|
||||
if (NS_IsNativeUTF8())
|
||||
{
|
||||
if (NS_IsNativeUTF8()) {
|
||||
// ensure that we don't cut the name in mid-UTF8-character
|
||||
// (assume the name is valid UTF8 to begin with)
|
||||
while (UTF8traits::isInSeq(rootName[maxRootLength]))
|
||||
while (UTF8traits::isInSeq(rootName[maxRootLength])) {
|
||||
--maxRootLength;
|
||||
}
|
||||
|
||||
// Another check to avoid ending up with an empty leaf name.
|
||||
if (maxRootLength == 0 && suffix.IsEmpty())
|
||||
if (maxRootLength == 0 && suffix.IsEmpty()) {
|
||||
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
rootName.SetLength(maxRootLength);
|
||||
SetNativeLeafName(rootName + suffix);
|
||||
#endif
|
||||
nsresult rv = Create(type, attributes);
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
|
||||
nsresult rv = Create(aType, aAttributes);
|
||||
if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
for (int indx = 1; indx < 10000; indx++)
|
||||
{
|
||||
for (int indx = 1; indx < 10000; ++indx) {
|
||||
// start with "Picture-1.jpg" after "Picture.jpg" exists
|
||||
#ifdef XP_WIN
|
||||
SetLeafName(rootName +
|
||||
|
@ -148,9 +153,10 @@ nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
|
|||
#else
|
||||
SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
|
||||
#endif
|
||||
rv = Create(type, attributes);
|
||||
if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS)
|
||||
rv = Create(aType, aAttributes);
|
||||
if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// The disk is full, sort of
|
||||
|
@ -165,104 +171,122 @@ static const char16_t kPathSeparatorChar = '/';
|
|||
#error Need to define file path separator for your platform
|
||||
#endif
|
||||
|
||||
static int32_t SplitPath(char16_t *path, char16_t **nodeArray, int32_t arrayLen)
|
||||
static int32_t
|
||||
SplitPath(char16_t* aPath, char16_t** aNodeArray, int32_t aArrayLen)
|
||||
{
|
||||
if (*path == 0)
|
||||
if (*aPath == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char16_t **nodePtr = nodeArray;
|
||||
if (*path == kPathSeparatorChar)
|
||||
path++;
|
||||
*nodePtr++ = path;
|
||||
char16_t** nodePtr = aNodeArray;
|
||||
if (*aPath == kPathSeparatorChar) {
|
||||
aPath++;
|
||||
}
|
||||
*nodePtr++ = aPath;
|
||||
|
||||
for (char16_t *cp = path; *cp != 0; cp++) {
|
||||
for (char16_t* cp = aPath; *cp != 0; ++cp) {
|
||||
if (*cp == kPathSeparatorChar) {
|
||||
*cp++ = 0;
|
||||
if (*cp == 0)
|
||||
if (*cp == 0) {
|
||||
break;
|
||||
if (nodePtr - nodeArray >= arrayLen)
|
||||
}
|
||||
if (nodePtr - aNodeArray >= aArrayLen) {
|
||||
return -1;
|
||||
}
|
||||
*nodePtr++ = cp;
|
||||
}
|
||||
}
|
||||
return nodePtr - nodeArray;
|
||||
return nodePtr - aNodeArray;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetRelativeDescriptor(nsIFile *fromFile, nsACString& _retval)
|
||||
nsLocalFile::GetRelativeDescriptor(nsIFile* aFromFile, nsACString& aResult)
|
||||
{
|
||||
if (NS_WARN_IF(!fromFile))
|
||||
if (NS_WARN_IF(!aFromFile)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
const int32_t kMaxNodesInPath = 32;
|
||||
|
||||
//
|
||||
// _retval will be UTF-8 encoded
|
||||
// aResult will be UTF-8 encoded
|
||||
//
|
||||
|
||||
nsresult rv;
|
||||
_retval.Truncate(0);
|
||||
aResult.Truncate(0);
|
||||
|
||||
nsAutoString thisPath, fromPath;
|
||||
char16_t *thisNodes[kMaxNodesInPath], *fromNodes[kMaxNodesInPath];
|
||||
int32_t thisNodeCnt, fromNodeCnt, nodeIndex;
|
||||
char16_t* thisNodes[kMaxNodesInPath];
|
||||
char16_t* fromNodes[kMaxNodesInPath];
|
||||
int32_t thisNodeCnt, fromNodeCnt, nodeIndex;
|
||||
|
||||
rv = GetPath(thisPath);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
rv = fromFile->GetPath(fromPath);
|
||||
if (NS_FAILED(rv))
|
||||
}
|
||||
rv = aFromFile->GetPath(fromPath);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// get raw pointer to mutable string buffer
|
||||
char16_t *thisPathPtr; thisPath.BeginWriting(thisPathPtr);
|
||||
char16_t *fromPathPtr; fromPath.BeginWriting(fromPathPtr);
|
||||
char16_t* thisPathPtr;
|
||||
thisPath.BeginWriting(thisPathPtr);
|
||||
char16_t* fromPathPtr;
|
||||
fromPath.BeginWriting(fromPathPtr);
|
||||
|
||||
thisNodeCnt = SplitPath(thisPathPtr, thisNodes, kMaxNodesInPath);
|
||||
fromNodeCnt = SplitPath(fromPathPtr, fromNodes, kMaxNodesInPath);
|
||||
if (thisNodeCnt < 0 || fromNodeCnt < 0)
|
||||
if (thisNodeCnt < 0 || fromNodeCnt < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
for (nodeIndex = 0; nodeIndex < thisNodeCnt && nodeIndex < fromNodeCnt; ++nodeIndex) {
|
||||
#ifdef XP_WIN
|
||||
if (_wcsicmp(char16ptr_t(thisNodes[nodeIndex]), char16ptr_t(fromNodes[nodeIndex])))
|
||||
if (_wcsicmp(char16ptr_t(thisNodes[nodeIndex]), char16ptr_t(fromNodes[nodeIndex]))) {
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (nsCRT::strcmp(thisNodes[nodeIndex], fromNodes[nodeIndex]))
|
||||
if (nsCRT::strcmp(thisNodes[nodeIndex], fromNodes[nodeIndex])) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t branchIndex = nodeIndex;
|
||||
for (nodeIndex = branchIndex; nodeIndex < fromNodeCnt; nodeIndex++)
|
||||
_retval.AppendLiteral("../");
|
||||
for (nodeIndex = branchIndex; nodeIndex < fromNodeCnt; ++nodeIndex) {
|
||||
aResult.AppendLiteral("../");
|
||||
}
|
||||
for (nodeIndex = branchIndex; nodeIndex < thisNodeCnt; nodeIndex++) {
|
||||
NS_ConvertUTF16toUTF8 nodeStr(thisNodes[nodeIndex]);
|
||||
_retval.Append(nodeStr);
|
||||
if (nodeIndex + 1 < thisNodeCnt)
|
||||
_retval.Append('/');
|
||||
aResult.Append(nodeStr);
|
||||
if (nodeIndex + 1 < thisNodeCnt) {
|
||||
aResult.Append('/');
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetRelativeDescriptor(nsIFile *fromFile, const nsACString& relativeDesc)
|
||||
nsLocalFile::SetRelativeDescriptor(nsIFile* aFromFile,
|
||||
const nsACString& aRelativeDesc)
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(kParentDirStr, "../");
|
||||
|
||||
nsCOMPtr<nsIFile> targetFile;
|
||||
nsresult rv = fromFile->Clone(getter_AddRefs(targetFile));
|
||||
if (NS_FAILED(rv))
|
||||
nsresult rv = aFromFile->Clone(getter_AddRefs(targetFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
// relativeDesc is UTF-8 encoded
|
||||
// aRelativeDesc is UTF-8 encoded
|
||||
//
|
||||
|
||||
nsCString::const_iterator strBegin, strEnd;
|
||||
relativeDesc.BeginReading(strBegin);
|
||||
relativeDesc.EndReading(strEnd);
|
||||
aRelativeDesc.BeginReading(strBegin);
|
||||
aRelativeDesc.EndReading(strEnd);
|
||||
|
||||
nsCString::const_iterator nodeBegin(strBegin), nodeEnd(strEnd);
|
||||
nsCString::const_iterator pos(strBegin);
|
||||
|
@ -270,10 +294,12 @@ nsLocalFile::SetRelativeDescriptor(nsIFile *fromFile, const nsACString& relative
|
|||
nsCOMPtr<nsIFile> parentDir;
|
||||
while (FindInReadable(kParentDirStr, nodeBegin, nodeEnd)) {
|
||||
rv = targetFile->GetParent(getter_AddRefs(parentDir));
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!parentDir)
|
||||
}
|
||||
if (!parentDir) {
|
||||
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
|
||||
}
|
||||
targetFile = parentDir;
|
||||
|
||||
nodeBegin = nodeEnd;
|
||||
|
@ -285,8 +311,9 @@ nsLocalFile::SetRelativeDescriptor(nsIFile *fromFile, const nsACString& relative
|
|||
while (nodeEnd != strEnd) {
|
||||
FindCharInReadable('/', nodeEnd, strEnd);
|
||||
targetFile->Append(NS_ConvertUTF8toUTF16(Substring(nodeBegin, nodeEnd)));
|
||||
if (nodeEnd != strEnd) // If there's more left in the string, inc over the '/' nodeEnd is on.
|
||||
if (nodeEnd != strEnd) { // If there's more left in the string, inc over the '/' nodeEnd is on.
|
||||
++nodeEnd;
|
||||
}
|
||||
nodeBegin = nodeEnd;
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -79,20 +79,22 @@
|
|||
#endif
|
||||
|
||||
|
||||
class nsLocalFile MOZ_FINAL :
|
||||
class nsLocalFile MOZ_FINAL
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
public nsILocalFileMac,
|
||||
: public nsILocalFileMac
|
||||
#else
|
||||
public nsILocalFile,
|
||||
: public nsILocalFile
|
||||
#endif
|
||||
public nsIHashable
|
||||
, public nsIHashable
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR(NS_LOCAL_FILE_CID)
|
||||
|
||||
nsLocalFile();
|
||||
|
||||
static nsresult nsLocalFileConstructor(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
static nsresult nsLocalFileConstructor(nsISupports* aOuter,
|
||||
const nsIID& aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIFILE
|
||||
|
@ -107,8 +109,10 @@ public:
|
|||
static void GlobalShutdown();
|
||||
|
||||
private:
|
||||
nsLocalFile(const nsLocalFile& other);
|
||||
~nsLocalFile() {}
|
||||
nsLocalFile(const nsLocalFile& aOther);
|
||||
~nsLocalFile()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// This stat cache holds the *last stat* - it does not invalidate.
|
||||
|
@ -116,19 +120,19 @@ protected:
|
|||
struct STAT mCachedStat;
|
||||
nsCString mPath;
|
||||
|
||||
void LocateNativeLeafName(nsACString::const_iterator &,
|
||||
nsACString::const_iterator &);
|
||||
void LocateNativeLeafName(nsACString::const_iterator&,
|
||||
nsACString::const_iterator&);
|
||||
|
||||
nsresult CopyDirectoryTo(nsIFile *newParent);
|
||||
nsresult CreateAllAncestors(uint32_t permissions);
|
||||
nsresult GetNativeTargetPathName(nsIFile *newParent,
|
||||
const nsACString &newName,
|
||||
nsACString &_retval);
|
||||
nsresult CopyDirectoryTo(nsIFile* aNewParent);
|
||||
nsresult CreateAllAncestors(uint32_t aPermissions);
|
||||
nsresult GetNativeTargetPathName(nsIFile* aNewParent,
|
||||
const nsACString& aNewName,
|
||||
nsACString& aResult);
|
||||
|
||||
bool FillStatCache();
|
||||
|
||||
nsresult CreateAndKeepOpen(uint32_t type, int flags,
|
||||
uint32_t permissions, PRFileDesc **_retval);
|
||||
nsresult CreateAndKeepOpen(uint32_t aType, int aFlags,
|
||||
uint32_t aPermissions, PRFileDesc** aResult);
|
||||
};
|
||||
|
||||
#endif /* _nsLocalFileUNIX_H_ */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -25,15 +25,18 @@
|
|||
|
||||
#include <sys/stat.h>
|
||||
|
||||
class nsLocalFile MOZ_FINAL : public nsILocalFileWin,
|
||||
public nsIHashable
|
||||
class nsLocalFile MOZ_FINAL
|
||||
: public nsILocalFileWin
|
||||
, public nsIHashable
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR(NS_LOCAL_FILE_CID)
|
||||
|
||||
nsLocalFile();
|
||||
|
||||
static nsresult nsLocalFileConstructor(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
static nsresult nsLocalFileConstructor(nsISupports* aOuter,
|
||||
const nsIID& aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -63,8 +66,10 @@ private:
|
|||
Rename = 1u << 3
|
||||
};
|
||||
|
||||
nsLocalFile(const nsLocalFile& other);
|
||||
~nsLocalFile() {}
|
||||
nsLocalFile(const nsLocalFile& aOther);
|
||||
~nsLocalFile()
|
||||
{
|
||||
}
|
||||
|
||||
bool mDirty; // cached information can only be used when this is false
|
||||
bool mResolveDirty;
|
||||
|
@ -96,16 +101,15 @@ private:
|
|||
|
||||
void EnsureShortPath();
|
||||
|
||||
nsresult CopyMove(nsIFile *newParentDir, const nsAString &newName,
|
||||
uint32_t options);
|
||||
nsresult CopySingleFile(nsIFile *source, nsIFile* dest,
|
||||
const nsAString &newName,
|
||||
uint32_t options);
|
||||
nsresult CopyMove(nsIFile* aNewParentDir, const nsAString& aNewName,
|
||||
uint32_t aOptions);
|
||||
nsresult CopySingleFile(nsIFile* aSource, nsIFile* aDest,
|
||||
const nsAString& aNewName, uint32_t aOptions);
|
||||
|
||||
nsresult SetModDate(int64_t aLastModifiedTime, const wchar_t *filePath);
|
||||
nsresult HasFileAttribute(DWORD fileAttrib, bool *_retval);
|
||||
nsresult AppendInternal(const nsAFlatString &node,
|
||||
bool multipleComponents);
|
||||
nsresult SetModDate(int64_t aLastModifiedTime, const wchar_t* aFilePath);
|
||||
nsresult HasFileAttribute(DWORD aFileAttrib, bool* aResult);
|
||||
nsresult AppendInternal(const nsAFlatString& aNode,
|
||||
bool aMultipleComponents);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,9 +27,10 @@ using namespace mozilla::ipc;
|
|||
|
||||
using mozilla::DeprecatedAbs;
|
||||
|
||||
class nsMultiplexInputStream MOZ_FINAL : public nsIMultiplexInputStream,
|
||||
public nsISeekableStream,
|
||||
public nsIIPCSerializableInputStream
|
||||
class nsMultiplexInputStream MOZ_FINAL
|
||||
: public nsIMultiplexInputStream
|
||||
, public nsISeekableStream
|
||||
, public nsIIPCSerializableInputStream
|
||||
{
|
||||
public:
|
||||
nsMultiplexInputStream();
|
||||
|
@ -41,9 +42,12 @@ public:
|
|||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
private:
|
||||
~nsMultiplexInputStream() {}
|
||||
~nsMultiplexInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
struct ReadSegmentsState {
|
||||
struct ReadSegmentsState
|
||||
{
|
||||
nsIInputStream* mThisStream;
|
||||
uint32_t mOffset;
|
||||
nsWriteSegmentFun mWriter;
|
||||
|
@ -53,9 +57,9 @@ private:
|
|||
|
||||
static NS_METHOD ReadSegCb(nsIInputStream* aIn, void* aClosure,
|
||||
const char* aFromRawSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t *aWriteCount);
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
nsTArray<nsCOMPtr<nsIInputStream> > mStreams;
|
||||
nsTArray<nsCOMPtr<nsIInputStream>> mStreams;
|
||||
uint32_t mCurrentStream;
|
||||
bool mStartedReadingCurrent;
|
||||
nsresult mStatus;
|
||||
|
@ -78,19 +82,19 @@ NS_IMPL_CI_INTERFACE_GETTER(nsMultiplexInputStream,
|
|||
nsISeekableStream)
|
||||
|
||||
static nsresult
|
||||
AvailableMaybeSeek(nsIInputStream *stream, uint64_t *_retval)
|
||||
AvailableMaybeSeek(nsIInputStream* aStream, uint64_t* aResult)
|
||||
{
|
||||
nsresult rv = stream->Available(_retval);
|
||||
nsresult rv = aStream->Available(aResult);
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
// Blindly seek to the current position if Available() returns
|
||||
// NS_BASE_STREAM_CLOSED.
|
||||
// If nsIFileInputStream is closed in Read() due to CLOSE_ON_EOF flag,
|
||||
// Seek() could reopen the file if REOPEN_ON_REWIND flag is set.
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(stream);
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aStream);
|
||||
if (seekable) {
|
||||
nsresult rv = seekable->Seek(nsISeekableStream::NS_SEEK_CUR, 0);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = stream->Available(_retval);
|
||||
rv = aStream->Available(aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,17 +102,17 @@ AvailableMaybeSeek(nsIInputStream *stream, uint64_t *_retval)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
TellMaybeSeek(nsISeekableStream *seekable, int64_t *_retval)
|
||||
TellMaybeSeek(nsISeekableStream* aSeekable, int64_t* aResult)
|
||||
{
|
||||
nsresult rv = seekable->Tell(_retval);
|
||||
nsresult rv = aSeekable->Tell(aResult);
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
// Blindly seek to the current position if Tell() returns
|
||||
// NS_BASE_STREAM_CLOSED.
|
||||
// If nsIFileInputStream is closed in Read() due to CLOSE_ON_EOF flag,
|
||||
// Seek() could reopen the file if REOPEN_ON_REWIND flag is set.
|
||||
nsresult rv = seekable->Seek(nsISeekableStream::NS_SEEK_CUR, 0);
|
||||
nsresult rv = aSeekable->Seek(nsISeekableStream::NS_SEEK_CUR, 0);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = seekable->Tell(_retval);
|
||||
rv = aSeekable->Tell(aResult);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -123,7 +127,7 @@ nsMultiplexInputStream::nsMultiplexInputStream()
|
|||
|
||||
/* readonly attribute unsigned long count; */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::GetCount(uint32_t *aCount)
|
||||
nsMultiplexInputStream::GetCount(uint32_t* aCount)
|
||||
{
|
||||
*aCount = mStreams.Length();
|
||||
return NS_OK;
|
||||
|
@ -131,7 +135,7 @@ nsMultiplexInputStream::GetCount(uint32_t *aCount)
|
|||
|
||||
#ifdef DEBUG
|
||||
static bool
|
||||
SeekableStreamAtBeginning(nsIInputStream *aStream)
|
||||
SeekableStreamAtBeginning(nsIInputStream* aStream)
|
||||
{
|
||||
int64_t streamPos;
|
||||
nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(aStream);
|
||||
|
@ -144,7 +148,7 @@ SeekableStreamAtBeginning(nsIInputStream *aStream)
|
|||
|
||||
/* void appendStream (in nsIInputStream stream); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::AppendStream(nsIInputStream *aStream)
|
||||
nsMultiplexInputStream::AppendStream(nsIInputStream* aStream)
|
||||
{
|
||||
NS_ASSERTION(SeekableStreamAtBeginning(aStream), "Appended stream not at beginning.");
|
||||
return mStreams.AppendElement(aStream) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -152,13 +156,14 @@ nsMultiplexInputStream::AppendStream(nsIInputStream *aStream)
|
|||
|
||||
/* void insertStream (in nsIInputStream stream, in unsigned long index); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::InsertStream(nsIInputStream *aStream, uint32_t aIndex)
|
||||
nsMultiplexInputStream::InsertStream(nsIInputStream* aStream, uint32_t aIndex)
|
||||
{
|
||||
NS_ASSERTION(SeekableStreamAtBeginning(aStream), "Inserted stream not at beginning.");
|
||||
mStreams.InsertElementAt(aIndex, aStream);
|
||||
if (mCurrentStream > aIndex ||
|
||||
(mCurrentStream == aIndex && mStartedReadingCurrent))
|
||||
(mCurrentStream == aIndex && mStartedReadingCurrent)) {
|
||||
++mCurrentStream;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -167,23 +172,25 @@ NS_IMETHODIMP
|
|||
nsMultiplexInputStream::RemoveStream(uint32_t aIndex)
|
||||
{
|
||||
mStreams.RemoveElementAt(aIndex);
|
||||
if (mCurrentStream > aIndex)
|
||||
if (mCurrentStream > aIndex) {
|
||||
--mCurrentStream;
|
||||
else if (mCurrentStream == aIndex)
|
||||
} else if (mCurrentStream == aIndex) {
|
||||
mStartedReadingCurrent = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIInputStream getStream (in unsigned long index); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::GetStream(uint32_t aIndex, nsIInputStream **_retval)
|
||||
nsMultiplexInputStream::GetStream(uint32_t aIndex, nsIInputStream** aResult)
|
||||
{
|
||||
*_retval = mStreams.SafeElementAt(aIndex, nullptr);
|
||||
if (NS_WARN_IF(!*_retval))
|
||||
*aResult = mStreams.SafeElementAt(aIndex, nullptr);
|
||||
if (NS_WARN_IF(!*aResult)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_ADDREF(*_retval);
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -199,18 +206,20 @@ nsMultiplexInputStream::Close()
|
|||
for (uint32_t i = 0; i < len; ++i) {
|
||||
nsresult rv2 = mStreams[i]->Close();
|
||||
// We still want to close all streams, but we should return an error
|
||||
if (NS_FAILED(rv2))
|
||||
if (NS_FAILED(rv2)) {
|
||||
rv = rv2;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* unsigned long long available (); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::Available(uint64_t *_retval)
|
||||
nsMultiplexInputStream::Available(uint64_t* aResult)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
uint64_t avail = 0;
|
||||
|
@ -219,28 +228,31 @@ nsMultiplexInputStream::Available(uint64_t *_retval)
|
|||
for (uint32_t i = mCurrentStream; i < len; i++) {
|
||||
uint64_t streamAvail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &streamAvail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
avail += streamAvail;
|
||||
}
|
||||
*_retval = avail;
|
||||
*aResult = avail;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] unsigned long read (in charPtr buf, in unsigned long count); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::Read(char * aBuf, uint32_t aCount, uint32_t *_retval)
|
||||
nsMultiplexInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
// It is tempting to implement this method in terms of ReadSegments, but
|
||||
// that would prevent this class from being used with streams that only
|
||||
// implement Read (e.g., file streams).
|
||||
|
||||
*_retval = 0;
|
||||
*aResult = 0;
|
||||
|
||||
if (mStatus == NS_BASE_STREAM_CLOSED)
|
||||
if (mStatus == NS_BASE_STREAM_CLOSED) {
|
||||
return NS_OK;
|
||||
if (NS_FAILED(mStatus))
|
||||
}
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -255,38 +267,38 @@ nsMultiplexInputStream::Read(char * aBuf, uint32_t aCount, uint32_t *_retval)
|
|||
NS_NOTREACHED("Input stream's Read method returned NS_BASE_STREAM_CLOSED");
|
||||
rv = NS_OK;
|
||||
read = 0;
|
||||
}
|
||||
else if (NS_FAILED(rv))
|
||||
} else if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (read == 0) {
|
||||
++mCurrentStream;
|
||||
mStartedReadingCurrent = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
NS_ASSERTION(aCount >= read, "Read more than requested");
|
||||
*_retval += read;
|
||||
*aResult += read;
|
||||
aCount -= read;
|
||||
aBuf += read;
|
||||
mStartedReadingCurrent = true;
|
||||
}
|
||||
}
|
||||
return *_retval ? NS_OK : rv;
|
||||
return *aResult ? NS_OK : rv;
|
||||
}
|
||||
|
||||
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun writer,
|
||||
* in voidPtr closure,
|
||||
* in unsigned long count); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
||||
uint32_t aCount, uint32_t *_retval)
|
||||
nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
if (mStatus == NS_BASE_STREAM_CLOSED) {
|
||||
*_retval = 0;
|
||||
*aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aWriter, "missing aWriter");
|
||||
|
||||
|
@ -312,15 +324,15 @@ nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
|||
}
|
||||
|
||||
// if |aWriter| decided to stop reading segments...
|
||||
if (state.mDone || NS_FAILED(rv))
|
||||
if (state.mDone || NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// if stream is empty, then advance to the next stream.
|
||||
if (read == 0) {
|
||||
++mCurrentStream;
|
||||
mStartedReadingCurrent = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
NS_ASSERTION(aCount >= read, "Read more than requested");
|
||||
state.mOffset += read;
|
||||
aCount -= read;
|
||||
|
@ -329,7 +341,7 @@ nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
|||
}
|
||||
|
||||
// if we successfully read some data, then this call succeeded.
|
||||
*_retval = state.mOffset;
|
||||
*aResult = state.mOffset;
|
||||
return state.mOffset ? NS_OK : rv;
|
||||
}
|
||||
|
||||
|
@ -337,7 +349,7 @@ NS_METHOD
|
|||
nsMultiplexInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
|
||||
const char* aFromRawSegment,
|
||||
uint32_t aToOffset, uint32_t aCount,
|
||||
uint32_t *aWriteCount)
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
nsresult rv;
|
||||
ReadSegmentsState* state = (ReadSegmentsState*)aClosure;
|
||||
|
@ -347,14 +359,15 @@ nsMultiplexInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
|
|||
aToOffset + state->mOffset,
|
||||
aCount,
|
||||
aWriteCount);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
state->mDone = true;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean nonBlocking; */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsMultiplexInputStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
uint32_t len = mStreams.Length();
|
||||
if (len == 0) {
|
||||
|
@ -367,13 +380,15 @@ nsMultiplexInputStream::IsNonBlocking(bool *aNonBlocking)
|
|||
}
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
nsresult rv = mStreams[i]->IsNonBlocking(aNonBlocking);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
// If one is non-blocking the entire stream becomes non-blocking
|
||||
// (except that we don't implement nsIAsyncInputStream, so there's
|
||||
// not much for the caller to do if Read returns "would block")
|
||||
if (*aNonBlocking)
|
||||
if (*aNonBlocking) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -382,8 +397,9 @@ nsMultiplexInputStream::IsNonBlocking(bool *aNonBlocking)
|
|||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
@ -407,11 +423,11 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
if (i < oldCurrentStream ||
|
||||
(i == oldCurrentStream && oldStartedReadingCurrent)) {
|
||||
rv = stream->Seek(NS_SEEK_SET, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -421,41 +437,42 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
if (i > oldCurrentStream ||
|
||||
(i == oldCurrentStream && !oldStartedReadingCurrent)) {
|
||||
streamPos = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
rv = TellMaybeSeek(stream, &streamPos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// See if we need to seek current stream forward or backward
|
||||
if (remaining < streamPos) {
|
||||
rv = stream->Seek(NS_SEEK_SET, remaining);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = remaining != 0;
|
||||
|
||||
remaining = 0;
|
||||
}
|
||||
else if (remaining > streamPos) {
|
||||
} else if (remaining > streamPos) {
|
||||
if (i < oldCurrentStream) {
|
||||
// We're already at end so no need to seek this stream
|
||||
remaining -= streamPos;
|
||||
NS_ASSERTION(remaining >= 0, "Remaining invalid");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t newPos = XPCOM_MIN(remaining, streamPos + (int64_t)avail);
|
||||
|
||||
rv = stream->Seek(NS_SEEK_SET, newPos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
|
@ -463,8 +480,7 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
remaining -= newPos;
|
||||
NS_ASSERTION(remaining >= 0, "Remaining invalid");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
NS_ASSERTION(remaining == streamPos, "Huh?");
|
||||
remaining = 0;
|
||||
}
|
||||
|
@ -481,14 +497,16 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t seek = XPCOM_MIN((int64_t)avail, remaining);
|
||||
|
||||
rv = stream->Seek(NS_SEEK_CUR, seek);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
|
@ -507,14 +525,16 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
|
||||
int64_t pos;
|
||||
rv = TellMaybeSeek(stream, &pos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t seek = XPCOM_MIN(pos, remaining);
|
||||
|
||||
rv = stream->Seek(NS_SEEK_CUR, -seek);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = seek != -pos;
|
||||
|
@ -544,10 +564,10 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
if (remaining == 0) {
|
||||
if (i >= oldCurrentStream) {
|
||||
rv = stream->Seek(NS_SEEK_END, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -559,8 +579,9 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
} else {
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
streamPos = avail;
|
||||
}
|
||||
|
@ -568,8 +589,9 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
// See if we have enough data in the current stream.
|
||||
if (DeprecatedAbs(remaining) < streamPos) {
|
||||
rv = stream->Seek(NS_SEEK_END, remaining);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
|
@ -583,22 +605,23 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
} else {
|
||||
int64_t avail;
|
||||
rv = TellMaybeSeek(stream, &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t newPos = streamPos + XPCOM_MIN(avail, DeprecatedAbs(remaining));
|
||||
|
||||
rv = stream->Seek(NS_SEEK_END, -newPos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
|
||||
remaining += newPos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
NS_ASSERTION(remaining == streamPos, "Huh?");
|
||||
remaining = 0;
|
||||
}
|
||||
|
@ -613,27 +636,30 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
|
||||
/* uint32_t tell (); */
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::Tell(int64_t *_retval)
|
||||
nsMultiplexInputStream::Tell(int64_t* aResult)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
int64_t ret64 = 0;
|
||||
uint32_t i, last;
|
||||
last = mStartedReadingCurrent ? mCurrentStream+1 : mCurrentStream;
|
||||
last = mStartedReadingCurrent ? mCurrentStream + 1 : mCurrentStream;
|
||||
for (i = 0; i < last; ++i) {
|
||||
nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(mStreams[i]);
|
||||
if (NS_WARN_IF(!stream))
|
||||
if (NS_WARN_IF(!stream)) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
int64_t pos;
|
||||
rv = TellMaybeSeek(stream, &pos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)))
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
ret64 += pos;
|
||||
}
|
||||
*_retval = ret64;
|
||||
*aResult = ret64;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -646,21 +672,23 @@ nsMultiplexInputStream::SetEOF()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsMultiplexInputStreamConstructor(nsISupports *outer,
|
||||
REFNSIID iid,
|
||||
void **result)
|
||||
nsMultiplexInputStreamConstructor(nsISupports* aOuter,
|
||||
REFNSIID aIID,
|
||||
void** aResult)
|
||||
{
|
||||
*result = nullptr;
|
||||
*aResult = nullptr;
|
||||
|
||||
if (outer)
|
||||
if (aOuter) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
nsMultiplexInputStream *inst = new nsMultiplexInputStream();
|
||||
if (!inst)
|
||||
nsMultiplexInputStream* inst = new nsMultiplexInputStream();
|
||||
if (!inst) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(inst);
|
||||
nsresult rv = inst->QueryInterface(iid, result);
|
||||
nsresult rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
{0x8d, 0xa1, 0xb4, 0xce, 0xf1, 0x7e, 0x56, 0x8d} \
|
||||
}
|
||||
|
||||
extern nsresult nsMultiplexInputStreamConstructor(nsISupports *outer,
|
||||
REFNSIID iid,
|
||||
void **result);
|
||||
extern nsresult nsMultiplexInputStreamConstructor(nsISupports* aOuter,
|
||||
REFNSIID aIID,
|
||||
void** aResult);
|
||||
|
||||
#endif // _nsMultiplexInputStream_h_
|
||||
|
|
|
@ -16,16 +16,16 @@
|
|||
#include "nsString.h"
|
||||
|
||||
nsresult
|
||||
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
||||
NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
CopyUTF8toUTF16(input, output);
|
||||
CopyUTF8toUTF16(aInput, aOutput);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
||||
NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput)
|
||||
{
|
||||
CopyUTF16toUTF8(input, output);
|
||||
CopyUTF16toUTF8(aInput, aOutput);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -69,26 +69,28 @@ using namespace mozilla;
|
|||
#endif
|
||||
|
||||
static void
|
||||
isolatin1_to_utf16(const char **input, uint32_t *inputLeft, char16_t **output, uint32_t *outputLeft)
|
||||
isolatin1_to_utf16(const char** aInput, uint32_t* aInputLeft,
|
||||
char16_t** aOutput, uint32_t* aOutputLeft)
|
||||
{
|
||||
while (*inputLeft && *outputLeft) {
|
||||
**output = (unsigned char) **input;
|
||||
(*input)++;
|
||||
(*inputLeft)--;
|
||||
(*output)++;
|
||||
(*outputLeft)--;
|
||||
while (*aInputLeft && *aOutputLeft) {
|
||||
**aOutput = (unsigned char)** aInput;
|
||||
(*aInput)++;
|
||||
(*aInputLeft)--;
|
||||
(*aOutput)++;
|
||||
(*aOutputLeft)--;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
utf16_to_isolatin1(const char16_t **input, uint32_t *inputLeft, char **output, uint32_t *outputLeft)
|
||||
utf16_to_isolatin1(const char16_t** aInput, uint32_t* aInputLeft,
|
||||
char** aOutput, uint32_t* aOutputLeft)
|
||||
{
|
||||
while (*inputLeft && *outputLeft) {
|
||||
**output = (unsigned char) **input;
|
||||
(*input)++;
|
||||
(*inputLeft)--;
|
||||
(*output)++;
|
||||
(*outputLeft)--;
|
||||
while (*aInputLeft && *aOutputLeft) {
|
||||
**aOutput = (unsigned char)**aInput;
|
||||
(*aInput)++;
|
||||
(*aInputLeft)--;
|
||||
(*aOutput)++;
|
||||
(*aOutputLeft)--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,25 +117,24 @@ utf16_to_isolatin1(const char16_t **input, uint32_t *inputLeft, char **output, u
|
|||
#define ENABLE_UTF8_FALLBACK_SUPPORT
|
||||
#endif
|
||||
|
||||
#define INVALID_ICONV_T ((iconv_t) -1)
|
||||
#define INVALID_ICONV_T ((iconv_t)-1)
|
||||
|
||||
static inline size_t
|
||||
xp_iconv(iconv_t converter,
|
||||
const char **input,
|
||||
size_t *inputLeft,
|
||||
char **output,
|
||||
size_t *outputLeft)
|
||||
const char** aInput, size_t* aInputLeft,
|
||||
char** aOutput, size_t* aOutputLeft)
|
||||
{
|
||||
size_t res, outputAvail = outputLeft ? *outputLeft : 0;
|
||||
res = iconv(converter, ICONV_INPUT(input), inputLeft, output, outputLeft);
|
||||
if (res == (size_t) -1) {
|
||||
size_t res, outputAvail = aOutputLeft ? *aOutputLeft : 0;
|
||||
res = iconv(converter, ICONV_INPUT(aInput), aInputLeft, aOutput, aOutputLeft);
|
||||
if (res == (size_t)-1) {
|
||||
// on some platforms (e.g., linux) iconv will fail with
|
||||
// E2BIG if it cannot convert _all_ of its input. it'll
|
||||
// still adjust all of the in/out params correctly, so we
|
||||
// can ignore this error. the assumption is that we will
|
||||
// be called again to complete the conversion.
|
||||
if ((errno == E2BIG) && (*outputLeft < outputAvail))
|
||||
if ((errno == E2BIG) && (*aOutputLeft < outputAvail)) {
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -145,23 +146,24 @@ xp_iconv_reset(iconv_t converter)
|
|||
// for all parameter to reset the converter, but beware the
|
||||
// evil Solaris crash if you go down this route >:-)
|
||||
|
||||
const char *zero_char_in_ptr = nullptr;
|
||||
char *zero_char_out_ptr = nullptr;
|
||||
size_t zero_size_in = 0,
|
||||
zero_size_out = 0;
|
||||
const char* zero_char_in_ptr = nullptr;
|
||||
char* zero_char_out_ptr = nullptr;
|
||||
size_t zero_size_in = 0;
|
||||
size_t zero_size_out = 0;
|
||||
|
||||
xp_iconv(converter, &zero_char_in_ptr,
|
||||
&zero_size_in,
|
||||
&zero_char_out_ptr,
|
||||
&zero_size_out);
|
||||
xp_iconv(converter,
|
||||
&zero_char_in_ptr,
|
||||
&zero_size_in,
|
||||
&zero_char_out_ptr,
|
||||
&zero_size_out);
|
||||
}
|
||||
|
||||
static inline iconv_t
|
||||
xp_iconv_open(const char **to_list, const char **from_list)
|
||||
xp_iconv_open(const char** to_list, const char** from_list)
|
||||
{
|
||||
iconv_t res;
|
||||
const char **from_name;
|
||||
const char **to_name;
|
||||
const char** from_name;
|
||||
const char** to_name;
|
||||
|
||||
// try all possible combinations to locate a converter.
|
||||
to_name = to_list;
|
||||
|
@ -171,8 +173,9 @@ xp_iconv_open(const char **to_list, const char **from_list)
|
|||
while (*from_name) {
|
||||
if (**from_name) {
|
||||
res = iconv_open(*to_name, *from_name);
|
||||
if (res != INVALID_ICONV_T)
|
||||
if (res != INVALID_ICONV_T) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
from_name++;
|
||||
}
|
||||
|
@ -197,7 +200,7 @@ xp_iconv_open(const char **to_list, const char **from_list)
|
|||
* variable ICONV_BYTEORDER is set to 'big-endian', about which not much
|
||||
* can be done other than adding a note in the release notes. (bug 206811)
|
||||
*/
|
||||
static const char *UTF_16_NAMES[] = {
|
||||
static const char* UTF_16_NAMES[] = {
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
"UTF-16LE",
|
||||
#if defined(__GLIBC__)
|
||||
|
@ -222,7 +225,7 @@ static const char *UTF_16_NAMES[] = {
|
|||
};
|
||||
|
||||
#if defined(ENABLE_UTF8_FALLBACK_SUPPORT)
|
||||
static const char *UTF_8_NAMES[] = {
|
||||
static const char* UTF_8_NAMES[] = {
|
||||
"UTF-8",
|
||||
"UTF8",
|
||||
"UTF_8",
|
||||
|
@ -233,7 +236,7 @@ static const char *UTF_8_NAMES[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const char *ISO_8859_1_NAMES[] = {
|
||||
static const char* ISO_8859_1_NAMES[] = {
|
||||
"ISO-8859-1",
|
||||
#if !defined(__GLIBC__)
|
||||
"ISO8859-1",
|
||||
|
@ -255,10 +258,10 @@ public:
|
|||
nsNativeCharsetConverter();
|
||||
~nsNativeCharsetConverter();
|
||||
|
||||
nsresult NativeToUnicode(const char **input , uint32_t *inputLeft,
|
||||
char16_t **output, uint32_t *outputLeft);
|
||||
nsresult UnicodeToNative(const char16_t **input , uint32_t *inputLeft,
|
||||
char **output, uint32_t *outputLeft);
|
||||
nsresult NativeToUnicode(const char** aInput, uint32_t* aInputLeft,
|
||||
char16_t** aOutput, uint32_t* aOutputLeft);
|
||||
nsresult UnicodeToNative(const char16_t** aInput, uint32_t* aInputLeft,
|
||||
char** aOutput, uint32_t* aOutputLeft);
|
||||
|
||||
static void GlobalInit();
|
||||
static void GlobalShutdown();
|
||||
|
@ -273,14 +276,24 @@ private:
|
|||
static iconv_t gUnicodeToUTF8;
|
||||
static iconv_t gUTF8ToUnicode;
|
||||
#endif
|
||||
static Mutex *gLock;
|
||||
static Mutex* gLock;
|
||||
static bool gInitialized;
|
||||
static bool gIsNativeUTF8;
|
||||
|
||||
static void LazyInit();
|
||||
|
||||
static void Lock() { if (gLock) gLock->Lock(); }
|
||||
static void Unlock() { if (gLock) gLock->Unlock(); }
|
||||
static void Lock()
|
||||
{
|
||||
if (gLock) {
|
||||
gLock->Lock();
|
||||
}
|
||||
}
|
||||
static void Unlock()
|
||||
{
|
||||
if (gLock) {
|
||||
gLock->Unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
iconv_t nsNativeCharsetConverter::gNativeToUnicode = INVALID_ICONV_T;
|
||||
|
@ -291,7 +304,7 @@ iconv_t nsNativeCharsetConverter::gUTF8ToNative = INVALID_ICONV_T;
|
|||
iconv_t nsNativeCharsetConverter::gUnicodeToUTF8 = INVALID_ICONV_T;
|
||||
iconv_t nsNativeCharsetConverter::gUTF8ToUnicode = INVALID_ICONV_T;
|
||||
#endif
|
||||
Mutex *nsNativeCharsetConverter::gLock = nullptr;
|
||||
Mutex* nsNativeCharsetConverter::gLock = nullptr;
|
||||
bool nsNativeCharsetConverter::gInitialized = false;
|
||||
bool nsNativeCharsetConverter::gIsNativeUTF8 = false;
|
||||
|
||||
|
@ -302,23 +315,25 @@ nsNativeCharsetConverter::LazyInit()
|
|||
// the setlocale it does has to be called before nl_langinfo. Like in
|
||||
// NS_StartupNativeCharsetUtils, assume we are called early enough that
|
||||
// we are the first to care about the locale's charset.
|
||||
if (!gLock)
|
||||
if (!gLock) {
|
||||
setlocale(LC_CTYPE, "");
|
||||
const char *blank_list[] = { "", nullptr };
|
||||
const char **native_charset_list = blank_list;
|
||||
const char *native_charset = nl_langinfo(CODESET);
|
||||
if (native_charset == nullptr) {
|
||||
}
|
||||
const char* blank_list[] = { "", nullptr };
|
||||
const char** native_charset_list = blank_list;
|
||||
const char* native_charset = nl_langinfo(CODESET);
|
||||
if (!native_charset) {
|
||||
NS_ERROR("native charset is unknown");
|
||||
// fallback to ISO-8859-1
|
||||
native_charset_list = ISO_8859_1_NAMES;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
native_charset_list[0] = native_charset;
|
||||
}
|
||||
|
||||
// Most, if not all, Unixen supporting UTF-8 and nl_langinfo(CODESET)
|
||||
// return 'UTF-8' (or 'utf-8')
|
||||
if (!PL_strcasecmp(native_charset, "UTF-8"))
|
||||
if (!PL_strcasecmp(native_charset, "UTF-8")) {
|
||||
gIsNativeUTF8 = true;
|
||||
}
|
||||
|
||||
gNativeToUnicode = xp_iconv_open(UTF_16_NAMES, native_charset_list);
|
||||
gUnicodeToNative = xp_iconv_open(native_charset_list, UTF_16_NAMES);
|
||||
|
@ -355,18 +370,18 @@ nsNativeCharsetConverter::LazyInit()
|
|||
char dummy_output[4];
|
||||
|
||||
if (gNativeToUnicode != INVALID_ICONV_T) {
|
||||
const char *input = dummy_input;
|
||||
const char* input = dummy_input;
|
||||
size_t input_left = sizeof(dummy_input);
|
||||
char *output = dummy_output;
|
||||
char* output = dummy_output;
|
||||
size_t output_left = sizeof(dummy_output);
|
||||
|
||||
xp_iconv(gNativeToUnicode, &input, &input_left, &output, &output_left);
|
||||
}
|
||||
#if defined(ENABLE_UTF8_FALLBACK_SUPPORT)
|
||||
if (gUTF8ToUnicode != INVALID_ICONV_T) {
|
||||
const char *input = dummy_input;
|
||||
const char* input = dummy_input;
|
||||
size_t input_left = sizeof(dummy_input);
|
||||
char *output = dummy_output;
|
||||
char* output = dummy_output;
|
||||
size_t output_left = sizeof(dummy_output);
|
||||
|
||||
xp_iconv(gUTF8ToUnicode, &input, &input_left, &output, &output_left);
|
||||
|
@ -425,48 +440,56 @@ nsNativeCharsetConverter::GlobalShutdown()
|
|||
nsNativeCharsetConverter::nsNativeCharsetConverter()
|
||||
{
|
||||
Lock();
|
||||
if (!gInitialized)
|
||||
if (!gInitialized) {
|
||||
LazyInit();
|
||||
}
|
||||
}
|
||||
|
||||
nsNativeCharsetConverter::~nsNativeCharsetConverter()
|
||||
{
|
||||
// reset converters for next time
|
||||
if (gNativeToUnicode != INVALID_ICONV_T)
|
||||
if (gNativeToUnicode != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gNativeToUnicode);
|
||||
if (gUnicodeToNative != INVALID_ICONV_T)
|
||||
}
|
||||
if (gUnicodeToNative != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gUnicodeToNative);
|
||||
}
|
||||
#if defined(ENABLE_UTF8_FALLBACK_SUPPORT)
|
||||
if (gNativeToUTF8 != INVALID_ICONV_T)
|
||||
if (gNativeToUTF8 != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gNativeToUTF8);
|
||||
if (gUTF8ToNative != INVALID_ICONV_T)
|
||||
}
|
||||
if (gUTF8ToNative != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gUTF8ToNative);
|
||||
if (gUnicodeToUTF8 != INVALID_ICONV_T)
|
||||
}
|
||||
if (gUnicodeToUTF8 != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gUnicodeToUTF8);
|
||||
if (gUTF8ToUnicode != INVALID_ICONV_T)
|
||||
}
|
||||
if (gUTF8ToUnicode != INVALID_ICONV_T) {
|
||||
xp_iconv_reset(gUTF8ToUnicode);
|
||||
}
|
||||
#endif
|
||||
Unlock();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeCharsetConverter::NativeToUnicode(const char **input,
|
||||
uint32_t *inputLeft,
|
||||
char16_t **output,
|
||||
uint32_t *outputLeft)
|
||||
nsNativeCharsetConverter::NativeToUnicode(const char** aInput,
|
||||
uint32_t* aInputLeft,
|
||||
char16_t** aOutput,
|
||||
uint32_t* aOutputLeft)
|
||||
{
|
||||
size_t res = 0;
|
||||
size_t inLeft = (size_t) *inputLeft;
|
||||
size_t outLeft = (size_t) *outputLeft * 2;
|
||||
size_t inLeft = (size_t)*aInputLeft;
|
||||
size_t outLeft = (size_t)*aOutputLeft * 2;
|
||||
|
||||
if (gNativeToUnicode != INVALID_ICONV_T) {
|
||||
|
||||
res = xp_iconv(gNativeToUnicode, input, &inLeft, (char **) output, &outLeft);
|
||||
res = xp_iconv(gNativeToUnicode, aInput, &inLeft, (char**)aOutput, &outLeft);
|
||||
|
||||
*inputLeft = inLeft;
|
||||
*outputLeft = outLeft / 2;
|
||||
if (res != (size_t) -1)
|
||||
*aInputLeft = inLeft;
|
||||
*aOutputLeft = outLeft / 2;
|
||||
if (res != (size_t)-1) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("conversion from native to utf-16 failed");
|
||||
|
||||
|
@ -477,36 +500,38 @@ nsNativeCharsetConverter::NativeToUnicode(const char **input,
|
|||
else if ((gNativeToUTF8 != INVALID_ICONV_T) &&
|
||||
(gUTF8ToUnicode != INVALID_ICONV_T)) {
|
||||
// convert first to UTF8, then from UTF8 to UCS2
|
||||
const char *in = *input;
|
||||
const char* in = *aInput;
|
||||
|
||||
char ubuf[1024];
|
||||
|
||||
// we assume we're always called with enough space in |output|,
|
||||
// we assume we're always called with enough space in |aOutput|,
|
||||
// so convert many chars at a time...
|
||||
while (inLeft) {
|
||||
char *p = ubuf;
|
||||
char* p = ubuf;
|
||||
size_t n = sizeof(ubuf);
|
||||
res = xp_iconv(gNativeToUTF8, &in, &inLeft, &p, &n);
|
||||
if (res == (size_t) -1) {
|
||||
if (res == (size_t)-1) {
|
||||
NS_ERROR("conversion from native to utf-8 failed");
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(outLeft > 0, "bad assumption");
|
||||
p = ubuf;
|
||||
n = sizeof(ubuf) - n;
|
||||
res = xp_iconv(gUTF8ToUnicode, (const char **) &p, &n, (char **) output, &outLeft);
|
||||
if (res == (size_t) -1) {
|
||||
res = xp_iconv(gUTF8ToUnicode, (const char**)&p, &n,
|
||||
(char**)aOutput, &outLeft);
|
||||
if (res == (size_t)-1) {
|
||||
NS_ERROR("conversion from utf-8 to utf-16 failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(*input) += (*inputLeft - inLeft);
|
||||
*inputLeft = inLeft;
|
||||
*outputLeft = outLeft / 2;
|
||||
(*aInput) += (*aInputLeft - inLeft);
|
||||
*aInputLeft = inLeft;
|
||||
*aOutputLeft = outLeft / 2;
|
||||
|
||||
if (res != (size_t) -1)
|
||||
if (res != (size_t)-1) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// reset converters
|
||||
xp_iconv_reset(gNativeToUTF8);
|
||||
|
@ -516,27 +541,28 @@ nsNativeCharsetConverter::NativeToUnicode(const char **input,
|
|||
|
||||
// fallback: zero-pad and hope for the best
|
||||
// XXX This is lame and we have to do better.
|
||||
isolatin1_to_utf16(input, inputLeft, output, outputLeft);
|
||||
isolatin1_to_utf16(aInput, aInputLeft, aOutput, aOutputLeft);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeCharsetConverter::UnicodeToNative(const char16_t **input,
|
||||
uint32_t *inputLeft,
|
||||
char **output,
|
||||
uint32_t *outputLeft)
|
||||
nsNativeCharsetConverter::UnicodeToNative(const char16_t** aInput,
|
||||
uint32_t* aInputLeft,
|
||||
char** aOutput,
|
||||
uint32_t* aOutputLeft)
|
||||
{
|
||||
size_t res = 0;
|
||||
size_t inLeft = (size_t) *inputLeft * 2;
|
||||
size_t outLeft = (size_t) *outputLeft;
|
||||
size_t inLeft = (size_t)*aInputLeft * 2;
|
||||
size_t outLeft = (size_t)*aOutputLeft;
|
||||
|
||||
if (gUnicodeToNative != INVALID_ICONV_T) {
|
||||
res = xp_iconv(gUnicodeToNative, (const char **) input, &inLeft, output, &outLeft);
|
||||
res = xp_iconv(gUnicodeToNative, (const char**)aInput, &inLeft,
|
||||
aOutput, &outLeft);
|
||||
|
||||
*inputLeft = inLeft / 2;
|
||||
*outputLeft = outLeft;
|
||||
if (res != (size_t) -1) {
|
||||
*aInputLeft = inLeft / 2;
|
||||
*aOutputLeft = outLeft;
|
||||
if (res != (size_t)-1) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -548,39 +574,39 @@ nsNativeCharsetConverter::UnicodeToNative(const char16_t **input,
|
|||
#if defined(ENABLE_UTF8_FALLBACK_SUPPORT)
|
||||
else if ((gUnicodeToUTF8 != INVALID_ICONV_T) &&
|
||||
(gUTF8ToNative != INVALID_ICONV_T)) {
|
||||
const char *in = (const char *) *input;
|
||||
const char* in = (const char*)*aInput;
|
||||
|
||||
char ubuf[6]; // max utf-8 char length (really only needs to be 4 bytes)
|
||||
|
||||
// convert one uchar at a time...
|
||||
while (inLeft && outLeft) {
|
||||
char *p = ubuf;
|
||||
char* p = ubuf;
|
||||
size_t n = sizeof(ubuf), one_uchar = sizeof(char16_t);
|
||||
res = xp_iconv(gUnicodeToUTF8, &in, &one_uchar, &p, &n);
|
||||
if (res == (size_t) -1) {
|
||||
if (res == (size_t)-1) {
|
||||
NS_ERROR("conversion from utf-16 to utf-8 failed");
|
||||
break;
|
||||
}
|
||||
p = ubuf;
|
||||
n = sizeof(ubuf) - n;
|
||||
res = xp_iconv(gUTF8ToNative, (const char **) &p, &n, output, &outLeft);
|
||||
if (res == (size_t) -1) {
|
||||
res = xp_iconv(gUTF8ToNative, (const char**)&p, &n, aOutput, &outLeft);
|
||||
if (res == (size_t)-1) {
|
||||
if (errno == E2BIG) {
|
||||
// not enough room for last uchar... back up and return.
|
||||
in -= sizeof(char16_t);
|
||||
res = 0;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
NS_ERROR("conversion from utf-8 to native failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
inLeft -= sizeof(char16_t);
|
||||
}
|
||||
|
||||
(*input) += (*inputLeft - inLeft / 2);
|
||||
*inputLeft = inLeft / 2;
|
||||
*outputLeft = outLeft;
|
||||
if (res != (size_t) -1) {
|
||||
(*aInput) += (*aInputLeft - inLeft / 2);
|
||||
*aInputLeft = inLeft / 2;
|
||||
*aOutputLeft = outLeft;
|
||||
if (res != (size_t)-1) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -592,7 +618,7 @@ nsNativeCharsetConverter::UnicodeToNative(const char16_t **input,
|
|||
|
||||
// fallback: truncate and hope for the best
|
||||
// XXX This is lame and we have to do better.
|
||||
utf16_to_isolatin1(input, inputLeft, output, outputLeft);
|
||||
utf16_to_isolatin1(aInput, aInputLeft, aOutput, aOutputLeft);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -602,8 +628,9 @@ nsNativeCharsetConverter::IsNativeUTF8()
|
|||
{
|
||||
if (!gInitialized) {
|
||||
Lock();
|
||||
if (!gInitialized)
|
||||
if (!gInitialized) {
|
||||
LazyInit();
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
return gIsNativeUTF8;
|
||||
|
@ -624,10 +651,10 @@ class nsNativeCharsetConverter
|
|||
public:
|
||||
nsNativeCharsetConverter();
|
||||
|
||||
nsresult NativeToUnicode(const char **input , uint32_t *inputLeft,
|
||||
char16_t **output, uint32_t *outputLeft);
|
||||
nsresult UnicodeToNative(const char16_t **input , uint32_t *inputLeft,
|
||||
char **output, uint32_t *outputLeft);
|
||||
nsresult NativeToUnicode(const char** aInput, uint32_t* aInputLeft,
|
||||
char16_t** aOutput, uint32_t* aOutputLeft);
|
||||
nsresult UnicodeToNative(const char16_t** aInput, uint32_t* aInputLeft,
|
||||
char** aOutput, uint32_t* aOutputLeft);
|
||||
|
||||
static void GlobalInit();
|
||||
static void GlobalShutdown() { }
|
||||
|
@ -671,21 +698,22 @@ nsNativeCharsetConverter::GlobalInit()
|
|||
char a = 'a';
|
||||
unsigned int w = 0;
|
||||
|
||||
int res = mbtowc((wchar_t *) &w, &a, 1);
|
||||
int res = mbtowc((wchar_t*)&w, &a, 1);
|
||||
|
||||
gWCharIsUnicode = (res != -1 && w == 'a');
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!gWCharIsUnicode)
|
||||
if (!gWCharIsUnicode) {
|
||||
NS_WARNING("wchar_t is not unicode (unicode conversion will be lossy)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeCharsetConverter::NativeToUnicode(const char **input,
|
||||
uint32_t *inputLeft,
|
||||
char16_t **output,
|
||||
uint32_t *outputLeft)
|
||||
nsNativeCharsetConverter::NativeToUnicode(const char** aInput,
|
||||
uint32_t* aInputLeft,
|
||||
char16_t** aOutput,
|
||||
uint32_t* aOutputLeft)
|
||||
{
|
||||
if (gWCharIsUnicode) {
|
||||
int incr;
|
||||
|
@ -693,68 +721,66 @@ nsNativeCharsetConverter::NativeToUnicode(const char **input,
|
|||
// cannot use wchar_t here since it may have been redefined (e.g.,
|
||||
// via -fshort-wchar). hopefully, sizeof(tmp) is sufficient XP.
|
||||
unsigned int tmp = 0;
|
||||
while (*inputLeft && *outputLeft) {
|
||||
while (*aInputLeft && *aOutputLeft) {
|
||||
#ifdef HAVE_MBRTOWC
|
||||
incr = (int) mbrtowc((wchar_t *) &tmp, *input, *inputLeft, &ps);
|
||||
incr = (int)mbrtowc((wchar_t*)&tmp, *aInput, *aInputLeft, &ps);
|
||||
#else
|
||||
// XXX is this thread-safe?
|
||||
incr = (int) mbtowc((wchar_t *) &tmp, *input, *inputLeft);
|
||||
incr = (int)mbtowc((wchar_t*)&tmp, *aInput, *aInputLeft);
|
||||
#endif
|
||||
if (incr < 0) {
|
||||
NS_WARNING("mbtowc failed: possible charset mismatch");
|
||||
// zero-pad and hope for the best
|
||||
tmp = (unsigned char) **input;
|
||||
tmp = (unsigned char)**aInput;
|
||||
incr = 1;
|
||||
}
|
||||
**output = (char16_t) tmp;
|
||||
(*input) += incr;
|
||||
(*inputLeft) -= incr;
|
||||
(*output)++;
|
||||
(*outputLeft)--;
|
||||
** aOutput = (char16_t)tmp;
|
||||
(*aInput) += incr;
|
||||
(*aInputLeft) -= incr;
|
||||
(*aOutput)++;
|
||||
(*aOutputLeft)--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// wchar_t isn't unicode, so the best we can do is treat the
|
||||
// input as if it is isolatin1 :(
|
||||
isolatin1_to_utf16(input, inputLeft, output, outputLeft);
|
||||
isolatin1_to_utf16(aInput, aInputLeft, aOutput, aOutputLeft);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeCharsetConverter::UnicodeToNative(const char16_t **input,
|
||||
uint32_t *inputLeft,
|
||||
char **output,
|
||||
uint32_t *outputLeft)
|
||||
nsNativeCharsetConverter::UnicodeToNative(const char16_t** aInput,
|
||||
uint32_t* aInputLeft,
|
||||
char** aOutput,
|
||||
uint32_t* aOutputLeft)
|
||||
{
|
||||
if (gWCharIsUnicode) {
|
||||
int incr;
|
||||
|
||||
while (*inputLeft && *outputLeft >= MB_CUR_MAX) {
|
||||
while (*aInputLeft && *aOutputLeft >= MB_CUR_MAX) {
|
||||
#ifdef HAVE_WCRTOMB
|
||||
incr = (int) wcrtomb(*output, (wchar_t) **input, &ps);
|
||||
incr = (int)wcrtomb(*aOutput, (wchar_t)**aInput, &ps);
|
||||
#else
|
||||
// XXX is this thread-safe?
|
||||
incr = (int) wctomb(*output, (wchar_t) **input);
|
||||
incr = (int)wctomb(*aOutput, (wchar_t)**aInput);
|
||||
#endif
|
||||
if (incr < 0) {
|
||||
NS_WARNING("mbtowc failed: possible charset mismatch");
|
||||
**output = (unsigned char) **input; // truncate
|
||||
** aOutput = (unsigned char)**aInput; // truncate
|
||||
incr = 1;
|
||||
}
|
||||
// most likely we're dead anyways if this assertion should fire
|
||||
NS_ASSERTION(uint32_t(incr) <= *outputLeft, "wrote beyond end of string");
|
||||
(*output) += incr;
|
||||
(*outputLeft) -= incr;
|
||||
(*input)++;
|
||||
(*inputLeft)--;
|
||||
NS_ASSERTION(uint32_t(incr) <= *aOutputLeft, "wrote beyond end of string");
|
||||
(*aOutput) += incr;
|
||||
(*aOutputLeft) -= incr;
|
||||
(*aInput)++;
|
||||
(*aInputLeft)--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// wchar_t isn't unicode, so the best we can do is treat the
|
||||
// input as if it is isolatin1 :(
|
||||
utf16_to_isolatin1(input, inputLeft, output, outputLeft);
|
||||
utf16_to_isolatin1(aInput, aInputLeft, aOutput, aOutputLeft);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -774,14 +800,14 @@ nsNativeCharsetConverter::IsNativeUTF8()
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
||||
NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
output.Truncate();
|
||||
aOutput.Truncate();
|
||||
|
||||
uint32_t inputLen = input.Length();
|
||||
uint32_t inputLen = aInput.Length();
|
||||
|
||||
nsACString::const_iterator iter;
|
||||
input.BeginReading(iter);
|
||||
aInput.BeginReading(iter);
|
||||
|
||||
//
|
||||
// OPTIMIZATION: preallocate space for largest possible result; convert
|
||||
|
@ -790,51 +816,55 @@ NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
|||
// this will generally result in a larger allocation, but that seems
|
||||
// better than an extra buffer copy.
|
||||
//
|
||||
if (!output.SetLength(inputLen, fallible_t()))
|
||||
if (!aOutput.SetLength(inputLen, fallible_t())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsAString::iterator out_iter;
|
||||
output.BeginWriting(out_iter);
|
||||
aOutput.BeginWriting(out_iter);
|
||||
|
||||
char16_t *result = out_iter.get();
|
||||
char16_t* result = out_iter.get();
|
||||
uint32_t resultLeft = inputLen;
|
||||
|
||||
const char *buf = iter.get();
|
||||
const char* buf = iter.get();
|
||||
uint32_t bufLeft = inputLen;
|
||||
|
||||
nsNativeCharsetConverter conv;
|
||||
nsresult rv = conv.NativeToUnicode(&buf, &bufLeft, &result, &resultLeft);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ASSERTION(bufLeft == 0, "did not consume entire input buffer");
|
||||
output.SetLength(inputLen - resultLeft);
|
||||
aOutput.SetLength(inputLen - resultLeft);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
||||
NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput)
|
||||
{
|
||||
output.Truncate();
|
||||
aOutput.Truncate();
|
||||
|
||||
nsAString::const_iterator iter, end;
|
||||
input.BeginReading(iter);
|
||||
input.EndReading(end);
|
||||
aInput.BeginReading(iter);
|
||||
aInput.EndReading(end);
|
||||
|
||||
// cannot easily avoid intermediate buffer copy.
|
||||
char temp[4096];
|
||||
|
||||
nsNativeCharsetConverter conv;
|
||||
|
||||
const char16_t *buf = iter.get();
|
||||
const char16_t* buf = iter.get();
|
||||
uint32_t bufLeft = Distance(iter, end);
|
||||
while (bufLeft) {
|
||||
char *p = temp;
|
||||
char* p = temp;
|
||||
uint32_t tempLeft = sizeof(temp);
|
||||
|
||||
nsresult rv = conv.UnicodeToNative(&buf, &bufLeft, &p, &tempLeft);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (tempLeft < sizeof(temp))
|
||||
output.Append(temp, sizeof(temp) - tempLeft);
|
||||
if (tempLeft < sizeof(temp)) {
|
||||
aOutput.Append(temp, sizeof(temp) - tempLeft);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -880,29 +910,31 @@ NS_ShutdownNativeCharsetUtils()
|
|||
using namespace mozilla;
|
||||
|
||||
nsresult
|
||||
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
||||
NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
uint32_t inputLen = input.Length();
|
||||
uint32_t inputLen = aInput.Length();
|
||||
|
||||
nsACString::const_iterator iter;
|
||||
input.BeginReading(iter);
|
||||
aInput.BeginReading(iter);
|
||||
|
||||
const char *buf = iter.get();
|
||||
const char* buf = iter.get();
|
||||
|
||||
// determine length of result
|
||||
uint32_t resultLen = 0;
|
||||
int n = ::MultiByteToWideChar(CP_ACP, 0, buf, inputLen, nullptr, 0);
|
||||
if (n > 0)
|
||||
if (n > 0) {
|
||||
resultLen += n;
|
||||
}
|
||||
|
||||
// allocate sufficient space
|
||||
if (!output.SetLength(resultLen, fallible_t()))
|
||||
if (!aOutput.SetLength(resultLen, fallible_t())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (resultLen > 0) {
|
||||
nsAString::iterator out_iter;
|
||||
output.BeginWriting(out_iter);
|
||||
aOutput.BeginWriting(out_iter);
|
||||
|
||||
char16_t *result = out_iter.get();
|
||||
char16_t* result = out_iter.get();
|
||||
|
||||
::MultiByteToWideChar(CP_ACP, 0, buf, inputLen, wwc(result), resultLen);
|
||||
}
|
||||
|
@ -910,12 +942,12 @@ NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
|||
}
|
||||
|
||||
nsresult
|
||||
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
||||
NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput)
|
||||
{
|
||||
uint32_t inputLen = input.Length();
|
||||
uint32_t inputLen = aInput.Length();
|
||||
|
||||
nsAString::const_iterator iter;
|
||||
input.BeginReading(iter);
|
||||
aInput.BeginReading(iter);
|
||||
|
||||
char16ptr_t buf = iter.get();
|
||||
|
||||
|
@ -924,21 +956,23 @@ NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
|||
|
||||
int n = ::WideCharToMultiByte(CP_ACP, 0, buf, inputLen, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
if (n > 0)
|
||||
if (n > 0) {
|
||||
resultLen += n;
|
||||
}
|
||||
|
||||
// allocate sufficient space
|
||||
if (!output.SetLength(resultLen, fallible_t()))
|
||||
if (!aOutput.SetLength(resultLen, fallible_t())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (resultLen > 0) {
|
||||
nsACString::iterator out_iter;
|
||||
output.BeginWriting(out_iter);
|
||||
aOutput.BeginWriting(out_iter);
|
||||
|
||||
// default "defaultChar" is '?', which is an illegal character on windows
|
||||
// file system. That will cause file uncreatable. Change it to '_'
|
||||
const char defaultChar = '_';
|
||||
|
||||
char *result = out_iter.get();
|
||||
char* result = out_iter.get();
|
||||
|
||||
::WideCharToMultiByte(CP_ACP, 0, buf, inputLen, result, resultLen,
|
||||
&defaultChar, nullptr);
|
||||
|
@ -948,17 +982,18 @@ NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
|||
|
||||
// moved from widget/windows/nsToolkit.cpp
|
||||
int32_t
|
||||
NS_ConvertAtoW(const char *aStrInA, int aBufferSize, char16_t *aStrOutW)
|
||||
NS_ConvertAtoW(const char* aStrInA, int aBufferSize, char16_t* aStrOutW)
|
||||
{
|
||||
return MultiByteToWideChar(CP_ACP, 0, aStrInA, -1, wwc(aStrOutW), aBufferSize);
|
||||
}
|
||||
|
||||
int32_t
|
||||
NS_ConvertWtoA(const char16_t *aStrInW, int aBufferSizeOut,
|
||||
char *aStrOutA, const char *aDefault)
|
||||
NS_ConvertWtoA(const char16_t* aStrInW, int aBufferSizeOut,
|
||||
char* aStrOutA, const char* aDefault)
|
||||
{
|
||||
if ((!aStrInW) || (!aStrOutA) || (aBufferSizeOut <= 0))
|
||||
if ((!aStrInW) || (!aStrOutA) || (aBufferSizeOut <= 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int numCharsConverted = WideCharToMultiByte(CP_ACP, 0, char16ptr_t(aStrInW), -1,
|
||||
aStrOutA, aBufferSizeOut,
|
||||
|
@ -967,14 +1002,12 @@ NS_ConvertWtoA(const char16_t *aStrInW, int aBufferSizeOut,
|
|||
if (!numCharsConverted) {
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
// Overflow, add missing null termination but return 0
|
||||
aStrOutA[aBufferSizeOut-1] = '\0';
|
||||
}
|
||||
else {
|
||||
aStrOutA[aBufferSizeOut - 1] = '\0';
|
||||
} else {
|
||||
// Other error, clear string and return 0
|
||||
aStrOutA[0] = '\0';
|
||||
}
|
||||
}
|
||||
else if (numCharsConverted < aBufferSizeOut) {
|
||||
} else if (numCharsConverted < aBufferSizeOut) {
|
||||
// Add 2nd null (really necessary?)
|
||||
aStrOutA[numCharsConverted] = '\0';
|
||||
}
|
||||
|
@ -987,16 +1020,16 @@ NS_ConvertWtoA(const char16_t *aStrInW, int aBufferSizeOut,
|
|||
#include "nsReadableUtils.h"
|
||||
|
||||
nsresult
|
||||
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
|
||||
NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
CopyASCIItoUTF16(input, output);
|
||||
CopyASCIItoUTF16(aInput, aOutput);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
|
||||
NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput)
|
||||
{
|
||||
LossyCopyUTF16toASCII(input, output);
|
||||
LossyCopyUTF16toASCII(aInput, aOutput);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
/**
|
||||
* thread-safe conversion routines that do not depend on uconv libraries.
|
||||
*/
|
||||
nsresult NS_CopyNativeToUnicode(const nsACString &input, nsAString &output);
|
||||
nsresult NS_CopyUnicodeToNative(const nsAString &input, nsACString &output);
|
||||
nsresult NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput);
|
||||
nsresult NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput);
|
||||
|
||||
/*
|
||||
* This function indicates whether the character encoding used in the file
|
||||
|
@ -42,7 +42,8 @@ nsresult NS_CopyUnicodeToNative(const nsAString &input, nsACString &output);
|
|||
#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(ANDROID)
|
||||
bool NS_IsNativeUTF8();
|
||||
#else
|
||||
inline bool NS_IsNativeUTF8()
|
||||
inline bool
|
||||
NS_IsNativeUTF8()
|
||||
{
|
||||
#if defined(XP_MACOSX) || defined(ANDROID)
|
||||
return true;
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
|
||||
// Generic factory constructor for the nsPipe class
|
||||
nsresult NS_HIDDEN
|
||||
nsPipeConstructor(nsISupports *outer, REFNSIID iid, void **result);
|
||||
nsPipeConstructor(nsISupports* outer, REFNSIID iid, void** result);
|
||||
|
||||
#endif // !defined(nsPipe_h__)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -12,20 +12,20 @@ NS_IMPL_ISUPPORTS(nsScriptableBase64Encoder, nsIScriptableBase64Encoder)
|
|||
|
||||
/* ACString encodeToCString (in nsIInputStream stream, in unsigned long length); */
|
||||
NS_IMETHODIMP
|
||||
nsScriptableBase64Encoder::EncodeToCString(nsIInputStream *aStream,
|
||||
nsScriptableBase64Encoder::EncodeToCString(nsIInputStream* aStream,
|
||||
uint32_t aLength,
|
||||
nsACString & _retval)
|
||||
nsACString& aResult)
|
||||
{
|
||||
Base64EncodeInputStream(aStream, _retval, aLength);
|
||||
Base64EncodeInputStream(aStream, aResult, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* AString encodeToString (in nsIInputStream stream, in unsigned long length); */
|
||||
NS_IMETHODIMP
|
||||
nsScriptableBase64Encoder::EncodeToString(nsIInputStream *aStream,
|
||||
nsScriptableBase64Encoder::EncodeToString(nsIInputStream* aStream,
|
||||
uint32_t aLength,
|
||||
nsAString & _retval)
|
||||
nsAString& aResult)
|
||||
{
|
||||
Base64EncodeInputStream(aStream, _retval, aLength);
|
||||
Base64EncodeInputStream(aStream, aResult, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISCRIPTABLEBASE64ENCODER
|
||||
private:
|
||||
~nsScriptableBase64Encoder() {}
|
||||
~nsScriptableBase64Encoder()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,39 +11,55 @@ NS_IMPL_ISUPPORTS(nsScriptableInputStream, nsIScriptableInputStream)
|
|||
|
||||
// nsIScriptableInputStream methods
|
||||
NS_IMETHODIMP
|
||||
nsScriptableInputStream::Close(void) {
|
||||
if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsScriptableInputStream::Close()
|
||||
{
|
||||
if (!mInputStream) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return mInputStream->Close();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptableInputStream::Init(nsIInputStream *aInputStream) {
|
||||
if (!aInputStream) return NS_ERROR_NULL_POINTER;
|
||||
nsScriptableInputStream::Init(nsIInputStream* aInputStream)
|
||||
{
|
||||
if (!aInputStream) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
mInputStream = aInputStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptableInputStream::Available(uint64_t *_retval) {
|
||||
if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
|
||||
return mInputStream->Available(_retval);
|
||||
nsScriptableInputStream::Available(uint64_t* aResult)
|
||||
{
|
||||
if (!mInputStream) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return mInputStream->Available(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptableInputStream::Read(uint32_t aCount, char **_retval) {
|
||||
nsScriptableInputStream::Read(uint32_t aCount, char** aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
uint64_t count64 = 0;
|
||||
char *buffer = nullptr;
|
||||
char* buffer = nullptr;
|
||||
|
||||
if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
|
||||
if (!mInputStream) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
rv = mInputStream->Available(&count64);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// bug716556 - Ensure count+1 doesn't overflow
|
||||
uint32_t count = XPCOM_MIN((uint32_t)XPCOM_MIN<uint64_t>(count64, aCount), UINT32_MAX - 1);
|
||||
buffer = (char*)moz_malloc(count+1); // make room for '\0'
|
||||
if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
|
||||
buffer = (char*)moz_malloc(count + 1); // make room for '\0'
|
||||
if (!buffer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = ReadHelper(buffer, count);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -52,25 +68,26 @@ nsScriptableInputStream::Read(uint32_t aCount, char **_retval) {
|
|||
}
|
||||
|
||||
buffer[count] = '\0';
|
||||
*_retval = buffer;
|
||||
*aResult = buffer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString &_retval) {
|
||||
nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString& aResult)
|
||||
{
|
||||
if (!mInputStream) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
_retval.SetLength(aCount);
|
||||
if (_retval.Length() != aCount) {
|
||||
aResult.SetLength(aCount);
|
||||
if (aResult.Length() != aCount) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
char *ptr = _retval.BeginWriting();
|
||||
char* ptr = aResult.BeginWriting();
|
||||
nsresult rv = ReadHelper(ptr, aCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
_retval.Truncate();
|
||||
aResult.Truncate();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -103,11 +120,17 @@ nsScriptableInputStream::ReadHelper(char* aBuffer, uint32_t aCount)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsScriptableInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {
|
||||
if (aOuter) return NS_ERROR_NO_AGGREGATION;
|
||||
nsScriptableInputStream::Create(nsISupports* aOuter, REFNSIID aIID,
|
||||
void** aResult)
|
||||
{
|
||||
if (aOuter) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
nsScriptableInputStream *sis = new nsScriptableInputStream();
|
||||
if (!sis) return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsScriptableInputStream* sis = new nsScriptableInputStream();
|
||||
if (!sis) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(sis);
|
||||
nsresult rv = sis->QueryInterface(aIID, aResult);
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#define NS_SCRIPTABLEINPUTSTREAM_CONTRACTID "@mozilla.org/scriptableinputstream;1"
|
||||
|
||||
class nsScriptableInputStream MOZ_FINAL : public nsIScriptableInputStream {
|
||||
class nsScriptableInputStream MOZ_FINAL : public nsIScriptableInputStream
|
||||
{
|
||||
public:
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -26,13 +27,17 @@ public:
|
|||
NS_DECL_NSISCRIPTABLEINPUTSTREAM
|
||||
|
||||
// nsScriptableInputStream methods
|
||||
nsScriptableInputStream() {}
|
||||
nsScriptableInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
static nsresult
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||
|
||||
private:
|
||||
~nsScriptableInputStream() {}
|
||||
~nsScriptableInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult ReadHelper(char* aBuffer, uint32_t aCount);
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
#include "nsMemory.h"
|
||||
|
||||
nsresult
|
||||
nsSegmentedBuffer::Init(uint32_t segmentSize, uint32_t maxSize)
|
||||
nsSegmentedBuffer::Init(uint32_t aSegmentSize, uint32_t aMaxSize)
|
||||
{
|
||||
if (mSegmentArrayCount != 0)
|
||||
return NS_ERROR_FAILURE; // initialized more than once
|
||||
mSegmentSize = segmentSize;
|
||||
mMaxSize = maxSize;
|
||||
if (mSegmentArrayCount != 0) {
|
||||
return NS_ERROR_FAILURE; // initialized more than once
|
||||
}
|
||||
mSegmentSize = aSegmentSize;
|
||||
mMaxSize = aMaxSize;
|
||||
#if 0 // testing...
|
||||
mSegmentArrayCount = 2;
|
||||
#else
|
||||
|
@ -25,14 +26,16 @@ nsSegmentedBuffer::Init(uint32_t segmentSize, uint32_t maxSize)
|
|||
char*
|
||||
nsSegmentedBuffer::AppendNewSegment()
|
||||
{
|
||||
if (GetSize() >= mMaxSize)
|
||||
if (GetSize() >= mMaxSize) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mSegmentArray == nullptr) {
|
||||
if (!mSegmentArray) {
|
||||
uint32_t bytes = mSegmentArrayCount * sizeof(char*);
|
||||
mSegmentArray = (char**)nsMemory::Alloc(bytes);
|
||||
if (mSegmentArray == nullptr)
|
||||
if (!mSegmentArray) {
|
||||
return nullptr;
|
||||
}
|
||||
memset(mSegmentArray, 0, bytes);
|
||||
}
|
||||
|
||||
|
@ -40,8 +43,9 @@ nsSegmentedBuffer::AppendNewSegment()
|
|||
uint32_t newArraySize = mSegmentArrayCount * 2;
|
||||
uint32_t bytes = newArraySize * sizeof(char*);
|
||||
char** newSegArray = (char**)nsMemory::Realloc(mSegmentArray, bytes);
|
||||
if (newSegArray == nullptr)
|
||||
if (!newSegArray) {
|
||||
return nullptr;
|
||||
}
|
||||
mSegmentArray = newSegArray;
|
||||
// copy wrapped content to new extension
|
||||
if (mFirstSegmentIndex > mLastSegmentIndex) {
|
||||
|
@ -53,8 +57,7 @@ nsSegmentedBuffer::AppendNewSegment()
|
|||
mLastSegmentIndex += mSegmentArrayCount;
|
||||
memset(&mSegmentArray[mLastSegmentIndex], 0,
|
||||
(newArraySize - mLastSegmentIndex) * sizeof(char*));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
memset(&mSegmentArray[mLastSegmentIndex], 0,
|
||||
(newArraySize - mLastSegmentIndex) * sizeof(char*));
|
||||
}
|
||||
|
@ -62,7 +65,7 @@ nsSegmentedBuffer::AppendNewSegment()
|
|||
}
|
||||
|
||||
char* seg = (char*)moz_malloc(mSegmentSize);
|
||||
if (seg == nullptr) {
|
||||
if (!seg) {
|
||||
return nullptr;
|
||||
}
|
||||
mSegmentArray[mLastSegmentIndex] = seg;
|
||||
|
@ -80,8 +83,7 @@ nsSegmentedBuffer::DeleteFirstSegment()
|
|||
if (mFirstSegmentIndex == last) {
|
||||
mLastSegmentIndex = last;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mFirstSegmentIndex = ModSegArraySize(mFirstSegmentIndex + 1);
|
||||
return false;
|
||||
}
|
||||
|
@ -99,18 +101,16 @@ nsSegmentedBuffer::DeleteLastSegment()
|
|||
}
|
||||
|
||||
bool
|
||||
nsSegmentedBuffer::ReallocLastSegment(size_t newSize)
|
||||
nsSegmentedBuffer::ReallocLastSegment(size_t aNewSize)
|
||||
{
|
||||
int32_t last = ModSegArraySize(mLastSegmentIndex - 1);
|
||||
NS_ASSERTION(mSegmentArray[last] != nullptr, "realloc'ing bad segment");
|
||||
char *newSegment =
|
||||
(char*)moz_realloc(mSegmentArray[last], newSize);
|
||||
char* newSegment = (char*)moz_realloc(mSegmentArray[last], aNewSize);
|
||||
if (newSegment) {
|
||||
mSegmentArray[last] = newSegment;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -118,8 +118,9 @@ nsSegmentedBuffer::Empty()
|
|||
{
|
||||
if (mSegmentArray) {
|
||||
for (uint32_t i = 0; i < mSegmentArrayCount; i++) {
|
||||
if (mSegmentArray[i])
|
||||
if (mSegmentArray[i]) {
|
||||
moz_free(mSegmentArray[i]);
|
||||
}
|
||||
}
|
||||
nsMemory::Free(mSegmentArray);
|
||||
mSegmentArray = nullptr;
|
||||
|
|
|
@ -13,17 +13,22 @@ class nsSegmentedBuffer
|
|||
{
|
||||
public:
|
||||
nsSegmentedBuffer()
|
||||
: mSegmentSize(0), mMaxSize(0),
|
||||
mSegmentArray(nullptr),
|
||||
mSegmentArrayCount(0),
|
||||
mFirstSegmentIndex(0), mLastSegmentIndex(0) {}
|
||||
: mSegmentSize(0)
|
||||
, mMaxSize(0)
|
||||
, mSegmentArray(nullptr)
|
||||
, mSegmentArrayCount(0)
|
||||
, mFirstSegmentIndex(0)
|
||||
, mLastSegmentIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
~nsSegmentedBuffer() {
|
||||
~nsSegmentedBuffer()
|
||||
{
|
||||
Empty();
|
||||
}
|
||||
|
||||
|
||||
nsresult Init(uint32_t segmentSize, uint32_t maxSize);
|
||||
nsresult Init(uint32_t aSegmentSize, uint32_t aMaxSize);
|
||||
|
||||
char* AppendNewSegment(); // pushes at end
|
||||
|
||||
|
@ -35,36 +40,50 @@ public:
|
|||
|
||||
// Call Realloc() on last segment. This is used to reduce memory
|
||||
// consumption when data is not an exact multiple of segment size.
|
||||
bool ReallocLastSegment(size_t newSize);
|
||||
bool ReallocLastSegment(size_t aNewSize);
|
||||
|
||||
void Empty(); // frees all segments
|
||||
|
||||
inline uint32_t GetSegmentCount() {
|
||||
if (mFirstSegmentIndex <= mLastSegmentIndex)
|
||||
inline uint32_t GetSegmentCount()
|
||||
{
|
||||
if (mFirstSegmentIndex <= mLastSegmentIndex) {
|
||||
return mLastSegmentIndex - mFirstSegmentIndex;
|
||||
else
|
||||
} else {
|
||||
return mSegmentArrayCount + mLastSegmentIndex - mFirstSegmentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t GetSegmentSize() { return mSegmentSize; }
|
||||
inline uint32_t GetMaxSize() { return mMaxSize; }
|
||||
inline uint32_t GetSize() { return GetSegmentCount() * mSegmentSize; }
|
||||
inline uint32_t GetSegmentSize()
|
||||
{
|
||||
return mSegmentSize;
|
||||
}
|
||||
inline uint32_t GetMaxSize()
|
||||
{
|
||||
return mMaxSize;
|
||||
}
|
||||
inline uint32_t GetSize()
|
||||
{
|
||||
return GetSegmentCount() * mSegmentSize;
|
||||
}
|
||||
|
||||
inline char* GetSegment(uint32_t indx) {
|
||||
NS_ASSERTION(indx < GetSegmentCount(), "index out of bounds");
|
||||
int32_t i = ModSegArraySize(mFirstSegmentIndex + (int32_t)indx);
|
||||
inline char* GetSegment(uint32_t aIndex)
|
||||
{
|
||||
NS_ASSERTION(aIndex < GetSegmentCount(), "index out of bounds");
|
||||
int32_t i = ModSegArraySize(mFirstSegmentIndex + (int32_t)aIndex);
|
||||
return mSegmentArray[i];
|
||||
}
|
||||
|
||||
protected:
|
||||
inline int32_t ModSegArraySize(int32_t n) {
|
||||
uint32_t result = n & (mSegmentArrayCount - 1);
|
||||
NS_ASSERTION(result == n % mSegmentArrayCount,
|
||||
inline int32_t ModSegArraySize(int32_t aIndex)
|
||||
{
|
||||
uint32_t result = aIndex & (mSegmentArrayCount - 1);
|
||||
NS_ASSERTION(result == aIndex % mSegmentArrayCount,
|
||||
"non-power-of-2 mSegmentArrayCount");
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool IsFull() {
|
||||
inline bool IsFull()
|
||||
{
|
||||
return ModSegArraySize(mLastSegmentIndex + 1) == mFirstSegmentIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
static PRLogModuleInfo*
|
||||
GetStorageStreamLog()
|
||||
{
|
||||
static PRLogModuleInfo *sLog;
|
||||
if (!sLog)
|
||||
static PRLogModuleInfo* sLog;
|
||||
if (!sLog) {
|
||||
sLog = PR_NewLogModule("nsStorageStream");
|
||||
}
|
||||
return sLog;
|
||||
}
|
||||
#endif
|
||||
|
@ -67,36 +68,43 @@ NS_IMPL_ISUPPORTS(nsStorageStream,
|
|||
nsIOutputStream)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::Init(uint32_t segmentSize, uint32_t maxSize)
|
||||
nsStorageStream::Init(uint32_t aSegmentSize, uint32_t aMaxSize)
|
||||
{
|
||||
mSegmentedBuffer = new nsSegmentedBuffer();
|
||||
if (!mSegmentedBuffer)
|
||||
if (!mSegmentedBuffer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mSegmentSize = segmentSize;
|
||||
mSegmentSizeLog2 = mozilla::FloorLog2(segmentSize);
|
||||
mSegmentSize = aSegmentSize;
|
||||
mSegmentSizeLog2 = mozilla::FloorLog2(aSegmentSize);
|
||||
|
||||
// Segment size must be a power of two
|
||||
if (mSegmentSize != ((uint32_t)1 << mSegmentSizeLog2))
|
||||
if (mSegmentSize != ((uint32_t)1 << mSegmentSizeLog2)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return mSegmentedBuffer->Init(segmentSize, maxSize);
|
||||
return mSegmentedBuffer->Init(aSegmentSize, aMaxSize);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::GetOutputStream(int32_t aStartingOffset,
|
||||
nsIOutputStream * *aOutputStream)
|
||||
nsIOutputStream** aOutputStream)
|
||||
{
|
||||
if (NS_WARN_IF(!aOutputStream))
|
||||
if (NS_WARN_IF(!aOutputStream)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
}
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (mWriteInProgress)
|
||||
if (mWriteInProgress) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult rv = Seek(aStartingOffset);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Enlarge the last segment in the buffer so that it is the same size as
|
||||
// all the other segments in the buffer. (It may have been realloc'ed
|
||||
|
@ -105,7 +113,9 @@ nsStorageStream::GetOutputStream(int32_t aStartingOffset,
|
|||
if (mSegmentedBuffer->ReallocLastSegment(mSegmentSize)) {
|
||||
// Need to re-Seek, since realloc changed segment base pointer
|
||||
rv = Seek(aStartingOffset);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(this);
|
||||
|
@ -117,8 +127,9 @@ nsStorageStream::GetOutputStream(int32_t aStartingOffset,
|
|||
NS_IMETHODIMP
|
||||
nsStorageStream::Close()
|
||||
{
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mWriteInProgress = false;
|
||||
|
||||
|
@ -126,8 +137,9 @@ nsStorageStream::Close()
|
|||
|
||||
// Shrink the final segment in the segmented buffer to the minimum size
|
||||
// needed to contain the data, so as to conserve memory.
|
||||
if (segmentOffset)
|
||||
if (segmentOffset) {
|
||||
mSegmentedBuffer->ReallocLastSegment(segmentOffset);
|
||||
}
|
||||
|
||||
mWriteCursor = 0;
|
||||
mSegmentEnd = 0;
|
||||
|
@ -145,12 +157,15 @@ nsStorageStream::Flush()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::Write(const char *aBuffer, uint32_t aCount, uint32_t *aNumWritten)
|
||||
nsStorageStream::Write(const char* aBuffer, uint32_t aCount,
|
||||
uint32_t* aNumWritten)
|
||||
{
|
||||
if (NS_WARN_IF(!aNumWritten) || NS_WARN_IF(!aBuffer))
|
||||
if (NS_WARN_IF(!aNumWritten) || NS_WARN_IF(!aBuffer)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
}
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
const char* readCursor;
|
||||
uint32_t count, availableInSegment, remaining;
|
||||
|
@ -204,26 +219,28 @@ out:
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::WriteFrom(nsIInputStream *inStr, uint32_t count, uint32_t *_retval)
|
||||
nsStorageStream::WriteFrom(nsIInputStream* aInStr, uint32_t aCount,
|
||||
uint32_t* aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::WriteSegments(nsReadSegmentFun reader, void * closure, uint32_t count, uint32_t *_retval)
|
||||
nsStorageStream::WriteSegments(nsReadSegmentFun aReader, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsStorageStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
*aNonBlocking = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::GetLength(uint32_t *aLength)
|
||||
nsStorageStream::GetLength(uint32_t* aLength)
|
||||
{
|
||||
*aLength = mLogicalLength;
|
||||
return NS_OK;
|
||||
|
@ -233,19 +250,23 @@ nsStorageStream::GetLength(uint32_t *aLength)
|
|||
NS_IMETHODIMP
|
||||
nsStorageStream::SetLength(uint32_t aLength)
|
||||
{
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (mWriteInProgress)
|
||||
if (mWriteInProgress) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (aLength > mLogicalLength)
|
||||
if (aLength > mLogicalLength) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
int32_t newLastSegmentNum = SegNum(aLength);
|
||||
int32_t segmentOffset = SegOffset(aLength);
|
||||
if (segmentOffset == 0)
|
||||
if (segmentOffset == 0) {
|
||||
newLastSegmentNum--;
|
||||
}
|
||||
|
||||
while (newLastSegmentNum < mLastSegmentNum) {
|
||||
mSegmentedBuffer->DeleteLastSegment();
|
||||
|
@ -257,7 +278,7 @@ nsStorageStream::SetLength(uint32_t aLength)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::GetWriteInProgress(bool *aWriteInProgress)
|
||||
nsStorageStream::GetWriteInProgress(bool* aWriteInProgress)
|
||||
{
|
||||
*aWriteInProgress = mWriteInProgress;
|
||||
return NS_OK;
|
||||
|
@ -266,16 +287,19 @@ nsStorageStream::GetWriteInProgress(bool *aWriteInProgress)
|
|||
NS_METHOD
|
||||
nsStorageStream::Seek(int32_t aPosition)
|
||||
{
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
// An argument of -1 means "seek to end of stream"
|
||||
if (aPosition == -1)
|
||||
if (aPosition == -1) {
|
||||
aPosition = mLogicalLength;
|
||||
}
|
||||
|
||||
// Seeking beyond the buffer end is illegal
|
||||
if ((uint32_t)aPosition > mLogicalLength)
|
||||
if ((uint32_t)aPosition > mLogicalLength) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Seeking backwards in the write stream results in truncation
|
||||
SetLength(aPosition);
|
||||
|
@ -298,10 +322,11 @@ nsStorageStream::Seek(int32_t aPosition)
|
|||
// because SegNum may reference the next-to-be-allocated segment, in which
|
||||
// case we need to be pointing at the end of the last segment.
|
||||
int32_t segmentOffset = SegOffset(aPosition);
|
||||
if (segmentOffset == 0 && (SegNum(aPosition) > (uint32_t) mLastSegmentNum))
|
||||
if (segmentOffset == 0 && (SegNum(aPosition) > (uint32_t) mLastSegmentNum)) {
|
||||
mWriteCursor = mSegmentEnd;
|
||||
else
|
||||
} else {
|
||||
mWriteCursor += segmentOffset;
|
||||
}
|
||||
|
||||
LOG(("nsStorageStream [%p] Seek mWriteCursor=%x mSegmentEnd=%x\n",
|
||||
this, mWriteCursor, mSegmentEnd));
|
||||
|
@ -311,11 +336,12 @@ nsStorageStream::Seek(int32_t aPosition)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// There can be many nsStorageInputStreams for a single nsStorageStream
|
||||
class nsStorageInputStream MOZ_FINAL : public nsIInputStream
|
||||
, public nsISeekableStream
|
||||
class nsStorageInputStream MOZ_FINAL
|
||||
: public nsIInputStream
|
||||
, public nsISeekableStream
|
||||
{
|
||||
public:
|
||||
nsStorageInputStream(nsStorageStream *aStorageStream, uint32_t aSegmentSize)
|
||||
nsStorageInputStream(nsStorageStream* aStorageStream, uint32_t aSegmentSize)
|
||||
: mStorageStream(aStorageStream), mReadCursor(0),
|
||||
mSegmentEnd(0), mSegmentNum(0),
|
||||
mSegmentSize(aSegmentSize), mLogicalCursor(0),
|
||||
|
@ -348,8 +374,14 @@ private:
|
|||
uint32_t mLogicalCursor; // Logical offset into stream
|
||||
nsresult mStatus;
|
||||
|
||||
uint32_t SegNum(uint32_t aPosition) {return aPosition >> mStorageStream->mSegmentSizeLog2;}
|
||||
uint32_t SegOffset(uint32_t aPosition) {return aPosition & (mSegmentSize - 1);}
|
||||
uint32_t SegNum(uint32_t aPosition)
|
||||
{
|
||||
return aPosition >> mStorageStream->mSegmentSizeLog2;
|
||||
}
|
||||
uint32_t SegOffset(uint32_t aPosition)
|
||||
{
|
||||
return aPosition & (mSegmentSize - 1);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsStorageInputStream,
|
||||
|
@ -357,14 +389,18 @@ NS_IMPL_ISUPPORTS(nsStorageInputStream,
|
|||
nsISeekableStream)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageStream::NewInputStream(int32_t aStartingOffset, nsIInputStream* *aInputStream)
|
||||
nsStorageStream::NewInputStream(int32_t aStartingOffset,
|
||||
nsIInputStream** aInputStream)
|
||||
{
|
||||
if (NS_WARN_IF(!mSegmentedBuffer))
|
||||
if (NS_WARN_IF(!mSegmentedBuffer)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsStorageInputStream *inputStream = new nsStorageInputStream(this, mSegmentSize);
|
||||
if (!inputStream)
|
||||
nsStorageInputStream* inputStream =
|
||||
new nsStorageInputStream(this, mSegmentSize);
|
||||
if (!inputStream) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(inputStream);
|
||||
|
||||
|
@ -386,29 +422,33 @@ nsStorageInputStream::Close()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageInputStream::Available(uint64_t *aAvailable)
|
||||
nsStorageInputStream::Available(uint64_t* aAvailable)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
*aAvailable = mStorageStream->mLogicalLength - mLogicalCursor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t *aNumRead)
|
||||
nsStorageInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aNumRead)
|
||||
{
|
||||
return ReadSegments(NS_CopySegmentToBuffer, aBuffer, aCount, aNumRead);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uint32_t aCount, uint32_t *aNumRead)
|
||||
nsStorageInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aNumRead)
|
||||
{
|
||||
*aNumRead = 0;
|
||||
if (mStatus == NS_BASE_STREAM_CLOSED)
|
||||
if (mStatus == NS_BASE_STREAM_CLOSED) {
|
||||
return NS_OK;
|
||||
if (NS_FAILED(mStatus))
|
||||
}
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
uint32_t count, availableInSegment, remainingCapacity, bytesConsumed;
|
||||
nsresult rv;
|
||||
|
@ -418,21 +458,23 @@ nsStorageInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uin
|
|||
availableInSegment = mSegmentEnd - mReadCursor;
|
||||
if (!availableInSegment) {
|
||||
uint32_t available = mStorageStream->mLogicalLength - mLogicalCursor;
|
||||
if (!available)
|
||||
if (!available) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
mSegmentNum++;
|
||||
mReadCursor = 0;
|
||||
mSegmentEnd = XPCOM_MIN(mSegmentSize, available);
|
||||
availableInSegment = mSegmentEnd;
|
||||
}
|
||||
const char *cur = mStorageStream->mSegmentedBuffer->GetSegment(mSegmentNum);
|
||||
const char* cur = mStorageStream->mSegmentedBuffer->GetSegment(mSegmentNum);
|
||||
|
||||
count = XPCOM_MIN(availableInSegment, remainingCapacity);
|
||||
rv = writer(this, closure, cur + mReadCursor, aCount - remainingCapacity,
|
||||
rv = aWriter(this, aClosure, cur + mReadCursor, aCount - remainingCapacity,
|
||||
count, &bytesConsumed);
|
||||
if (NS_FAILED(rv) || (bytesConsumed == 0))
|
||||
if (NS_FAILED(rv) || (bytesConsumed == 0)) {
|
||||
break;
|
||||
}
|
||||
remainingCapacity -= bytesConsumed;
|
||||
mReadCursor += bytesConsumed;
|
||||
mLogicalCursor += bytesConsumed;
|
||||
|
@ -442,17 +484,19 @@ out:
|
|||
*aNumRead = aCount - remainingCapacity;
|
||||
|
||||
bool isWriteInProgress = false;
|
||||
if (NS_FAILED(mStorageStream->GetWriteInProgress(&isWriteInProgress)))
|
||||
if (NS_FAILED(mStorageStream->GetWriteInProgress(&isWriteInProgress))) {
|
||||
isWriteInProgress = false;
|
||||
}
|
||||
|
||||
if (*aNumRead == 0 && isWriteInProgress)
|
||||
if (*aNumRead == 0 && isWriteInProgress) {
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageInputStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsStorageInputStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
// TODO: This class should implement nsIAsyncInputStream so that callers
|
||||
// have some way of dealing with NS_BASE_STREAM_WOULD_BLOCK errors.
|
||||
|
@ -464,8 +508,9 @@ nsStorageInputStream::IsNonBlocking(bool *aNonBlocking)
|
|||
NS_IMETHODIMP
|
||||
nsStorageInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
int64_t pos = aOffset;
|
||||
|
||||
|
@ -482,17 +527,19 @@ nsStorageInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
|||
NS_NOTREACHED("unexpected whence value");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (pos == int64_t(mLogicalCursor))
|
||||
if (pos == int64_t(mLogicalCursor)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return Seek(pos);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStorageInputStream::Tell(int64_t *aResult)
|
||||
nsStorageInputStream::Tell(int64_t* aResult)
|
||||
{
|
||||
if (NS_FAILED(mStatus))
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
*aResult = mLogicalCursor;
|
||||
return NS_OK;
|
||||
|
@ -509,11 +556,13 @@ NS_METHOD
|
|||
nsStorageInputStream::Seek(uint32_t aPosition)
|
||||
{
|
||||
uint32_t length = mStorageStream->mLogicalLength;
|
||||
if (aPosition > length)
|
||||
if (aPosition > length) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
if (length == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mSegmentNum = SegNum(aPosition);
|
||||
mReadCursor = SegOffset(aPosition);
|
||||
|
@ -524,18 +573,21 @@ nsStorageInputStream::Seek(uint32_t aPosition)
|
|||
}
|
||||
|
||||
nsresult
|
||||
NS_NewStorageStream(uint32_t segmentSize, uint32_t maxSize, nsIStorageStream **result)
|
||||
NS_NewStorageStream(uint32_t aSegmentSize, uint32_t aMaxSize,
|
||||
nsIStorageStream** aResult)
|
||||
{
|
||||
nsStorageStream* storageStream = new nsStorageStream();
|
||||
if (!storageStream) return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!storageStream) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(storageStream);
|
||||
nsresult rv = storageStream->Init(segmentSize, maxSize);
|
||||
nsresult rv = storageStream->Init(aSegmentSize, aMaxSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(storageStream);
|
||||
return rv;
|
||||
}
|
||||
*result = storageStream;
|
||||
*aResult = storageStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
|
||||
class nsSegmentedBuffer;
|
||||
|
||||
class nsStorageStream MOZ_FINAL : public nsIStorageStream,
|
||||
public nsIOutputStream
|
||||
class nsStorageStream MOZ_FINAL
|
||||
: public nsIStorageStream
|
||||
, public nsIOutputStream
|
||||
{
|
||||
public:
|
||||
nsStorageStream();
|
||||
|
@ -59,8 +60,14 @@ private:
|
|||
uint32_t mLogicalLength; // Number of bytes written to stream
|
||||
|
||||
NS_METHOD Seek(int32_t aPosition);
|
||||
uint32_t SegNum(uint32_t aPosition) {return aPosition >> mSegmentSizeLog2;}
|
||||
uint32_t SegOffset(uint32_t aPosition) {return aPosition & (mSegmentSize - 1);}
|
||||
uint32_t SegNum(uint32_t aPosition)
|
||||
{
|
||||
return aPosition >> mSegmentSizeLog2;
|
||||
}
|
||||
uint32_t SegOffset(uint32_t aPosition)
|
||||
{
|
||||
return aPosition & (mSegmentSize - 1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _nsStorageStream_h_
|
||||
|
|
|
@ -22,24 +22,26 @@ using namespace mozilla;
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsInputStreamReadyEvent MOZ_FINAL : public nsIRunnable
|
||||
, public nsIInputStreamCallback
|
||||
class nsInputStreamReadyEvent MOZ_FINAL
|
||||
: public nsIRunnable
|
||||
, public nsIInputStreamCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
nsInputStreamReadyEvent(nsIInputStreamCallback *callback,
|
||||
nsIEventTarget *target)
|
||||
: mCallback(callback)
|
||||
, mTarget(target)
|
||||
nsInputStreamReadyEvent(nsIInputStreamCallback* aCallback,
|
||||
nsIEventTarget* aTarget)
|
||||
: mCallback(aCallback)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
~nsInputStreamReadyEvent()
|
||||
{
|
||||
if (!mCallback)
|
||||
if (!mCallback) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// whoa!! looks like we never posted this event. take care to
|
||||
// release mCallback on the correct thread. if mTarget lives on the
|
||||
|
@ -57,7 +59,7 @@ private:
|
|||
rv = event->OnInputStreamReady(nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_NOTREACHED("leaking stream event");
|
||||
nsISupports *sup = event;
|
||||
nsISupports* sup = event;
|
||||
NS_ADDREF(sup);
|
||||
}
|
||||
}
|
||||
|
@ -65,9 +67,9 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *stream)
|
||||
NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream* aStream)
|
||||
{
|
||||
mStream = stream;
|
||||
mStream = aStream;
|
||||
|
||||
nsresult rv =
|
||||
mTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
|
@ -82,8 +84,9 @@ public:
|
|||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mCallback) {
|
||||
if (mStream)
|
||||
if (mStream) {
|
||||
mCallback->OnInputStreamReady(mStream);
|
||||
}
|
||||
mCallback = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -100,24 +103,26 @@ NS_IMPL_ISUPPORTS(nsInputStreamReadyEvent, nsIRunnable,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsOutputStreamReadyEvent MOZ_FINAL : public nsIRunnable
|
||||
, public nsIOutputStreamCallback
|
||||
class nsOutputStreamReadyEvent MOZ_FINAL
|
||||
: public nsIRunnable
|
||||
, public nsIOutputStreamCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
nsOutputStreamReadyEvent(nsIOutputStreamCallback *callback,
|
||||
nsIEventTarget *target)
|
||||
: mCallback(callback)
|
||||
, mTarget(target)
|
||||
nsOutputStreamReadyEvent(nsIOutputStreamCallback* aCallback,
|
||||
nsIEventTarget* aTarget)
|
||||
: mCallback(aCallback)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
~nsOutputStreamReadyEvent()
|
||||
{
|
||||
if (!mCallback)
|
||||
if (!mCallback) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// whoa!! looks like we never posted this event. take care to
|
||||
// release mCallback on the correct thread. if mTarget lives on the
|
||||
|
@ -135,7 +140,7 @@ private:
|
|||
rv = event->OnOutputStreamReady(nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_NOTREACHED("leaking stream event");
|
||||
nsISupports *sup = event;
|
||||
nsISupports* sup = event;
|
||||
NS_ADDREF(sup);
|
||||
}
|
||||
}
|
||||
|
@ -143,9 +148,9 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *stream)
|
||||
NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream* aStream)
|
||||
{
|
||||
mStream = stream;
|
||||
mStream = aStream;
|
||||
|
||||
nsresult rv =
|
||||
mTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
|
@ -160,8 +165,9 @@ public:
|
|||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mCallback) {
|
||||
if (mStream)
|
||||
if (mStream) {
|
||||
mCallback->OnOutputStreamReady(mStream);
|
||||
}
|
||||
mCallback = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -179,24 +185,24 @@ NS_IMPL_ISUPPORTS(nsOutputStreamReadyEvent, nsIRunnable,
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
already_AddRefed<nsIInputStreamCallback>
|
||||
NS_NewInputStreamReadyEvent(nsIInputStreamCallback *callback,
|
||||
nsIEventTarget *target)
|
||||
NS_NewInputStreamReadyEvent(nsIInputStreamCallback* aCallback,
|
||||
nsIEventTarget* aTarget)
|
||||
{
|
||||
NS_ASSERTION(callback, "null callback");
|
||||
NS_ASSERTION(target, "null target");
|
||||
NS_ASSERTION(aCallback, "null callback");
|
||||
NS_ASSERTION(aTarget, "null target");
|
||||
nsRefPtr<nsInputStreamReadyEvent> ev =
|
||||
new nsInputStreamReadyEvent(callback, target);
|
||||
new nsInputStreamReadyEvent(aCallback, aTarget);
|
||||
return ev.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIOutputStreamCallback>
|
||||
NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback *callback,
|
||||
nsIEventTarget *target)
|
||||
NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback* aCallback,
|
||||
nsIEventTarget* aTarget)
|
||||
{
|
||||
NS_ASSERTION(callback, "null callback");
|
||||
NS_ASSERTION(target, "null target");
|
||||
NS_ASSERTION(aCallback, "null callback");
|
||||
NS_ASSERTION(aTarget, "null target");
|
||||
nsRefPtr<nsOutputStreamReadyEvent> ev =
|
||||
new nsOutputStreamReadyEvent(callback, target);
|
||||
new nsOutputStreamReadyEvent(aCallback, aTarget);
|
||||
return ev.forget();
|
||||
}
|
||||
|
||||
|
@ -204,9 +210,10 @@ NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback *callback,
|
|||
// NS_AsyncCopy implementation
|
||||
|
||||
// abstract stream copier...
|
||||
class nsAStreamCopier : public nsIInputStreamCallback
|
||||
, public nsIOutputStreamCallback
|
||||
, public nsIRunnable
|
||||
class nsAStreamCopier
|
||||
: public nsIInputStreamCallback
|
||||
, public nsIOutputStreamCallback
|
||||
, public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -232,25 +239,25 @@ public:
|
|||
}
|
||||
|
||||
// kick off the async copy...
|
||||
nsresult Start(nsIInputStream *source,
|
||||
nsIOutputStream *sink,
|
||||
nsIEventTarget *target,
|
||||
nsAsyncCopyCallbackFun callback,
|
||||
void *closure,
|
||||
uint32_t chunksize,
|
||||
bool closeSource,
|
||||
bool closeSink,
|
||||
nsAsyncCopyProgressFun progressCallback)
|
||||
nsresult Start(nsIInputStream* aSource,
|
||||
nsIOutputStream* aSink,
|
||||
nsIEventTarget* aTarget,
|
||||
nsAsyncCopyCallbackFun aCallback,
|
||||
void* aClosure,
|
||||
uint32_t aChunksize,
|
||||
bool aCloseSource,
|
||||
bool aCloseSink,
|
||||
nsAsyncCopyProgressFun aProgressCallback)
|
||||
{
|
||||
mSource = source;
|
||||
mSink = sink;
|
||||
mTarget = target;
|
||||
mCallback = callback;
|
||||
mClosure = closure;
|
||||
mChunkSize = chunksize;
|
||||
mCloseSource = closeSource;
|
||||
mCloseSink = closeSink;
|
||||
mProgressCallback = progressCallback;
|
||||
mSource = aSource;
|
||||
mSink = aSink;
|
||||
mTarget = aTarget;
|
||||
mCallback = aCallback;
|
||||
mClosure = aClosure;
|
||||
mChunkSize = aChunksize;
|
||||
mCloseSource = aCloseSource;
|
||||
mCloseSink = aCloseSink;
|
||||
mProgressCallback = aProgressCallback;
|
||||
|
||||
mAsyncSource = do_QueryInterface(mSource);
|
||||
mAsyncSink = do_QueryInterface(mSink);
|
||||
|
@ -260,12 +267,14 @@ public:
|
|||
|
||||
// implemented by subclasses, returns number of bytes copied and
|
||||
// sets source and sink condition before returning.
|
||||
virtual uint32_t DoCopy(nsresult *sourceCondition, nsresult *sinkCondition) = 0;
|
||||
virtual uint32_t DoCopy(nsresult* aSourceCondition,
|
||||
nsresult* aSinkCondition) = 0;
|
||||
|
||||
void Process()
|
||||
{
|
||||
if (!mSource || !mSink)
|
||||
if (!mSource || !mSink) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult sourceCondition, sinkCondition;
|
||||
nsresult cancelStatus;
|
||||
|
@ -306,8 +315,7 @@ public:
|
|||
nsIAsyncOutputStream::WAIT_CLOSURE_ONLY,
|
||||
0, nullptr);
|
||||
break;
|
||||
}
|
||||
else if (sinkCondition == NS_BASE_STREAM_WOULD_BLOCK && mAsyncSink) {
|
||||
} else if (sinkCondition == NS_BASE_STREAM_WOULD_BLOCK && mAsyncSink) {
|
||||
// need to wait for more room in the sink. while waiting for
|
||||
// more room in the sink, be sure to observer failures on the
|
||||
// input end.
|
||||
|
@ -324,10 +332,11 @@ public:
|
|||
if (mCloseSource) {
|
||||
// close source
|
||||
if (mAsyncSource)
|
||||
mAsyncSource->CloseWithStatus(canceled ? cancelStatus :
|
||||
sinkCondition);
|
||||
else
|
||||
mAsyncSource->CloseWithStatus(
|
||||
canceled ? cancelStatus : sinkCondition);
|
||||
else {
|
||||
mSource->Close();
|
||||
}
|
||||
}
|
||||
mAsyncSource = nullptr;
|
||||
mSource = nullptr;
|
||||
|
@ -335,8 +344,8 @@ public:
|
|||
if (mCloseSink) {
|
||||
// close sink
|
||||
if (mAsyncSink)
|
||||
mAsyncSink->CloseWithStatus(canceled ? cancelStatus :
|
||||
sourceCondition);
|
||||
mAsyncSink->CloseWithStatus(
|
||||
canceled ? cancelStatus : sourceCondition);
|
||||
else {
|
||||
// If we have an nsISafeOutputStream, and our
|
||||
// sourceCondition and sinkCondition are not set to a
|
||||
|
@ -344,10 +353,11 @@ public:
|
|||
nsCOMPtr<nsISafeOutputStream> sostream =
|
||||
do_QueryInterface(mSink);
|
||||
if (sostream && NS_SUCCEEDED(sourceCondition) &&
|
||||
NS_SUCCEEDED(sinkCondition))
|
||||
NS_SUCCEEDED(sinkCondition)) {
|
||||
sostream->Finish();
|
||||
else
|
||||
} else {
|
||||
mSink->Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
mAsyncSink = nullptr;
|
||||
|
@ -358,10 +368,12 @@ public:
|
|||
nsresult status;
|
||||
if (!canceled) {
|
||||
status = sourceCondition;
|
||||
if (NS_SUCCEEDED(status))
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
status = sinkCondition;
|
||||
if (status == NS_BASE_STREAM_CLOSED)
|
||||
}
|
||||
if (status == NS_BASE_STREAM_CLOSED) {
|
||||
status = NS_OK;
|
||||
}
|
||||
} else {
|
||||
status = cancelStatus;
|
||||
}
|
||||
|
@ -375,8 +387,9 @@ public:
|
|||
nsresult Cancel(nsresult aReason)
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
if (mCanceled)
|
||||
if (mCanceled) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(aReason)) {
|
||||
NS_WARNING("cancel with non-failure status code");
|
||||
|
@ -388,13 +401,13 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *source)
|
||||
NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream* aSource)
|
||||
{
|
||||
PostContinuationEvent();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *sink)
|
||||
NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream* aSink)
|
||||
{
|
||||
PostContinuationEvent();
|
||||
return NS_OK;
|
||||
|
@ -432,14 +445,15 @@ public:
|
|||
nsresult PostContinuationEvent_Locked()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mEventInProcess)
|
||||
if (mEventInProcess) {
|
||||
mEventIsPending = true;
|
||||
else {
|
||||
} else {
|
||||
rv = mTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mEventInProcess = true;
|
||||
else
|
||||
} else {
|
||||
NS_WARNING("unable to post continuation event");
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -453,7 +467,7 @@ protected:
|
|||
Mutex mLock;
|
||||
nsAsyncCopyCallbackFun mCallback;
|
||||
nsAsyncCopyProgressFun mProgressCallback;
|
||||
void *mClosure;
|
||||
void* mClosure;
|
||||
uint32_t mChunkSize;
|
||||
bool mEventInProcess;
|
||||
bool mEventIsPending;
|
||||
|
@ -471,42 +485,48 @@ NS_IMPL_ISUPPORTS(nsAStreamCopier,
|
|||
class nsStreamCopierIB MOZ_FINAL : public nsAStreamCopier
|
||||
{
|
||||
public:
|
||||
nsStreamCopierIB() : nsAStreamCopier() {}
|
||||
virtual ~nsStreamCopierIB() {}
|
||||
nsStreamCopierIB() : nsAStreamCopier()
|
||||
{
|
||||
}
|
||||
virtual ~nsStreamCopierIB()
|
||||
{
|
||||
}
|
||||
|
||||
struct ReadSegmentsState {
|
||||
nsIOutputStream *mSink;
|
||||
struct ReadSegmentsState
|
||||
{
|
||||
nsIOutputStream* mSink;
|
||||
nsresult mSinkCondition;
|
||||
};
|
||||
|
||||
static NS_METHOD ConsumeInputBuffer(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
static NS_METHOD ConsumeInputBuffer(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
ReadSegmentsState *state = (ReadSegmentsState *) closure;
|
||||
ReadSegmentsState* state = (ReadSegmentsState*)aClosure;
|
||||
|
||||
nsresult rv = state->mSink->Write(buffer, count, countWritten);
|
||||
if (NS_FAILED(rv))
|
||||
nsresult rv = state->mSink->Write(aBuffer, aCount, aCountWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
state->mSinkCondition = rv;
|
||||
else if (*countWritten == 0)
|
||||
} else if (*aCountWritten == 0) {
|
||||
state->mSinkCondition = NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
return state->mSinkCondition;
|
||||
}
|
||||
|
||||
uint32_t DoCopy(nsresult *sourceCondition, nsresult *sinkCondition)
|
||||
uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition)
|
||||
{
|
||||
ReadSegmentsState state;
|
||||
state.mSink = mSink;
|
||||
state.mSinkCondition = NS_OK;
|
||||
|
||||
uint32_t n;
|
||||
*sourceCondition =
|
||||
*aSourceCondition =
|
||||
mSource->ReadSegments(ConsumeInputBuffer, &state, mChunkSize, &n);
|
||||
*sinkCondition = state.mSinkCondition;
|
||||
*aSinkCondition = state.mSinkCondition;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
@ -514,42 +534,48 @@ public:
|
|||
class nsStreamCopierOB MOZ_FINAL : public nsAStreamCopier
|
||||
{
|
||||
public:
|
||||
nsStreamCopierOB() : nsAStreamCopier() {}
|
||||
virtual ~nsStreamCopierOB() {}
|
||||
nsStreamCopierOB() : nsAStreamCopier()
|
||||
{
|
||||
}
|
||||
virtual ~nsStreamCopierOB()
|
||||
{
|
||||
}
|
||||
|
||||
struct WriteSegmentsState {
|
||||
nsIInputStream *mSource;
|
||||
struct WriteSegmentsState
|
||||
{
|
||||
nsIInputStream* mSource;
|
||||
nsresult mSourceCondition;
|
||||
};
|
||||
|
||||
static NS_METHOD FillOutputBuffer(nsIOutputStream *outStr,
|
||||
void *closure,
|
||||
char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countRead)
|
||||
static NS_METHOD FillOutputBuffer(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead)
|
||||
{
|
||||
WriteSegmentsState *state = (WriteSegmentsState *) closure;
|
||||
WriteSegmentsState* state = (WriteSegmentsState*)aClosure;
|
||||
|
||||
nsresult rv = state->mSource->Read(buffer, count, countRead);
|
||||
if (NS_FAILED(rv))
|
||||
nsresult rv = state->mSource->Read(aBuffer, aCount, aCountRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
state->mSourceCondition = rv;
|
||||
else if (*countRead == 0)
|
||||
} else if (*aCountRead == 0) {
|
||||
state->mSourceCondition = NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
return state->mSourceCondition;
|
||||
}
|
||||
|
||||
uint32_t DoCopy(nsresult *sourceCondition, nsresult *sinkCondition)
|
||||
uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition)
|
||||
{
|
||||
WriteSegmentsState state;
|
||||
state.mSource = mSource;
|
||||
state.mSourceCondition = NS_OK;
|
||||
|
||||
uint32_t n;
|
||||
*sinkCondition =
|
||||
*aSinkCondition =
|
||||
mSink->WriteSegments(FillOutputBuffer, &state, mChunkSize, &n);
|
||||
*sourceCondition = state.mSourceCondition;
|
||||
*aSourceCondition = state.mSourceCondition;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
@ -557,35 +583,37 @@ public:
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_AsyncCopy(nsIInputStream *source,
|
||||
nsIOutputStream *sink,
|
||||
nsIEventTarget *target,
|
||||
nsAsyncCopyMode mode,
|
||||
uint32_t chunkSize,
|
||||
nsAsyncCopyCallbackFun callback,
|
||||
void *closure,
|
||||
bool closeSource,
|
||||
bool closeSink,
|
||||
nsISupports **aCopierCtx,
|
||||
nsAsyncCopyProgressFun progressCallback)
|
||||
NS_AsyncCopy(nsIInputStream* aSource,
|
||||
nsIOutputStream* aSink,
|
||||
nsIEventTarget* aTarget,
|
||||
nsAsyncCopyMode aMode,
|
||||
uint32_t aChunkSize,
|
||||
nsAsyncCopyCallbackFun aCallback,
|
||||
void* aClosure,
|
||||
bool aCloseSource,
|
||||
bool aCloseSink,
|
||||
nsISupports** aCopierCtx,
|
||||
nsAsyncCopyProgressFun aProgressCallback)
|
||||
{
|
||||
NS_ASSERTION(target, "non-null target required");
|
||||
NS_ASSERTION(aTarget, "non-null target required");
|
||||
|
||||
nsresult rv;
|
||||
nsAStreamCopier *copier;
|
||||
nsAStreamCopier* copier;
|
||||
|
||||
if (mode == NS_ASYNCCOPY_VIA_READSEGMENTS)
|
||||
if (aMode == NS_ASYNCCOPY_VIA_READSEGMENTS) {
|
||||
copier = new nsStreamCopierIB();
|
||||
else
|
||||
} else {
|
||||
copier = new nsStreamCopierOB();
|
||||
}
|
||||
|
||||
if (!copier)
|
||||
if (!copier) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Start() takes an owning ref to the copier...
|
||||
NS_ADDREF(copier);
|
||||
rv = copier->Start(source, sink, target, callback, closure, chunkSize,
|
||||
closeSource, closeSink, progressCallback);
|
||||
rv = copier->Start(aSource, aSink, aTarget, aCallback, aClosure, aChunkSize,
|
||||
aCloseSource, aCloseSink, aProgressCallback);
|
||||
|
||||
if (aCopierCtx) {
|
||||
*aCopierCtx = static_cast<nsISupports*>(
|
||||
|
@ -600,9 +628,9 @@ NS_AsyncCopy(nsIInputStream *source,
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_CancelAsyncCopy(nsISupports *aCopierCtx, nsresult aReason)
|
||||
NS_CancelAsyncCopy(nsISupports* aCopierCtx, nsresult aReason)
|
||||
{
|
||||
nsAStreamCopier *copier = static_cast<nsAStreamCopier *>(
|
||||
nsAStreamCopier* copier = static_cast<nsAStreamCopier*>(
|
||||
static_cast<nsIRunnable *>(aCopierCtx));
|
||||
return copier->Cancel(aReason);
|
||||
}
|
||||
|
@ -610,43 +638,50 @@ NS_CancelAsyncCopy(nsISupports *aCopierCtx, nsresult aReason)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_ConsumeStream(nsIInputStream *stream, uint32_t maxCount, nsACString &result)
|
||||
NS_ConsumeStream(nsIInputStream* aStream, uint32_t aMaxCount, nsACString& aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
result.Truncate();
|
||||
aResult.Truncate();
|
||||
|
||||
while (maxCount) {
|
||||
while (aMaxCount) {
|
||||
uint64_t avail64;
|
||||
rv = stream->Available(&avail64);
|
||||
rv = aStream->Available(&avail64);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_BASE_STREAM_CLOSED)
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (avail64 == 0)
|
||||
if (avail64 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t avail = (uint32_t)XPCOM_MIN<uint64_t>(avail64, maxCount);
|
||||
uint32_t avail = (uint32_t)XPCOM_MIN<uint64_t>(avail64, aMaxCount);
|
||||
|
||||
// resize result buffer
|
||||
uint32_t length = result.Length();
|
||||
if (avail > UINT32_MAX - length)
|
||||
// resize aResult buffer
|
||||
uint32_t length = aResult.Length();
|
||||
if (avail > UINT32_MAX - length) {
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
|
||||
result.SetLength(length + avail);
|
||||
if (result.Length() != (length + avail))
|
||||
aResult.SetLength(length + avail);
|
||||
if (aResult.Length() != (length + avail)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
char *buf = result.BeginWriting() + length;
|
||||
}
|
||||
char* buf = aResult.BeginWriting() + length;
|
||||
|
||||
uint32_t n;
|
||||
rv = stream->Read(buf, avail, &n);
|
||||
if (NS_FAILED(rv))
|
||||
rv = aStream->Read(buf, avail, &n);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
if (n != avail)
|
||||
result.SetLength(length + n);
|
||||
if (n == 0)
|
||||
}
|
||||
if (n != avail) {
|
||||
aResult.SetLength(length + n);
|
||||
}
|
||||
if (n == 0) {
|
||||
break;
|
||||
maxCount -= n;
|
||||
}
|
||||
aMaxCount -= n;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -655,149 +690,150 @@ NS_ConsumeStream(nsIInputStream *stream, uint32_t maxCount, nsACString &result)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
static NS_METHOD
|
||||
TestInputStream(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
TestInputStream(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
bool *result = static_cast<bool *>(closure);
|
||||
bool* result = static_cast<bool*>(aClosure);
|
||||
*result = true;
|
||||
return NS_ERROR_ABORT; // don't call me anymore
|
||||
}
|
||||
|
||||
bool
|
||||
NS_InputStreamIsBuffered(nsIInputStream *stream)
|
||||
NS_InputStreamIsBuffered(nsIInputStream* aStream)
|
||||
{
|
||||
nsCOMPtr<nsIBufferedInputStream> bufferedIn = do_QueryInterface(stream);
|
||||
nsCOMPtr<nsIBufferedInputStream> bufferedIn = do_QueryInterface(aStream);
|
||||
if (bufferedIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
uint32_t n;
|
||||
nsresult rv = stream->ReadSegments(TestInputStream,
|
||||
nsresult rv = aStream->ReadSegments(TestInputStream,
|
||||
&result, 1, &n);
|
||||
return result || NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
TestOutputStream(nsIOutputStream *outStr,
|
||||
void *closure,
|
||||
char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countRead)
|
||||
TestOutputStream(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead)
|
||||
{
|
||||
bool *result = static_cast<bool *>(closure);
|
||||
bool* result = static_cast<bool*>(aClosure);
|
||||
*result = true;
|
||||
return NS_ERROR_ABORT; // don't call me anymore
|
||||
}
|
||||
|
||||
bool
|
||||
NS_OutputStreamIsBuffered(nsIOutputStream *stream)
|
||||
NS_OutputStreamIsBuffered(nsIOutputStream* aStream)
|
||||
{
|
||||
nsCOMPtr<nsIBufferedOutputStream> bufferedOut = do_QueryInterface(stream);
|
||||
nsCOMPtr<nsIBufferedOutputStream> bufferedOut = do_QueryInterface(aStream);
|
||||
if (bufferedOut) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
uint32_t n;
|
||||
stream->WriteSegments(TestOutputStream, &result, 1, &n);
|
||||
aStream->WriteSegments(TestOutputStream, &result, 1, &n);
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_METHOD
|
||||
NS_CopySegmentToStream(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
NS_CopySegmentToStream(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
nsIOutputStream *outStr = static_cast<nsIOutputStream *>(closure);
|
||||
*countWritten = 0;
|
||||
while (count) {
|
||||
nsIOutputStream* outStr = static_cast<nsIOutputStream*>(aClosure);
|
||||
*aCountWritten = 0;
|
||||
while (aCount) {
|
||||
uint32_t n;
|
||||
nsresult rv = outStr->Write(buffer, count, &n);
|
||||
if (NS_FAILED(rv))
|
||||
nsresult rv = outStr->Write(aBuffer, aCount, &n);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
buffer += n;
|
||||
count -= n;
|
||||
*countWritten += n;
|
||||
}
|
||||
aBuffer += n;
|
||||
aCount -= n;
|
||||
*aCountWritten += n;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_CopySegmentToBuffer(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
NS_CopySegmentToBuffer(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
char *toBuf = static_cast<char *>(closure);
|
||||
memcpy(&toBuf[offset], buffer, count);
|
||||
*countWritten = count;
|
||||
char* toBuf = static_cast<char*>(aClosure);
|
||||
memcpy(&toBuf[aOffset], aBuffer, aCount);
|
||||
*aCountWritten = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_CopySegmentToBuffer(nsIOutputStream *outStr,
|
||||
void *closure,
|
||||
char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countRead)
|
||||
NS_CopySegmentToBuffer(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead)
|
||||
{
|
||||
const char* fromBuf = static_cast<const char*>(closure);
|
||||
memcpy(buffer, &fromBuf[offset], count);
|
||||
*countRead = count;
|
||||
const char* fromBuf = static_cast<const char*>(aClosure);
|
||||
memcpy(aBuffer, &fromBuf[aOffset], aCount);
|
||||
*aCountRead = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_DiscardSegment(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
NS_DiscardSegment(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
*countWritten = count;
|
||||
*aCountWritten = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_METHOD
|
||||
NS_WriteSegmentThunk(nsIInputStream *inStr,
|
||||
void *closure,
|
||||
const char *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t count,
|
||||
uint32_t *countWritten)
|
||||
NS_WriteSegmentThunk(nsIInputStream* aInStr,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountWritten)
|
||||
{
|
||||
nsWriteSegmentThunk *thunk = static_cast<nsWriteSegmentThunk *>(closure);
|
||||
return thunk->mFun(thunk->mStream, thunk->mClosure, buffer, offset, count,
|
||||
countWritten);
|
||||
nsWriteSegmentThunk* thunk = static_cast<nsWriteSegmentThunk*>(aClosure);
|
||||
return thunk->mFun(thunk->mStream, thunk->mClosure, aBuffer, aOffset, aCount,
|
||||
aCountWritten);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_FillArray(FallibleTArray<char>& aDest, nsIInputStream *aInput,
|
||||
uint32_t aKeep, uint32_t *aNewBytes)
|
||||
NS_FillArray(FallibleTArray<char>& aDest, nsIInputStream* aInput,
|
||||
uint32_t aKeep, uint32_t* aNewBytes)
|
||||
{
|
||||
MOZ_ASSERT(aInput, "null stream");
|
||||
MOZ_ASSERT(aKeep <= aDest.Length(), "illegal keep count");
|
||||
|
||||
char* aBuffer = aDest.Elements();
|
||||
int64_t keepOffset = int64_t(aDest.Length()) - aKeep;
|
||||
if (0 != aKeep && keepOffset > 0) {
|
||||
if (aKeep != 0 && keepOffset > 0) {
|
||||
memmove(aBuffer, aBuffer + keepOffset, aKeep);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ class nsIEventTarget;
|
|||
* aTarget parameter is non-null.
|
||||
*/
|
||||
extern already_AddRefed<nsIInputStreamCallback>
|
||||
NS_NewInputStreamReadyEvent(nsIInputStreamCallback *aNotify,
|
||||
nsIEventTarget *aTarget);
|
||||
NS_NewInputStreamReadyEvent(nsIInputStreamCallback* aNotify,
|
||||
nsIEventTarget* aTarget);
|
||||
|
||||
/**
|
||||
* A "one-shot" proxy of the OnOutputStreamReady callback. The resulting
|
||||
|
@ -42,8 +42,8 @@ NS_NewInputStreamReadyEvent(nsIInputStreamCallback *aNotify,
|
|||
* aTarget parameter is non-null.
|
||||
*/
|
||||
extern already_AddRefed<nsIOutputStreamCallback>
|
||||
NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback *aNotify,
|
||||
nsIEventTarget *aTarget);
|
||||
NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback* aNotify,
|
||||
nsIEventTarget* aTarget);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -56,13 +56,13 @@ enum nsAsyncCopyMode {
|
|||
* This function is called when a new chunk of data has been copied. The
|
||||
* reported count is the size of the current chunk.
|
||||
*/
|
||||
typedef void (* nsAsyncCopyProgressFun)(void *closure, uint32_t count);
|
||||
typedef void (* nsAsyncCopyProgressFun)(void* closure, uint32_t count);
|
||||
|
||||
/**
|
||||
* This function is called when the async copy process completes. The reported
|
||||
* status is NS_OK on success and some error code on failure.
|
||||
*/
|
||||
typedef void (* nsAsyncCopyCallbackFun)(void *closure, nsresult status);
|
||||
typedef void (* nsAsyncCopyCallbackFun)(void* closure, nsresult status);
|
||||
|
||||
/**
|
||||
* This function asynchronously copies data from the source to the sink. All
|
||||
|
@ -81,17 +81,17 @@ typedef void (* nsAsyncCopyCallbackFun)(void *closure, nsresult status);
|
|||
* Caller can obtain aCopierCtx to be able to cancel copying.
|
||||
*/
|
||||
extern nsresult
|
||||
NS_AsyncCopy(nsIInputStream *aSource,
|
||||
nsIOutputStream *aSink,
|
||||
nsIEventTarget *aTarget,
|
||||
nsAsyncCopyMode aMode = NS_ASYNCCOPY_VIA_READSEGMENTS,
|
||||
uint32_t aChunkSize = 4096,
|
||||
nsAsyncCopyCallbackFun aCallbackFun = nullptr,
|
||||
void *aCallbackClosure = nullptr,
|
||||
bool aCloseSource = true,
|
||||
bool aCloseSink = true,
|
||||
nsISupports **aCopierCtx = nullptr,
|
||||
nsAsyncCopyProgressFun aProgressCallbackFun = nullptr);
|
||||
NS_AsyncCopy(nsIInputStream* aSource,
|
||||
nsIOutputStream* aSink,
|
||||
nsIEventTarget* aTarget,
|
||||
nsAsyncCopyMode aMode = NS_ASYNCCOPY_VIA_READSEGMENTS,
|
||||
uint32_t aChunkSize = 4096,
|
||||
nsAsyncCopyCallbackFun aCallbackFun = nullptr,
|
||||
void* aCallbackClosure = nullptr,
|
||||
bool aCloseSource = true,
|
||||
bool aCloseSink = true,
|
||||
nsISupports** aCopierCtx = nullptr,
|
||||
nsAsyncCopyProgressFun aProgressCallbackFun = nullptr);
|
||||
|
||||
/**
|
||||
* This function cancels copying started by function NS_AsyncCopy.
|
||||
|
@ -103,7 +103,7 @@ NS_AsyncCopy(nsIInputStream *aSource,
|
|||
* It is an error to pass a success code.
|
||||
*/
|
||||
extern nsresult
|
||||
NS_CancelAsyncCopy(nsISupports *aCopierCtx, nsresult aReason);
|
||||
NS_CancelAsyncCopy(nsISupports* aCopierCtx, nsresult aReason);
|
||||
|
||||
/**
|
||||
* This function copies all of the available data from the stream (up to at
|
||||
|
@ -129,8 +129,8 @@ NS_CancelAsyncCopy(nsISupports *aCopierCtx, nsresult aReason);
|
|||
* contain non-ASCII values.
|
||||
*/
|
||||
extern nsresult
|
||||
NS_ConsumeStream(nsIInputStream *aSource, uint32_t aMaxCount,
|
||||
nsACString &aBuffer);
|
||||
NS_ConsumeStream(nsIInputStream* aSource, uint32_t aMaxCount,
|
||||
nsACString& aBuffer);
|
||||
|
||||
/**
|
||||
* This function tests whether or not the input stream is buffered. A buffered
|
||||
|
@ -151,7 +151,7 @@ NS_ConsumeStream(nsIInputStream *aSource, uint32_t aMaxCount,
|
|||
* The input stream to test.
|
||||
*/
|
||||
extern bool
|
||||
NS_InputStreamIsBuffered(nsIInputStream *aInputStream);
|
||||
NS_InputStreamIsBuffered(nsIInputStream* aInputStream);
|
||||
|
||||
/**
|
||||
* This function tests whether or not the output stream is buffered. A
|
||||
|
@ -173,7 +173,7 @@ NS_InputStreamIsBuffered(nsIInputStream *aInputStream);
|
|||
* The output stream to test.
|
||||
*/
|
||||
extern bool
|
||||
NS_OutputStreamIsBuffered(nsIOutputStream *aOutputStream);
|
||||
NS_OutputStreamIsBuffered(nsIOutputStream* aOutputStream);
|
||||
|
||||
/**
|
||||
* This function is intended to be passed to nsIInputStream::ReadSegments to
|
||||
|
@ -183,9 +183,9 @@ NS_OutputStreamIsBuffered(nsIOutputStream *aOutputStream);
|
|||
* @see nsIInputStream.idl for a description of this function's parameters.
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_CopySegmentToStream(nsIInputStream *aInputStream, void *aClosure,
|
||||
const char *aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t *aWriteCount);
|
||||
NS_CopySegmentToStream(nsIInputStream* aInputStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
/**
|
||||
* This function is intended to be passed to nsIInputStream::ReadSegments to
|
||||
|
@ -196,9 +196,9 @@ NS_CopySegmentToStream(nsIInputStream *aInputStream, void *aClosure,
|
|||
* @see nsIInputStream.idl for a description of this function's parameters.
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_CopySegmentToBuffer(nsIInputStream *aInputStream, void *aClosure,
|
||||
const char *aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t *aWriteCount);
|
||||
NS_CopySegmentToBuffer(nsIInputStream* aInputStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
/**
|
||||
* This function is intended to be passed to nsIOutputStream::WriteSegments to
|
||||
|
@ -208,9 +208,9 @@ NS_CopySegmentToBuffer(nsIInputStream *aInputStream, void *aClosure,
|
|||
* @see nsIOutputStream.idl for a description of this function's parameters.
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_CopySegmentToBuffer(nsIOutputStream *aOutputStream, void *aClosure,
|
||||
char *aToSegment, uint32_t aFromOffset,
|
||||
uint32_t aCount, uint32_t *aReadCount);
|
||||
NS_CopySegmentToBuffer(nsIOutputStream* aOutputStream, void* aClosure,
|
||||
char* aToSegment, uint32_t aFromOffset,
|
||||
uint32_t aCount, uint32_t* aReadCount);
|
||||
|
||||
/**
|
||||
* This function is intended to be passed to nsIInputStream::ReadSegments to
|
||||
|
@ -220,9 +220,9 @@ NS_CopySegmentToBuffer(nsIOutputStream *aOutputStream, void *aClosure,
|
|||
* @see nsIInputStream.idl for a description of this function's parameters.
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_DiscardSegment(nsIInputStream *aInputStream, void *aClosure,
|
||||
const char *aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t *aWriteCount);
|
||||
NS_DiscardSegment(nsIInputStream* aInputStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
/**
|
||||
* This function is intended to be passed to nsIInputStream::ReadSegments to
|
||||
|
@ -236,14 +236,15 @@ NS_DiscardSegment(nsIInputStream *aInputStream, void *aClosure,
|
|||
* inner stream's ReadSegments.
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_WriteSegmentThunk(nsIInputStream *aInputStream, void *aClosure,
|
||||
const char *aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t *aWriteCount);
|
||||
NS_WriteSegmentThunk(nsIInputStream* aInputStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
struct nsWriteSegmentThunk {
|
||||
nsIInputStream *mStream;
|
||||
nsWriteSegmentFun mFun;
|
||||
void *mClosure;
|
||||
struct nsWriteSegmentThunk
|
||||
{
|
||||
nsIInputStream* mStream;
|
||||
nsWriteSegmentFun mFun;
|
||||
void* mClosure;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -260,7 +261,7 @@ struct nsWriteSegmentThunk {
|
|||
* @return the result from aInput->Read(...)
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_FillArray(FallibleTArray<char> &aDest, nsIInputStream *aInput,
|
||||
uint32_t aKeep, uint32_t *aNewBytes);
|
||||
NS_FillArray(FallibleTArray<char>& aDest, nsIInputStream* aInput,
|
||||
uint32_t aKeep, uint32_t* aNewBytes);
|
||||
|
||||
#endif // !nsStreamUtils_h__
|
||||
|
|
|
@ -29,10 +29,11 @@ using namespace mozilla::ipc;
|
|||
// nsIStringInputStream implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsStringInputStream MOZ_FINAL : public nsIStringInputStream
|
||||
, public nsISeekableStream
|
||||
, public nsISupportsCString
|
||||
, public nsIIPCSerializableInputStream
|
||||
class nsStringInputStream MOZ_FINAL
|
||||
: public nsIStringInputStream
|
||||
, public nsISeekableStream
|
||||
, public nsISupportsCString
|
||||
, public nsIIPCSerializableInputStream
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -50,7 +51,8 @@ public:
|
|||
|
||||
private:
|
||||
~nsStringInputStream()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t Length() const
|
||||
{
|
||||
|
@ -100,35 +102,36 @@ NS_IMPL_CI_INTERFACE_GETTER(nsStringInputStream,
|
|||
/////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::GetType(uint16_t *type)
|
||||
nsStringInputStream::GetType(uint16_t* aType)
|
||||
{
|
||||
*type = TYPE_CSTRING;
|
||||
*aType = TYPE_CSTRING;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::GetData(nsACString &data)
|
||||
nsStringInputStream::GetData(nsACString& data)
|
||||
{
|
||||
// The stream doesn't have any data when it is closed. We could fake it
|
||||
// and return an empty string here, but it seems better to keep this return
|
||||
// value consistent with the behavior of the other 'getter' methods.
|
||||
if (NS_WARN_IF(Closed()))
|
||||
if (NS_WARN_IF(Closed())) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
data.Assign(mData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::SetData(const nsACString &data)
|
||||
nsStringInputStream::SetData(const nsACString& aData)
|
||||
{
|
||||
mData.Assign(data);
|
||||
mData.Assign(aData);
|
||||
mOffset = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::ToString(char **result)
|
||||
nsStringInputStream::ToString(char** aResult)
|
||||
{
|
||||
// NOTE: This method may result in data loss, so we do not implement it.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -139,35 +142,39 @@ nsStringInputStream::ToString(char **result)
|
|||
/////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::SetData(const char *data, int32_t dataLen)
|
||||
nsStringInputStream::SetData(const char* aData, int32_t aDataLen)
|
||||
{
|
||||
if (NS_WARN_IF(!data))
|
||||
if (NS_WARN_IF(!aData)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
mData.Assign(data, dataLen);
|
||||
}
|
||||
mData.Assign(aData, aDataLen);
|
||||
mOffset = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::AdoptData(char *data, int32_t dataLen)
|
||||
nsStringInputStream::AdoptData(char* aData, int32_t aDataLen)
|
||||
{
|
||||
if (NS_WARN_IF(!data))
|
||||
if (NS_WARN_IF(!aData)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
mData.Adopt(data, dataLen);
|
||||
}
|
||||
mData.Adopt(aData, aDataLen);
|
||||
mOffset = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::ShareData(const char *data, int32_t dataLen)
|
||||
nsStringInputStream::ShareData(const char* aData, int32_t aDataLen)
|
||||
{
|
||||
if (NS_WARN_IF(!data))
|
||||
if (NS_WARN_IF(!aData)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (dataLen < 0)
|
||||
dataLen = strlen(data);
|
||||
if (aDataLen < 0) {
|
||||
aDataLen = strlen(aData);
|
||||
}
|
||||
|
||||
mData.Rebind(data, dataLen);
|
||||
mData.Rebind(aData, aDataLen);
|
||||
mOffset = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -184,48 +191,51 @@ nsStringInputStream::Close()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::Available(uint64_t *aLength)
|
||||
nsStringInputStream::Available(uint64_t* aLength)
|
||||
{
|
||||
NS_ASSERTION(aLength, "null ptr");
|
||||
|
||||
if (Closed())
|
||||
if (Closed()) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
*aLength = LengthRemaining();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::Read(char* aBuf, uint32_t aCount, uint32_t *aReadCount)
|
||||
nsStringInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount)
|
||||
{
|
||||
NS_ASSERTION(aBuf, "null ptr");
|
||||
return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::ReadSegments(nsWriteSegmentFun writer, void *closure,
|
||||
uint32_t aCount, uint32_t *result)
|
||||
nsStringInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
||||
uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
NS_ASSERTION(result, "null ptr");
|
||||
NS_ASSERTION(aResult, "null ptr");
|
||||
NS_ASSERTION(Length() >= mOffset, "bad stream state");
|
||||
|
||||
if (Closed())
|
||||
if (Closed()) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
// We may be at end-of-file
|
||||
uint32_t maxCount = LengthRemaining();
|
||||
if (maxCount == 0) {
|
||||
*result = 0;
|
||||
*aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aCount > maxCount)
|
||||
if (aCount > maxCount) {
|
||||
aCount = maxCount;
|
||||
nsresult rv = writer(this, closure, mData.BeginReading() + mOffset, 0, aCount, result);
|
||||
}
|
||||
nsresult rv = aWriter(this, aClosure, mData.BeginReading() + mOffset, 0, aCount, aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ASSERTION(*result <= aCount,
|
||||
NS_ASSERTION(*aResult <= aCount,
|
||||
"writer should not write more than we asked it to write");
|
||||
mOffset += *result;
|
||||
mOffset += *aResult;
|
||||
}
|
||||
|
||||
// errors returned from the writer end here!
|
||||
|
@ -233,7 +243,7 @@ nsStringInputStream::ReadSegments(nsWriteSegmentFun writer, void *closure,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::IsNonBlocking(bool *aNonBlocking)
|
||||
nsStringInputStream::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
*aNonBlocking = true;
|
||||
return NS_OK;
|
||||
|
@ -244,15 +254,16 @@ nsStringInputStream::IsNonBlocking(bool *aNonBlocking)
|
|||
/////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::Seek(int32_t whence, int64_t offset)
|
||||
nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
{
|
||||
if (Closed())
|
||||
if (Closed()) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
// Compute new stream position. The given offset may be a negative value.
|
||||
|
||||
int64_t newPos = offset;
|
||||
switch (whence) {
|
||||
int64_t newPos = aOffset;
|
||||
switch (aWhence) {
|
||||
case NS_SEEK_SET:
|
||||
break;
|
||||
case NS_SEEK_CUR:
|
||||
|
@ -262,32 +273,35 @@ nsStringInputStream::Seek(int32_t whence, int64_t offset)
|
|||
newPos += Length();
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("invalid whence");
|
||||
NS_ERROR("invalid aWhence");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(newPos < 0) || NS_WARN_IF(newPos > Length()))
|
||||
if (NS_WARN_IF(newPos < 0) || NS_WARN_IF(newPos > Length())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mOffset = (uint32_t)newPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::Tell(int64_t* outWhere)
|
||||
nsStringInputStream::Tell(int64_t* aOutWhere)
|
||||
{
|
||||
if (Closed())
|
||||
if (Closed()) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
*outWhere = mOffset;
|
||||
*aOutWhere = mOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStringInputStream::SetEOF()
|
||||
{
|
||||
if (Closed())
|
||||
if (Closed()) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
mOffset = Length();
|
||||
return NS_OK;
|
||||
|
@ -330,8 +344,9 @@ NS_NewByteInputStream(nsIInputStream** aStreamResult,
|
|||
NS_PRECONDITION(aStreamResult, "null out ptr");
|
||||
|
||||
nsStringInputStream* stream = new nsStringInputStream();
|
||||
if (! stream)
|
||||
if (! stream) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(stream);
|
||||
|
||||
|
@ -375,8 +390,9 @@ NS_NewCStringInputStream(nsIInputStream** aStreamResult,
|
|||
NS_PRECONDITION(aStreamResult, "null out ptr");
|
||||
|
||||
nsStringInputStream* stream = new nsStringInputStream();
|
||||
if (! stream)
|
||||
if (! stream) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(stream);
|
||||
|
||||
|
@ -388,19 +404,21 @@ NS_NewCStringInputStream(nsIInputStream** aStreamResult,
|
|||
|
||||
// factory method for constructing a nsStringInputStream object
|
||||
nsresult
|
||||
nsStringInputStreamConstructor(nsISupports *outer, REFNSIID iid, void **result)
|
||||
nsStringInputStreamConstructor(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
*result = nullptr;
|
||||
*aResult = nullptr;
|
||||
|
||||
if (NS_WARN_IF(outer))
|
||||
if (NS_WARN_IF(aOuter)) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
nsStringInputStream *inst = new nsStringInputStream();
|
||||
if (!inst)
|
||||
nsStringInputStream* inst = new nsStringInputStream();
|
||||
if (!inst) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(inst);
|
||||
nsresult rv = inst->QueryInterface(iid, result);
|
||||
nsresult rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
#define STRING_BUFFER_SIZE 8192
|
||||
|
||||
class StringUnicharInputStream MOZ_FINAL : public nsIUnicharInputStream {
|
||||
class StringUnicharInputStream MOZ_FINAL : public nsIUnicharInputStream
|
||||
{
|
||||
public:
|
||||
StringUnicharInputStream(const nsAString& aString) :
|
||||
mString(aString), mPos(0), mLen(aString.Length()) { }
|
||||
|
@ -41,7 +42,7 @@ private:
|
|||
NS_IMETHODIMP
|
||||
StringUnicharInputStream::Read(char16_t* aBuf,
|
||||
uint32_t aCount,
|
||||
uint32_t *aReadCount)
|
||||
uint32_t* aReadCount)
|
||||
{
|
||||
if (mPos >= mLen) {
|
||||
*aReadCount = 0;
|
||||
|
@ -63,7 +64,7 @@ StringUnicharInputStream::Read(char16_t* aBuf,
|
|||
NS_IMETHODIMP
|
||||
StringUnicharInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter,
|
||||
void* aClosure,
|
||||
uint32_t aCount, uint32_t *aReadCount)
|
||||
uint32_t aCount, uint32_t* aReadCount)
|
||||
{
|
||||
uint32_t bytesWritten;
|
||||
uint32_t totalBytesWritten = 0;
|
||||
|
@ -111,7 +112,8 @@ StringUnicharInputStream::ReadString(uint32_t aCount, nsAString& aString,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult StringUnicharInputStream::Close()
|
||||
nsresult
|
||||
StringUnicharInputStream::Close()
|
||||
{
|
||||
mPos = mLen;
|
||||
return NS_OK;
|
||||
|
@ -121,7 +123,8 @@ NS_IMPL_ISUPPORTS(StringUnicharInputStream, nsIUnicharInputStream)
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class UTF8InputStream MOZ_FINAL : public nsIUnicharInputStream {
|
||||
class UTF8InputStream MOZ_FINAL : public nsIUnicharInputStream
|
||||
{
|
||||
public:
|
||||
UTF8InputStream();
|
||||
nsresult Init(nsIInputStream* aStream);
|
||||
|
@ -133,9 +136,11 @@ private:
|
|||
~UTF8InputStream();
|
||||
|
||||
protected:
|
||||
int32_t Fill(nsresult * aErrorCode);
|
||||
int32_t Fill(nsresult* aErrorCode);
|
||||
|
||||
static void CountValidUTF8Bytes(const char *aBuf, uint32_t aMaxBytes, uint32_t& aValidUTF8bytes, uint32_t& aValidUTF16CodeUnits);
|
||||
static void CountValidUTF8Bytes(const char* aBuf, uint32_t aMaxBytes,
|
||||
uint32_t& aValidUTF8bytes,
|
||||
uint32_t& aValidUTF16CodeUnits);
|
||||
|
||||
nsCOMPtr<nsIInputStream> mInput;
|
||||
FallibleTArray<char> mByteData;
|
||||
|
@ -165,14 +170,15 @@ UTF8InputStream::Init(nsIInputStream* aStream)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(UTF8InputStream,nsIUnicharInputStream)
|
||||
NS_IMPL_ISUPPORTS(UTF8InputStream, nsIUnicharInputStream)
|
||||
|
||||
UTF8InputStream::~UTF8InputStream()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
nsresult UTF8InputStream::Close()
|
||||
nsresult
|
||||
UTF8InputStream::Close()
|
||||
{
|
||||
mInput = nullptr;
|
||||
mByteData.Clear();
|
||||
|
@ -180,9 +186,8 @@ nsresult UTF8InputStream::Close()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult UTF8InputStream::Read(char16_t* aBuf,
|
||||
uint32_t aCount,
|
||||
uint32_t *aReadCount)
|
||||
nsresult
|
||||
UTF8InputStream::Read(char16_t* aBuf, uint32_t aCount, uint32_t* aReadCount)
|
||||
{
|
||||
NS_ASSERTION(mUnicharDataLength >= mUnicharDataOffset, "unsigned madness");
|
||||
uint32_t readCount = mUnicharDataLength - mUnicharDataOffset;
|
||||
|
@ -209,7 +214,7 @@ nsresult UTF8InputStream::Read(char16_t* aBuf,
|
|||
NS_IMETHODIMP
|
||||
UTF8InputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter,
|
||||
void* aClosure,
|
||||
uint32_t aCount, uint32_t *aReadCount)
|
||||
uint32_t aCount, uint32_t* aReadCount)
|
||||
{
|
||||
NS_ASSERTION(mUnicharDataLength >= mUnicharDataOffset, "unsigned madness");
|
||||
uint32_t bytesToWrite = mUnicharDataLength - mUnicharDataOffset;
|
||||
|
@ -224,8 +229,9 @@ UTF8InputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter,
|
|||
bytesToWrite = bytesRead;
|
||||
}
|
||||
|
||||
if (bytesToWrite > aCount)
|
||||
if (bytesToWrite > aCount) {
|
||||
bytesToWrite = aCount;
|
||||
}
|
||||
|
||||
uint32_t bytesWritten;
|
||||
uint32_t totalBytesWritten = 0;
|
||||
|
@ -277,9 +283,10 @@ UTF8InputStream::ReadString(uint32_t aCount, nsAString& aString,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t UTF8InputStream::Fill(nsresult * aErrorCode)
|
||||
int32_t
|
||||
UTF8InputStream::Fill(nsresult* aErrorCode)
|
||||
{
|
||||
if (nullptr == mInput) {
|
||||
if (!mInput) {
|
||||
// We already closed the stream!
|
||||
*aErrorCode = NS_BASE_STREAM_CLOSED;
|
||||
return -1;
|
||||
|
@ -302,14 +309,16 @@ int32_t UTF8InputStream::Fill(nsresult * aErrorCode)
|
|||
|
||||
// Now convert as much of the byte buffer to unicode as possible
|
||||
uint32_t srcLen, dstLen;
|
||||
CountValidUTF8Bytes(mByteData.Elements(),remainder + nb, srcLen, dstLen);
|
||||
CountValidUTF8Bytes(mByteData.Elements(), remainder + nb, srcLen, dstLen);
|
||||
|
||||
// the number of UCS2 characters should always be <= the number of
|
||||
// UTF8 chars
|
||||
NS_ASSERTION( (remainder+nb >= srcLen), "cannot be longer than out buffer");
|
||||
NS_ASSERTION(remainder + nb >= srcLen, "cannot be longer than out buffer");
|
||||
NS_ASSERTION(dstLen <= mUnicharData.Capacity(),
|
||||
"Ouch. I would overflow my buffer if I wasn't so careful.");
|
||||
if (dstLen > mUnicharData.Capacity()) return 0;
|
||||
if (dstLen > mUnicharData.Capacity()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConvertUTF8toUTF16 converter(mUnicharData.Elements());
|
||||
|
||||
|
@ -330,32 +339,33 @@ int32_t UTF8InputStream::Fill(nsresult * aErrorCode)
|
|||
}
|
||||
|
||||
void
|
||||
UTF8InputStream::CountValidUTF8Bytes(const char* aBuffer, uint32_t aMaxBytes, uint32_t& aValidUTF8bytes, uint32_t& aValidUTF16CodeUnits)
|
||||
UTF8InputStream::CountValidUTF8Bytes(const char* aBuffer, uint32_t aMaxBytes,
|
||||
uint32_t& aValidUTF8bytes,
|
||||
uint32_t& aValidUTF16CodeUnits)
|
||||
{
|
||||
const char *c = aBuffer;
|
||||
const char *end = aBuffer + aMaxBytes;
|
||||
const char *lastchar = c; // pre-initialize in case of 0-length buffer
|
||||
const char* c = aBuffer;
|
||||
const char* end = aBuffer + aMaxBytes;
|
||||
const char* lastchar = c; // pre-initialize in case of 0-length buffer
|
||||
uint32_t utf16length = 0;
|
||||
while (c < end && *c) {
|
||||
lastchar = c;
|
||||
utf16length++;
|
||||
|
||||
if (UTF8traits::isASCII(*c))
|
||||
if (UTF8traits::isASCII(*c)) {
|
||||
c++;
|
||||
else if (UTF8traits::is2byte(*c))
|
||||
} else if (UTF8traits::is2byte(*c)) {
|
||||
c += 2;
|
||||
else if (UTF8traits::is3byte(*c))
|
||||
} else if (UTF8traits::is3byte(*c)) {
|
||||
c += 3;
|
||||
else if (UTF8traits::is4byte(*c)) {
|
||||
} else if (UTF8traits::is4byte(*c)) {
|
||||
c += 4;
|
||||
utf16length++; // add 1 more because this will be converted to a
|
||||
// surrogate pair.
|
||||
}
|
||||
else if (UTF8traits::is5byte(*c))
|
||||
// surrogate pair.
|
||||
} else if (UTF8traits::is5byte(*c)) {
|
||||
c += 5;
|
||||
else if (UTF8traits::is6byte(*c))
|
||||
} else if (UTF8traits::is6byte(*c)) {
|
||||
c += 6;
|
||||
else {
|
||||
} else {
|
||||
NS_WARNING("Unrecognized UTF8 string in UTF8InputStream::CountValidUTF8Bytes()");
|
||||
break; // Otherwise we go into an infinite loop. But what happens now?
|
||||
}
|
||||
|
@ -373,12 +383,20 @@ NS_IMPL_QUERY_INTERFACE(nsSimpleUnicharStreamFactory,
|
|||
nsIFactory,
|
||||
nsISimpleUnicharStreamFactory)
|
||||
|
||||
NS_IMETHODIMP_(MozExternalRefCountType) nsSimpleUnicharStreamFactory::AddRef() { return 2; }
|
||||
NS_IMETHODIMP_(MozExternalRefCountType) nsSimpleUnicharStreamFactory::Release() { return 1; }
|
||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
||||
nsSimpleUnicharStreamFactory::AddRef()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
||||
nsSimpleUnicharStreamFactory::Release()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleUnicharStreamFactory::CreateInstance(nsISupports* aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
void** aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -391,7 +409,7 @@ nsSimpleUnicharStreamFactory::LockFactory(bool aLock)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleUnicharStreamFactory::CreateInstanceFromString(const nsAString& aString,
|
||||
nsIUnicharInputStream* *aResult)
|
||||
nsIUnicharInputStream** aResult)
|
||||
{
|
||||
StringUnicharInputStream* it = new StringUnicharInputStream(aString);
|
||||
if (!it) {
|
||||
|
@ -404,18 +422,20 @@ nsSimpleUnicharStreamFactory::CreateInstanceFromString(const nsAString& aString,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleUnicharStreamFactory::CreateInstanceFromUTF8Stream(nsIInputStream* aStreamToWrap,
|
||||
nsIUnicharInputStream* *aResult)
|
||||
nsIUnicharInputStream** aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
|
||||
// Create converter input stream
|
||||
nsRefPtr<UTF8InputStream> it = new UTF8InputStream();
|
||||
if (!it)
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = it->Init(aStreamToWrap);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = it);
|
||||
return NS_OK;
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
#define NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID \
|
||||
{ 0x428dca6f, 0x1a0f, 0x4cda, { 0xb5, 0x16, 0xd, 0x52, 0x44, 0x74, 0x5a, 0x6a } }
|
||||
|
||||
class nsSimpleUnicharStreamFactory :
|
||||
public nsIFactory,
|
||||
private nsISimpleUnicharStreamFactory
|
||||
class nsSimpleUnicharStreamFactory
|
||||
: public nsIFactory
|
||||
, private nsISimpleUnicharStreamFactory
|
||||
{
|
||||
public:
|
||||
nsSimpleUnicharStreamFactory() {}
|
||||
nsSimpleUnicharStreamFactory()
|
||||
{
|
||||
}
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIFACTORY
|
||||
NS_DECL_NSISIMPLEUNICHARSTREAMFACTORY
|
||||
|
|
|
@ -27,57 +27,61 @@ typedef int static_assert_character_code_arrangement['a' > 'A' ? 1 : -1];
|
|||
|
||||
template<class T>
|
||||
static int
|
||||
alpha(T c)
|
||||
alpha(T aChar)
|
||||
{
|
||||
return ('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z');
|
||||
return ('a' <= aChar && aChar <= 'z') ||
|
||||
('A' <= aChar && aChar <= 'Z');
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
alphanumeric(T c)
|
||||
alphanumeric(T aChar)
|
||||
{
|
||||
return ('0' <= c && c <= '9') || ::alpha(c);
|
||||
return ('0' <= aChar && aChar <= '9') || ::alpha(aChar);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
lower(T c)
|
||||
lower(T aChar)
|
||||
{
|
||||
return ('A' <= c && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
return ('A' <= aChar && aChar <= 'Z') ? aChar + ('a' - 'A') : aChar;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
upper(T c)
|
||||
upper(T aChar)
|
||||
{
|
||||
return ('a' <= c && c <= 'z') ? c - ('a' - 'A') : c;
|
||||
return ('a' <= aChar && aChar <= 'z') ? aChar - ('a' - 'A') : aChar;
|
||||
}
|
||||
|
||||
/* ----------------------------- _valid_subexp ---------------------------- */
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
_valid_subexp(const T *expr, T stop1, T stop2)
|
||||
_valid_subexp(const T* aExpr, T aStop1, T aStop2)
|
||||
{
|
||||
int x;
|
||||
int nsc = 0; /* Number of special characters */
|
||||
int np; /* Number of pipe characters in union */
|
||||
int tld = 0; /* Number of tilde characters */
|
||||
|
||||
for (x = 0; expr[x] && (expr[x] != stop1) && (expr[x] != stop2); ++x) {
|
||||
switch(expr[x]) {
|
||||
for (x = 0; aExpr[x] && (aExpr[x] != aStop1) && (aExpr[x] != aStop2); ++x) {
|
||||
switch (aExpr[x]) {
|
||||
case '~':
|
||||
if(tld) /* at most one exclusion */
|
||||
if (tld) { /* at most one exclusion */
|
||||
return INVALID_SXP;
|
||||
if (stop1) /* no exclusions within unions */
|
||||
}
|
||||
if (aStop1) { /* no exclusions within unions */
|
||||
return INVALID_SXP;
|
||||
if (!expr[x+1]) /* exclusion cannot be last character */
|
||||
}
|
||||
if (!aExpr[x + 1]) { /* exclusion cannot be last character */
|
||||
return INVALID_SXP;
|
||||
if (!x) /* exclusion cannot be first character */
|
||||
}
|
||||
if (!x) { /* exclusion cannot be first character */
|
||||
return INVALID_SXP;
|
||||
}
|
||||
++tld;
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
case '*':
|
||||
case '?':
|
||||
case '$':
|
||||
|
@ -85,31 +89,38 @@ _valid_subexp(const T *expr, T stop1, T stop2)
|
|||
break;
|
||||
case '[':
|
||||
++nsc;
|
||||
if((!expr[++x]) || (expr[x] == ']'))
|
||||
if ((!aExpr[++x]) || (aExpr[x] == ']')) {
|
||||
return INVALID_SXP;
|
||||
for(; expr[x] && (expr[x] != ']'); ++x) {
|
||||
if(expr[x] == '\\' && !expr[++x])
|
||||
return INVALID_SXP;
|
||||
}
|
||||
if(!expr[x])
|
||||
for (; aExpr[x] && (aExpr[x] != ']'); ++x) {
|
||||
if (aExpr[x] == '\\' && !aExpr[++x]) {
|
||||
return INVALID_SXP;
|
||||
}
|
||||
}
|
||||
if (!aExpr[x]) {
|
||||
return INVALID_SXP;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
++nsc;
|
||||
if (stop1) /* no nested unions */
|
||||
if (aStop1) { /* no nested unions */
|
||||
return INVALID_SXP;
|
||||
}
|
||||
np = -1;
|
||||
do {
|
||||
int t = ::_valid_subexp(&expr[++x], T(')'), T('|'));
|
||||
if(t == 0 || t == INVALID_SXP)
|
||||
int t = ::_valid_subexp(&aExpr[++x], T(')'), T('|'));
|
||||
if (t == 0 || t == INVALID_SXP) {
|
||||
return INVALID_SXP;
|
||||
x+=t;
|
||||
if(!expr[x])
|
||||
}
|
||||
x += t;
|
||||
if (!aExpr[x]) {
|
||||
return INVALID_SXP;
|
||||
}
|
||||
++np;
|
||||
} while (expr[x] == '|' );
|
||||
if(np < 1) /* must be at least one pipe */
|
||||
} while (aExpr[x] == '|');
|
||||
if (np < 1) { /* must be at least one pipe */
|
||||
return INVALID_SXP;
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
|
@ -117,37 +128,39 @@ _valid_subexp(const T *expr, T stop1, T stop2)
|
|||
return INVALID_SXP;
|
||||
case '\\':
|
||||
++nsc;
|
||||
if(!expr[++x])
|
||||
if (!aExpr[++x]) {
|
||||
return INVALID_SXP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((!stop1) && (!nsc)) /* must be at least one special character */
|
||||
if (!aStop1 && !nsc) { /* must be at least one special character */
|
||||
return NON_SXP;
|
||||
return ((expr[x] == stop1 || expr[x] == stop2) ? x : INVALID_SXP);
|
||||
}
|
||||
return ((aExpr[x] == aStop1 || aExpr[x] == aStop2) ? x : INVALID_SXP);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
int
|
||||
NS_WildCardValid_(const T *expr)
|
||||
NS_WildCardValid_(const T* aExpr)
|
||||
{
|
||||
int x = ::_valid_subexp(expr, T('\0'), T('\0'));
|
||||
int x = ::_valid_subexp(aExpr, T('\0'), T('\0'));
|
||||
return (x < 0 ? x : VALID_SXP);
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardValid(const char *expr)
|
||||
NS_WildCardValid(const char* aExpr)
|
||||
{
|
||||
return NS_WildCardValid_(expr);
|
||||
return NS_WildCardValid_(aExpr);
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardValid(const char16_t *expr)
|
||||
NS_WildCardValid(const char16_t* aExpr)
|
||||
{
|
||||
return NS_WildCardValid_(expr);
|
||||
return NS_WildCardValid_(aExpr);
|
||||
}
|
||||
|
||||
/* ----------------------------- _shexp_match ----------------------------- */
|
||||
|
@ -159,7 +172,8 @@ NS_WildCardValid(const char16_t *expr)
|
|||
|
||||
template<class T>
|
||||
static int
|
||||
_shexp_match(const T *str, const T *expr, bool case_insensitive, unsigned int level);
|
||||
_shexp_match(const T* aStr, const T* aExpr, bool aCaseInsensitive,
|
||||
unsigned int aLevel);
|
||||
|
||||
/**
|
||||
* Count characters until we reach a NUL character or either of the
|
||||
|
@ -172,29 +186,31 @@ _shexp_match(const T *str, const T *expr, bool case_insensitive, unsigned int le
|
|||
*/
|
||||
template<class T>
|
||||
static int
|
||||
_scan_and_copy(const T *expr, T stop1, T stop2, T *dest)
|
||||
_scan_and_copy(const T* aExpr, T aStop1, T aStop2, T* aDest)
|
||||
{
|
||||
int sx; /* source index */
|
||||
T cc;
|
||||
|
||||
for (sx = 0; (cc = expr[sx]) && cc != stop1 && cc != stop2; sx++) {
|
||||
for (sx = 0; (cc = aExpr[sx]) && cc != aStop1 && cc != aStop2; ++sx) {
|
||||
if (cc == '\\') {
|
||||
if (!expr[++sx])
|
||||
return ABORTED; /* should be impossible */
|
||||
}
|
||||
else if (cc == '[') {
|
||||
while ((cc = expr[++sx]) && cc != ']') {
|
||||
if(cc == '\\' && !expr[++sx])
|
||||
return ABORTED;
|
||||
if (!aExpr[++sx]) {
|
||||
return ABORTED; /* should be impossible */
|
||||
}
|
||||
} else if (cc == '[') {
|
||||
while ((cc = aExpr[++sx]) && cc != ']') {
|
||||
if (cc == '\\' && !aExpr[++sx]) {
|
||||
return ABORTED;
|
||||
}
|
||||
}
|
||||
if (!cc) {
|
||||
return ABORTED; /* should be impossible */
|
||||
}
|
||||
if (!cc)
|
||||
return ABORTED; /* should be impossible */
|
||||
}
|
||||
}
|
||||
if (dest && sx) {
|
||||
if (aDest && sx) {
|
||||
/* Copy all but the closing delimiter. */
|
||||
memcpy(dest, expr, sx * sizeof(T));
|
||||
dest[sx] = 0;
|
||||
memcpy(aDest, aExpr, sx * sizeof(T));
|
||||
aDest[sx] = 0;
|
||||
}
|
||||
return cc ? sx : ABORTED; /* index of closing delimiter */
|
||||
}
|
||||
|
@ -209,84 +225,94 @@ _scan_and_copy(const T *expr, T stop1, T stop2, T *dest)
|
|||
*/
|
||||
template<class T>
|
||||
static int
|
||||
_handle_union(const T *str, const T *expr, bool case_insensitive,
|
||||
unsigned int level)
|
||||
_handle_union(const T* aStr, const T* aExpr, bool aCaseInsensitive,
|
||||
unsigned int aLevel)
|
||||
{
|
||||
int sx; /* source index */
|
||||
int cp; /* source index of closing parenthesis */
|
||||
int count;
|
||||
int ret = NOMATCH;
|
||||
T *e2;
|
||||
T* e2;
|
||||
|
||||
/* Find the closing parenthesis that ends this union in the expression */
|
||||
cp = ::_scan_and_copy(expr, T(')'), T('\0'), static_cast<T*>(nullptr));
|
||||
if (cp == ABORTED || cp < 4) /* must be at least "(a|b" before ')' */
|
||||
cp = ::_scan_and_copy(aExpr, T(')'), T('\0'), static_cast<T*>(nullptr));
|
||||
if (cp == ABORTED || cp < 4) { /* must be at least "(a|b" before ')' */
|
||||
return ABORTED;
|
||||
}
|
||||
++cp; /* now index of char after closing parenthesis */
|
||||
e2 = (T *) NS_Alloc((1 + nsCharTraits<T>::length(expr)) * sizeof(T));
|
||||
if (!e2)
|
||||
e2 = (T*)NS_Alloc((1 + nsCharTraits<T>::length(aExpr)) * sizeof(T));
|
||||
if (!e2) {
|
||||
return ABORTED;
|
||||
}
|
||||
for (sx = 1; ; ++sx) {
|
||||
/* Here, expr[sx] is one character past the preceding '(' or '|'. */
|
||||
/* Here, aExpr[sx] is one character past the preceding '(' or '|'. */
|
||||
/* Copy everything up to the next delimiter to e2 */
|
||||
count = ::_scan_and_copy(expr + sx, T(')'), T('|'), e2);
|
||||
count = ::_scan_and_copy(aExpr + sx, T(')'), T('|'), e2);
|
||||
if (count == ABORTED || !count) {
|
||||
ret = ABORTED;
|
||||
break;
|
||||
}
|
||||
sx += count;
|
||||
/* Append everything after closing parenthesis to e2. This is safe. */
|
||||
nsCharTraits<T>::copy(e2 + count, expr + cp, nsCharTraits<T>::length(expr + cp) + 1);
|
||||
ret = ::_shexp_match(str, e2, case_insensitive, level + 1);
|
||||
if (ret != NOMATCH || !expr[sx] || expr[sx] == ')')
|
||||
nsCharTraits<T>::copy(e2 + count, aExpr + cp,
|
||||
nsCharTraits<T>::length(aExpr + cp) + 1);
|
||||
ret = ::_shexp_match(aStr, e2, aCaseInsensitive, aLevel + 1);
|
||||
if (ret != NOMATCH || !aExpr[sx] || aExpr[sx] == ')') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_Free(e2);
|
||||
if (sx < 2)
|
||||
if (sx < 2) {
|
||||
ret = ABORTED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* returns 1 if val is in range from start..end, case insensitive. */
|
||||
static int
|
||||
_is_char_in_range(unsigned char start, unsigned char end, unsigned char val)
|
||||
_is_char_in_range(unsigned char aStart, unsigned char aEnd, unsigned char aVal)
|
||||
{
|
||||
char map[256];
|
||||
memset(map, 0, sizeof map);
|
||||
while (start <= end)
|
||||
map[lower(start++)] = 1;
|
||||
return map[lower(val)];
|
||||
memset(map, 0, sizeof(map));
|
||||
while (aStart <= aEnd) {
|
||||
map[lower(aStart++)] = 1;
|
||||
}
|
||||
return map[lower(aVal)];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
_shexp_match(const T *str, const T *expr, bool case_insensitive,
|
||||
unsigned int level)
|
||||
_shexp_match(const T* aStr, const T* aExpr, bool aCaseInsensitive,
|
||||
unsigned int aLevel)
|
||||
{
|
||||
int x; /* input string index */
|
||||
int y; /* expression index */
|
||||
int ret,neg;
|
||||
int ret, neg;
|
||||
|
||||
if (level > 20) /* Don't let the stack get too deep. */
|
||||
if (aLevel > 20) { /* Don't let the stack get too deep. */
|
||||
return ABORTED;
|
||||
for(x = 0, y = 0; expr[y]; ++y, ++x) {
|
||||
if((!str[x]) && (expr[y] != '$') && (expr[y] != '*')) {
|
||||
}
|
||||
for (x = 0, y = 0; aExpr[y]; ++y, ++x) {
|
||||
if (!aStr[x] && aExpr[y] != '$' && aExpr[y] != '*') {
|
||||
return NOMATCH;
|
||||
}
|
||||
switch(expr[y]) {
|
||||
switch (aExpr[y]) {
|
||||
case '$':
|
||||
if(str[x])
|
||||
if (aStr[x]) {
|
||||
return NOMATCH;
|
||||
}
|
||||
--x; /* we don't want loop to increment x */
|
||||
break;
|
||||
case '*':
|
||||
while(expr[++y] == '*'){}
|
||||
if(!expr[y])
|
||||
while (aExpr[++y] == '*') {
|
||||
}
|
||||
if (!aExpr[y]) {
|
||||
return MATCH;
|
||||
while(str[x]) {
|
||||
ret = ::_shexp_match(&str[x++], &expr[y], case_insensitive,
|
||||
level + 1);
|
||||
switch(ret) {
|
||||
}
|
||||
while (aStr[x]) {
|
||||
ret = ::_shexp_match(&aStr[x++], &aExpr[y], aCaseInsensitive,
|
||||
aLevel + 1);
|
||||
switch (ret) {
|
||||
case NOMATCH:
|
||||
continue;
|
||||
case ABORTED:
|
||||
|
@ -295,65 +321,73 @@ _shexp_match(const T *str, const T *expr, bool case_insensitive,
|
|||
return MATCH;
|
||||
}
|
||||
}
|
||||
if((expr[y] == '$') && (expr[y+1] == '\0') && (!str[x]))
|
||||
if (aExpr[y] == '$' && aExpr[y + 1] == '\0' && !aStr[x]) {
|
||||
return MATCH;
|
||||
else
|
||||
} else {
|
||||
return NOMATCH;
|
||||
}
|
||||
case '[': {
|
||||
T start, end = 0;
|
||||
int i;
|
||||
neg = ((expr[++y] == '^') && (expr[y+1] != ']'));
|
||||
if (neg)
|
||||
neg = (aExpr[++y] == '^' && aExpr[y + 1] != ']');
|
||||
if (neg) {
|
||||
++y;
|
||||
i = y;
|
||||
start = expr[i++];
|
||||
if (start == '\\')
|
||||
start = expr[i++];
|
||||
if (::alphanumeric(start) && expr[i++] == '-') {
|
||||
end = expr[i++];
|
||||
if (end == '\\')
|
||||
end = expr[i++];
|
||||
}
|
||||
if (::alphanumeric(end) && expr[i] == ']') {
|
||||
i = y;
|
||||
start = aExpr[i++];
|
||||
if (start == '\\') {
|
||||
start = aExpr[i++];
|
||||
}
|
||||
if (::alphanumeric(start) && aExpr[i++] == '-') {
|
||||
end = aExpr[i++];
|
||||
if (end == '\\') {
|
||||
end = aExpr[i++];
|
||||
}
|
||||
}
|
||||
if (::alphanumeric(end) && aExpr[i] == ']') {
|
||||
/* This is a range form: a-b */
|
||||
T val = str[x];
|
||||
T val = aStr[x];
|
||||
if (end < start) { /* swap them */
|
||||
T tmp = end;
|
||||
end = start;
|
||||
start = tmp;
|
||||
}
|
||||
if (case_insensitive && ::alpha(val)) {
|
||||
val = ::_is_char_in_range((unsigned char) start,
|
||||
(unsigned char) end,
|
||||
(unsigned char) val);
|
||||
if (neg == val)
|
||||
if (aCaseInsensitive && ::alpha(val)) {
|
||||
val = ::_is_char_in_range((unsigned char)start,
|
||||
(unsigned char)end,
|
||||
(unsigned char)val);
|
||||
if (neg == val) {
|
||||
return NOMATCH;
|
||||
}
|
||||
else if (neg != ((val < start) || (val > end))) {
|
||||
}
|
||||
} else if (neg != (val < start || val > end)) {
|
||||
return NOMATCH;
|
||||
}
|
||||
y = i;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Not range form */
|
||||
int matched = 0;
|
||||
for (; expr[y] != ']'; y++) {
|
||||
if (expr[y] == '\\')
|
||||
for (; aExpr[y] != ']'; ++y) {
|
||||
if (aExpr[y] == '\\') {
|
||||
++y;
|
||||
if(case_insensitive)
|
||||
matched |= (::upper(str[x]) == ::upper(expr[y]));
|
||||
else
|
||||
matched |= (str[x] == expr[y]);
|
||||
}
|
||||
if (aCaseInsensitive) {
|
||||
matched |= (::upper(aStr[x]) == ::upper(aExpr[y]));
|
||||
} else {
|
||||
matched |= (aStr[x] == aExpr[y]);
|
||||
}
|
||||
}
|
||||
if (neg == matched)
|
||||
if (neg == matched) {
|
||||
return NOMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
if (!expr[y+1])
|
||||
if (!aExpr[y + 1]) {
|
||||
return ABORTED;
|
||||
return ::_handle_union(&str[x], &expr[y], case_insensitive, level + 1);
|
||||
}
|
||||
return ::_handle_union(&aStr[x], &aExpr[y], aCaseInsensitive,
|
||||
aLevel + 1);
|
||||
case '?':
|
||||
break;
|
||||
case ')':
|
||||
|
@ -362,50 +396,59 @@ _shexp_match(const T *str, const T *expr, bool case_insensitive,
|
|||
return ABORTED;
|
||||
case '\\':
|
||||
++y;
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
default:
|
||||
if(case_insensitive) {
|
||||
if(::upper(str[x]) != ::upper(expr[y]))
|
||||
if (aCaseInsensitive) {
|
||||
if (::upper(aStr[x]) != ::upper(aExpr[y])) {
|
||||
return NOMATCH;
|
||||
}
|
||||
else {
|
||||
if(str[x] != expr[y])
|
||||
}
|
||||
} else {
|
||||
if (aStr[x] != aExpr[y]) {
|
||||
return NOMATCH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (str[x] ? NOMATCH : MATCH);
|
||||
return (aStr[x] ? NOMATCH : MATCH);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
static int
|
||||
ns_WildCardMatch(const T *str, const T *xp, bool case_insensitive)
|
||||
ns_WildCardMatch(const T* aStr, const T* aXp, bool aCaseInsensitive)
|
||||
{
|
||||
T *expr = nullptr;
|
||||
int x, ret = MATCH;
|
||||
T* expr = nullptr;
|
||||
int ret = MATCH;
|
||||
|
||||
if (!nsCharTraits<T>::find(xp, nsCharTraits<T>::length(xp), T('~')))
|
||||
return ::_shexp_match(str, xp, case_insensitive, 0);
|
||||
if (!nsCharTraits<T>::find(aXp, nsCharTraits<T>::length(aXp), T('~'))) {
|
||||
return ::_shexp_match(aStr, aXp, aCaseInsensitive, 0);
|
||||
}
|
||||
|
||||
expr = (T *) NS_Alloc((nsCharTraits<T>::length(xp) + 1) * sizeof(T));
|
||||
if(!expr)
|
||||
expr = (T*)NS_Alloc((nsCharTraits<T>::length(aXp) + 1) * sizeof(T));
|
||||
if (!expr) {
|
||||
return NOMATCH;
|
||||
memcpy(expr, xp, (nsCharTraits<T>::length(xp) + 1) * sizeof(T));
|
||||
}
|
||||
memcpy(expr, aXp, (nsCharTraits<T>::length(aXp) + 1) * sizeof(T));
|
||||
|
||||
x = ::_scan_and_copy(expr, T('~'), T('\0'), static_cast<T*>(nullptr));
|
||||
int x = ::_scan_and_copy(expr, T('~'), T('\0'), static_cast<T*>(nullptr));
|
||||
if (x != ABORTED && expr[x] == '~') {
|
||||
expr[x++] = '\0';
|
||||
ret = ::_shexp_match(str, &expr[x], case_insensitive, 0);
|
||||
ret = ::_shexp_match(aStr, &expr[x], aCaseInsensitive, 0);
|
||||
switch (ret) {
|
||||
case NOMATCH: ret = MATCH; break;
|
||||
case MATCH: ret = NOMATCH; break;
|
||||
default: break;
|
||||
case NOMATCH:
|
||||
ret = MATCH;
|
||||
break;
|
||||
case MATCH:
|
||||
ret = NOMATCH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == MATCH)
|
||||
ret = ::_shexp_match(str, expr, case_insensitive, 0);
|
||||
if (ret == MATCH) {
|
||||
ret = ::_shexp_match(aStr, expr, aCaseInsensitive, 0);
|
||||
}
|
||||
|
||||
NS_Free(expr);
|
||||
return ret;
|
||||
|
@ -413,27 +456,26 @@ ns_WildCardMatch(const T *str, const T *xp, bool case_insensitive)
|
|||
|
||||
template<class T>
|
||||
int
|
||||
NS_WildCardMatch_(const T *str, const T *expr, bool case_insensitive)
|
||||
NS_WildCardMatch_(const T* aStr, const T* aExpr, bool aCaseInsensitive)
|
||||
{
|
||||
int is_valid = NS_WildCardValid(expr);
|
||||
switch(is_valid) {
|
||||
int is_valid = NS_WildCardValid(aExpr);
|
||||
switch (is_valid) {
|
||||
case INVALID_SXP:
|
||||
return -1;
|
||||
default:
|
||||
return ::ns_WildCardMatch(str, expr, case_insensitive);
|
||||
return ::ns_WildCardMatch(aStr, aExpr, aCaseInsensitive);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardMatch(const char *str, const char *xp,
|
||||
bool case_insensitive)
|
||||
NS_WildCardMatch(const char* aStr, const char* aXp, bool aCaseInsensitive)
|
||||
{
|
||||
return NS_WildCardMatch_(str, xp, case_insensitive);
|
||||
return NS_WildCardMatch_(aStr, aXp, aCaseInsensitive);
|
||||
}
|
||||
|
||||
int
|
||||
NS_WildCardMatch(const char16_t *str, const char16_t *xp,
|
||||
bool case_insensitive)
|
||||
NS_WildCardMatch(const char16_t* aStr, const char16_t* aXp,
|
||||
bool aCaseInsensitive)
|
||||
{
|
||||
return NS_WildCardMatch_(str, xp, case_insensitive);
|
||||
return NS_WildCardMatch_(aStr, aXp, aCaseInsensitive);
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@
|
|||
#define INVALID_SXP -2
|
||||
#define VALID_SXP 1
|
||||
|
||||
int NS_WildCardValid(const char *expr);
|
||||
int NS_WildCardValid(const char* aExpr);
|
||||
|
||||
int NS_WildCardValid(const char16_t *expr);
|
||||
int NS_WildCardValid(const char16_t* aExpr);
|
||||
|
||||
/* return values for the search routines */
|
||||
#define MATCH 0
|
||||
|
@ -54,10 +54,10 @@ int NS_WildCardValid(const char16_t *expr);
|
|||
* Returns 0 on match and 1 on non-match.
|
||||
*/
|
||||
|
||||
int NS_WildCardMatch(const char *str, const char *expr,
|
||||
bool case_insensitive);
|
||||
int NS_WildCardMatch(const char* aStr, const char* aExpr,
|
||||
bool aCaseInsensitive);
|
||||
|
||||
int NS_WildCardMatch(const char16_t *str, const char16_t *expr,
|
||||
bool case_insensitive);
|
||||
int NS_WildCardMatch(const char16_t* aStr, const char16_t* aExpr,
|
||||
bool aCaseInsensitive);
|
||||
|
||||
#endif /* nsWildCard_h__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче