views:

525

answers:

4

Hi

I have a const char* that specifies the file that I want to delete. I want to use RF::Delete to delete a file which takes a TDesC16 as input argument. Does anyone know how to easily convert

RFs fs;
TUint err;

const char *pFileToDelete = "c:\\myfile.txt";

if ( fs.Connect () == KErrNone )
{
 err = fs.Delete(pFileToDelete); 
 fs.Close();
}

Many thanks,

A: 

Depends what the character encoding is of the string pFileToDelete. If you don't know, then you need to find out (or define it yourself).

Assuming that it's 7-bit ASCII, then

TPtr8 wrapper(pFileToDelete, User::StringLength(pFileToDelete));
{
    TFileName name;
    name.Copy(wrapper);
    error = fs.Delete(name);
}

Braces are there just because TFileName is quite a large class (512 bytes or so, IIRC), so you want to be slightly wary about putting one on the stack, and give it the smallest scope possible. You could heap-allocate instead.

If it's UTF-8, then there is more work to do, check out ConvertToUnicodeFromUTF8 in class CnvUtfConverter.

It's usually better to define your filename as a descriptor literal in the first place, if you can.

Steve Jessop
There's no need for the TFileName at all, you've already got the descriptor in 'wrapper'
Dynite
I was assuming a unicode build (or else why would the OP say that `RFs::Delete` takes a TDesC16?). So wrapper cannot be passed to Delete, because it's an 8-bit descriptor, not a TDesC.
Steve Jessop
A: 

Something along these lines:

_LIT(KMyFilename,"c:\\myfile.txt");
TPtrC filename(KMyFilename);

RFs fs;
TInt err =fs.Connect();
User::LeaveIfError(err);
err = fs.Delete(filename);
...

but check http://descriptors.blogspot.com

Dynite
Doesn't answer the question. What if the questioner isn't completely missing the point of descriptors, genuinely does need to convert a C-style string, and in fact can't just use a descriptor literal?
Steve Jessop
... which is not to say that it's a wrong answer for the question the OP *should* have asked. Maybe the filename can be a descriptor literal. It's just not a right answer for the question actually asked :-)
Steve Jessop
+2  A: 
RFs fs;
TUint err;
const char *pFileToDelete = "c:\\myfile.txt";
TPtrC8 filename8 = (const TText8*)pFileToDelete;
//ok, so we could use a TBuf or a TFileName, but we'd need to now 
//the size of the TBuf at compile time and 
//TFileNames should never be allocated on the stack due to their size. 
//Easier to use a HBufC.
HBufC* filename = HBufC::NewLC(filename8.Length());
//Copy will only do the right thing if the text in pFiletoDelete is 7-bit ascii
filename->Des().Copy(filename8);
if ( fs.Connect () == KErrNone ){        
    err = fs.Delete(*filename);
    fs.Close();
}
CleanupStack::PopAndDestroy(filename);

I haven't actually compiled this code so it may need som TLC.

Ola
"TFileNames should never be allocated on the stack". Symbian may say that, but they're wusses. I've done it before. No-one died, and giving my thread 16k of stack didn't even make an appreciable dent in the 32MB of RAM on the handsets I was targetting :-) +1 because you could be bothered to write the code for the HBufC, and I couldn't.
Steve Jessop
A single TFileName on the stack is no problem. The problem is that you have to guarantee that no call path in you program contains too many TFileNames or other large stack objects.
Ola