Tidied iocli exports, build macro tweaks.
Removed 4 overloads of CCommandBase::RunCommand[L] that are no longer used at all, and changed one more to not be exported as it's only used internally to iocli.dll.
fixed builds on platforms that don't support btrace or any form of tracing.
// file_utils.cpp
//
// Copyright (c) 2006 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Accenture - Initial contribution
//
#include <e32base.h>
#include <f32file.h>
#include "ioutils.h"
using namespace IoUtils;
//
// Constants.
//
_LIT(KSlash, "\\");
_LIT(KDoubleSlash, "\\\\");
_LIT(KDot, ".");
_LIT(KDoubleDot, "..");
__ASSERT_COMPILE(sizeof(TFileName2) == sizeof(TFileName) + 4);
//
// TFileName2.
//
EXPORT_C TFileName2::TFileName2()
{
new(this) TFileName2(EFile);
}
EXPORT_C TFileName2::TFileName2(TType aType)
{
new(this) TFileName2(KNullDesC, aType);
}
EXPORT_C TFileName2::TFileName2(const TDesC& aName)
: TBuf<256>(aName), iType(EFile)
{
new(this) TFileName2(aName, EFile);
}
EXPORT_C TFileName2::TFileName2(const TDesC& aName, TType aType)
: TBuf<256>(aName), iType(aType)
{
// Remove any double slashes that may be present.
TInt pos;
while ((pos = Find(KDoubleSlash)) >= 0)
{
Delete(pos, 1);
}
}
EXPORT_C TBool TFileName2::IsAbsolute() const
{
return ((Length() >= 3) && TChar((*this)[0]).IsAlpha() && ((*this)[1] == ':') && ((*this)[2] == '\\'));
}
EXPORT_C TBool TFileName2::IsDriveLetter() const
{
return (Length() == 2) && TChar((*this)[0]).IsAlpha() && ((*this)[1] == ':');
}
EXPORT_C TBool TFileName2::IsDriveRoot() const
{
return ((Length() == 3) && TChar((*this)[0]).IsAlpha() && ((*this)[1] == ':') && ((*this)[2] == '\\'));
}
EXPORT_C TBool TFileName2::IsWild() const
{
return TParsePtrC(*this).IsWild();
}
EXPORT_C TBool TFileName2::IsFile() const
{
TBool ret = (iType == EFile);
ASSERT((ret && !HasTrailingSlash()) || (!ret && HasTrailingSlash()));
return ret;
}
EXPORT_C TBool TFileName2::IsDir() const
{
TBool ret = (iType == EDirectory);
ASSERT((ret && HasTrailingSlash()) || (!ret && !HasTrailingSlash()));
return ret;
}
EXPORT_C TBool TFileName2::HasDriveLetter() const
{
return ((Length() >= 2) && TChar((*this)[0]).IsAlpha() && ((*this)[1] == ':'));
}
EXPORT_C TBool TFileName2::HasLeadingSlash() const
{
return ((Length() >= 1) && ((*this)[0] == '\\'));
}
EXPORT_C TBool TFileName2::HasTrailingSlash() const
{
return ((Length() >= 1) && ((*this)[Length() - 1] == '\\'));
}
EXPORT_C TPtrC TFileName2::Drive() const
{
return TParsePtrC(*this).Drive();
}
EXPORT_C TPtrC TFileName2::Path() const
{
return TParsePtrC(*this).Path();
}
EXPORT_C TPtrC TFileName2::DriveAndPath() const
{
return TParsePtrC(*this).DriveAndPath();
}
EXPORT_C TPtrC TFileName2::Name() const
{
return TParsePtrC(*this).Name();
}
EXPORT_C TPtrC TFileName2::Ext() const
{
return TParsePtrC(*this).Ext();
}
EXPORT_C TPtrC TFileName2::NameAndExt() const
{
return TParsePtrC(*this).NameAndExt();
}
EXPORT_C void TFileName2::SetL(const TFileName2& aName)
{
Zero();
AppendComponentL(aName);
}
EXPORT_C void TFileName2::SetTypeL(TType aType)
{
switch (aType)
{
case EFile:
{
if (HasTrailingSlash() && ((HasDriveLetter() && (Length() > 3)) || (!HasDriveLetter() && (Length() > 1))))
{
Delete(Length() - 1, 1);
}
iType = EFile;
break;
}
case EDirectory:
{
if (!HasTrailingSlash())
{
AppendComponentL(KNullDesC());
}
iType = EDirectory;
break;
}
default:
{
ASSERT(EFalse);
}
}
}
EXPORT_C void TFileName2::SetTypeL(RFs& aFs)
{
if (IsDirL(aFs))
{
SetTypeL(EDirectory);
}
else
{
SetTypeL(EFile);
}
}
EXPORT_C void TFileName2::SetDriveL(const TDesC& aDrive)
{
if (Drive().Length() > 0)
{
(*this)[0] = aDrive[0];
}
else
{
PrependL(aDrive);
}
}
EXPORT_C void TFileName2::SetPathL(const TDesC& aPath)
{
TFileName2 temp;
temp.SetDriveL(Drive());
temp.AppendComponentL(aPath);
temp.SetNameAndExtL(NameAndExt());
Copy(temp);
}
EXPORT_C void TFileName2::SetNameL(const TDesC& aName)
{
TPtrC namePtrC(Name());
if (namePtrC.Length() > 0)
{
CheckSpaceL(aName.Length() - namePtrC.Length());
TInt namePos = namePtrC.Ptr() - Ptr();
Delete(namePos, namePtrC.Length());
Insert(namePos, aName);
}
else
{
AppendComponentL(aName);
}
}
EXPORT_C void TFileName2::SetExtL(const TDesC& aExt)
{
TPtrC extPtrC(Ext());
if (extPtrC.Length() > 0)
{
CheckSpaceL(aExt.Length() + ((aExt[0] == '.') ? 0 : 1) - extPtrC.Length());
Delete(extPtrC.Ptr() - Ptr(), extPtrC.Length());
}
else
{
CheckSpaceL(aExt.Length() + ((aExt[0] == '.') ? 0 : 1));
}
if (aExt[0] != '.')
{
Append('.');
}
Append(aExt);
}
EXPORT_C void TFileName2::SetNameAndExtL(const TDesC& aNameAndExt)
{
TPtrC nameAndExtPtrC(NameAndExt());
if (nameAndExtPtrC.Length() > 0)
{
CheckSpaceL(aNameAndExt.Length() - nameAndExtPtrC.Length());
TInt nameAndExtPos = nameAndExtPtrC.Ptr() - Ptr();
Delete(nameAndExtPos, nameAndExtPtrC.Length());
Insert(nameAndExtPos, aNameAndExt);
}
else
{
AppendComponentL(aNameAndExt);
}
}
EXPORT_C void TFileName2::PrependL(const TFileName2& aName)
{
if (Length() == 0)
{
CheckSpaceL(aName.Length() + (((iType == EDirectory) && !HasTrailingSlash()) ? 1 : 0));
Append(aName);
}
else if (aName.HasTrailingSlash() && HasLeadingSlash())
{
CheckSpaceL(aName.Length() - 1 + (((iType == EDirectory) && !HasTrailingSlash()) ? 1 : 0));
Insert(0, aName.Mid(1));
}
else if (!aName.HasTrailingSlash() && !HasLeadingSlash())
{
CheckSpaceL(aName.Length() + 1 + (((iType == EDirectory) && !HasTrailingSlash()) ? 1 : 0));
Insert(0, KSlash);
Insert(0, aName);
}
else
{
CheckSpaceL(aName.Length() + (((iType == EDirectory) && !HasTrailingSlash()) ? 1 : 0));
Insert(0, aName);
}
if ((iType == EDirectory) && (!HasTrailingSlash()))
{
Append(KSlash);
}
}
EXPORT_C void TFileName2::AppendComponentL(const TFileName2& aName)
{
AppendComponentL(aName, iType);
}
EXPORT_C void TFileName2::AppendComponentL(const TDesC& aPathComponent, TFileName2::TType aType)
{
// This function doesn't use iType, therefore you can call it and get the same results regardless of whether the type has been set - you will only get a trailing slash if (a) aPathComponent ends in a slash, or (b) aType is EDirectory.
TPtrC pathWithoutLeadingSlash(aPathComponent);
if (aPathComponent.Length() && aPathComponent[0] == '\\') pathWithoutLeadingSlash.Set(aPathComponent.Mid(1));
TInt pathLen = pathWithoutLeadingSlash.Length();
const TDesC* middle = &KNullDesC;
if (Length() && !HasTrailingSlash()) middle = &KSlash;
const TDesC* end = &KNullDesC;
if (aType == EDirectory && pathLen && pathWithoutLeadingSlash[pathLen-1] != '\\') end = &KSlash;
CheckSpaceL(pathLen + middle->Length() + end->Length());
Append(*middle);
Append(pathWithoutLeadingSlash);
Append(*end);
}
EXPORT_C void TFileName2::AppendComponentL(const TEntry& aEntry)
{
AppendComponentL(aEntry.iName, aEntry.IsDir() ? EDirectory : EFile);
}
EXPORT_C void TFileName2::SetIsDirectoryL()
{
// This is the more complicated way to do it, the other would be: if (!HasTrailingSlash()) AppendL(KSlash);
// Or indeed, AppendComponentL(KNullDesC, EDirectory) since the type is irrelevant if the component is empty
AppendComponentL(KNullDesC, EFile);
}
void TFileName2::CheckSpaceL(TInt aLengthToAdd) const
{
if ((MaxLength() - Length()) < aLengthToAdd)
{
User::Leave(KErrTooBig);
}
}
EXPORT_C void TFileName2::SplitL(RArray<TFileName2>& aOutput)
{
TLex lex(*this);
while (!lex.Eos())
{
lex.Mark();
while (!lex.Eos() && (lex.Peek() != '\\'))
{
lex.Get();
}
User::LeaveIfError(aOutput.Append(TFileName2(lex.MarkedToken())));
if (!lex.Eos())
{
// Skip over the slash
lex.Get();
if (lex.Eos())
{
// ended with slash - insert empty path component
User::LeaveIfError(aOutput.Append(TFileName2()));
}
}
}
}
EXPORT_C void TFileName2::MakeAbsoluteL(const TFileName2& aAbsoluteTo)
{
ASSERT(aAbsoluteTo.IsAbsolute());
if (IsAbsolute())
{
return;
}
if (HasLeadingSlash())
{
// Just prepend drive letter.
PrependL(aAbsoluteTo.Left(2));
return;
}
PrependL(aAbsoluteTo);
RArray<TFileName2> splitName;
CleanupClosePushL(splitName);
SplitL(splitName);
TInt i = 0;
while (i < splitName.Count())
{
const TFileName2& piece = splitName[i];
if (piece == KDot)
{
splitName.Remove(i);
}
else if (piece == KDoubleDot)
{
if ((i == 0) || ((i == 1) && splitName[0].IsDriveLetter()))
{
User::Leave(KErrBadName);
}
splitName.Remove(i);
splitName.Remove(i - 1);
--i;
}
else if ((piece == KNullDesC) && (i != 0) && (i != splitName.Count()-1))
{
// Allow empty piece in first or last slot to support leading/trailing slashes.
splitName.Remove(i);
}
else
{
++i;
}
}
UnsplitL(splitName);
CleanupStack::PopAndDestroy(&splitName);
}
EXPORT_C void TFileName2::MakeAbsoluteL(RFs& aFs)
{
TFileName2 sessionPath;
User::LeaveIfError(aFs.SessionPath(sessionPath));
MakeAbsoluteL(sessionPath);
}
EXPORT_C void TFileName2::UnsplitL(const RArray<TFileName2>& aInput)
{
Zero();
const TInt count = aInput.Count();
for (TInt i = 0; i < count; ++i)
{
AppendComponentL(aInput[i]);
}
if ((count == 1) && (aInput[0].Match(_L("?:")) == 0))
{
Append(KSlash);
}
}
EXPORT_C TBool TFileName2::Exists(RFs& aFs) const
{
TInt err;
if (IsDriveRoot())
{
TInt driveNumber;
err = RFs::CharToDrive(Drive()[0], driveNumber);
if (err == KErrNone)
{
TDriveInfo driveInfo;
err = aFs.Drive(driveInfo, driveNumber);
}
}
else
{
TUint att;
err = aFs.Att(*this, att);
}
return (err == KErrNone);
}
EXPORT_C TBool TFileName2::IsReadOnlyL(RFs& aFs) const
{
TEntry entry;
User::LeaveIfError(aFs.Entry(*this, entry));
return entry.IsReadOnly();
}
EXPORT_C TBool TFileName2::IsHiddenL(RFs& aFs) const
{
TEntry entry;
User::LeaveIfError(aFs.Entry(*this, entry));
return entry.IsHidden();
}
EXPORT_C TBool TFileName2::IsSystemL(RFs& aFs) const
{
TEntry entry;
User::LeaveIfError(aFs.Entry(*this, entry));
return entry.IsSystem();
}
EXPORT_C TBool TFileName2::IsDirL(RFs& aFs) const
{
if (IsDriveRoot())
{
if (!Exists(aFs))
{
User::Leave(KErrNotFound);
}
return ETrue;
}
else
{
TEntry entry;
User::LeaveIfError(aFs.Entry(*this, entry));
return entry.IsDir();
}
}
EXPORT_C TBool TFileName2::IsArchiveL(RFs& aFs) const
{
TEntry entry;
User::LeaveIfError(aFs.Entry(*this, entry));
return entry.IsArchive();
}
EXPORT_C TInt TFileName2::FindFile(RFs& aFs)
{
TFindFile ff(aFs);
TInt err = ff.FindByDir(*this, KNullDesC);
if (err==KErrNone)
{
*this = ff.File();
}
return err;
}
EXPORT_C void TFileName2::FindFileL(RFs& aFs)
{
User::LeaveIfError(FindFile(aFs));
}