• Welcome to PlanetSquires Forums.
 

Outputting CWSTR to BOM-16 file

Started by Paul Squires, July 19, 2018, 01:20:14 AM

Previous topic - Next topic

Paul Squires

Hi Jose,

Maybe it's way too late at night and my brain is not working... how do you output a CWSTR string to a BOM-16 encoded file. I am creating the BOM-16 file vian binary and Put statements but it does not work.

Here is some code that better shows what I am trying to do:


#include once "Afx/CWStr.inc"
USING Afx

kill "cwstr_test.txt"

dim as long f = freefile
open "cwstr_test.txt" for binary as #f

' Output the BOM first
put #f, , chr(&HFF, &HFE)

dim as CWSTR wszText = "This is simple text that should be written to the BOM-16 unicode file."

' Trying to output the text buffer does not result in the string being correctly written to file.
put #f, , **wszText     ' <-- does not work correctly

' Writing out each string character to file using indexing does work correctly.
'for i as long = 0 to len(wszText)
'   put #f, , wszText[i]
'next

close #f


Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

Hi Paul,

Like all the other FreeBasic native procedures that work with files, Put does not work with WSTRINGs.

You can use:


put #f, , CAST(BYTE PTR, wszText.m_pBuffer)[0], wszText.m_BufferLen


Paul Squires

Ah, thanks Jose - that makes sense
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

You can also use:


put #f, , CAST(USHORT PTR, wszText.m_pBuffer)[0], LEN(wszText)


Paul Squires

Thanks Jose, the first syntax worked okay but I will keep this second version in mind as well.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

This also works and is more suited for people that doesn't know the inner working of CWSTR:


put #f, , CAST(USHORT PTR, *wszText)[0], LEN(wszText)


Casting is unavoidable because *wszText returns a WSTRING pointer and FB does not support it with PUT.

Wilko Verweij

Hi Jose, I am a bit confused about the file commands with unicode. I will check the CTextStream class soon, but, for the meantime, which FB file commands do not work with unicode? Dir$, I read, and OPEN does not work with unicode path/file names. What about FileCopy? And is there a way to get 'INPUT #' working with wstrings? LINE INPUT # works, I found out, but INPUT # does not...

José Roca

The declaration for Filecopy
Declare Function FileCopy ( ByVal source As ZString Ptr, ByVal destination As ZString Ptr ) As Long
uses ZString, so I assume that it won't work if you pass a WString containing true unicode characters, such "тест" (cyrillic), not "Test" (ascii), because FB will try to automatically convert it to ansi.

I only have used OPEN once, when I began to work with FB, and it is in my ToDo list to change the function that uses it. I haven't tested all the FB file procedures to see if they work with unicode or not, because if OPEN does not work then the rest is useless.


Paul Squires

From now on all my FB file input will be done using CTextStream (non-binary files) and CStream (for binary files). CTextStream is **EXTREMELY** easy to use and mirrors the FB syntax closely so the learning curve is minimal. The CStream was a little harder because Jose did not have Help file info for it but with a couple of searches of Microsoft's documentation I was able to find the right flags.

COMMAND is another non-unicode aware FB function. Use AfxCommand instead.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#9
To replace FileCopy, you can use:


#INCLUDE ONCE "Afx/CFileSys.inc"

DIM pFileSys AS CFileSys
pFileSys.CopyFile("C:\MyFolder\MyFile.txt", "C:\MyOtherFolder\MyFile.txt")


It will work if you use Russian, Chinese, Arab, etc.

And with CFileSys you can do other things like copy a folder and move, delete or rename files and folders.

Wilko Verweij

Thanks. I am actually looking for a substitute for 'INPUT #FileNum, Variable". In the CTextStream I see only the equivalent for "LINE INPUT". Can the functions in the C-runtime library be used for replacing "INPUT #"? Or are those only for ANSI-files?

José Roca

They can't because INPUT # accepts a variable list of variables, but you can easily replace it by reading the full line and then use the AfxStrExtract function to extract the values and assign them to your variables.

José Roca

To replace FileCopy with a version that also works with unicode, you can use the API function CopyFileW.
See: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-copyfilew

The FreeBasic version


FBCALL int fb_FileCopy( const char *source, const char *destination )
{
BOOL res;
res = CopyFile( source, destination, FALSE );
return fb_ErrorSetNum( res == FALSE ? FB_RTERROR_ILLEGALFUNCTIONCALL : FB_RTERROR_OK );
}


calls the ansi version of CopyFile.

Wilko Verweij

OK, thanks again. I'll go for the AfxStrExtract function.