PlanetSquires Forums

Support Forums => WinFBX - Windows Framework for FreeBASIC => Topic started by: Paul Squires on July 19, 2018, 01:20:14 AM

Title: Outputting CWSTR to BOM-16 file
Post by: Paul Squires on July 19, 2018, 01:20:14 AM
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:

Code: [Select]
#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

Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on July 19, 2018, 02:46:36 AM
Hi Paul,

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

You can use:

Code: [Select]
put #f, , CAST(BYTE PTR, wszText.m_pBuffer)[0], wszText.m_BufferLen
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Paul Squires on July 19, 2018, 08:04:17 AM
Ah, thanks Jose - that makes sense
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on July 19, 2018, 03:53:55 PM
You can also use:

Code: [Select]
put #f, , CAST(USHORT PTR, wszText.m_pBuffer)[0], LEN(wszText)
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Paul Squires on July 19, 2018, 03:55:28 PM
Thanks Jose, the first syntax worked okay but I will keep this second version in mind as well.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on July 19, 2018, 04:11:33 PM
This also works and is more suited for people that doesn't know the inner working of CWSTR:

Code: [Select]
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.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Wilko Verweij on August 11, 2018, 06:50:50 AM
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...
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on August 11, 2018, 08:09:31 AM
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.

Title: Re: Outputting CWSTR to BOM-16 file
Post by: Paul Squires on August 11, 2018, 08:16:06 AM
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.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on August 11, 2018, 08:19:19 AM
To replace FileCopy, you can use:

Code: [Select]
#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.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Wilko Verweij on August 12, 2018, 06:51:13 AM
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?
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on August 12, 2018, 07:11:28 AM
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.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Josť Roca on August 12, 2018, 07:52:10 AM
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

Code: [Select]
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.
Title: Re: Outputting CWSTR to BOM-16 file
Post by: Wilko Verweij on August 12, 2018, 07:55:30 AM
OK, thanks again. I'll go for the AfxStrExtract function.