Recent Posts

Pages: 1 2 3 4 5 6 7 8 9 10
1
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 09:33:01 PM »
In

Code: [Select]
PRIVATE FUNCTION AfxStrReplace OVERLOAD (BYREF wszMainStr AS CONST WSTRING, BYREF wszMatchStr AS WSTRING, BYREF wszReplaceWith AS WSTRING) AS CWSTR
   DIM cwsMainStr AS CWSTR = wszMainStr

as cwsMainStr is declared as a CWSTR, wszMainStr will always be copied, not attached. Therefore, this code works:

Code: [Select]
DIM cbs AS CBSTR = "1234567890"
print AfxStrReplace(cbs, "5", "x")
print cbs

Now change DIM cwsMainStr AS CWSTR = wszMainStr to DIM cwsMainStr AS CBSTR = wszMainStr and you will be asking for trouble.
2
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 09:19:50 PM »
In this code

Code: [Select]
PRIVATE FUNCTION Remove_ overload (BYREF w AS WSTRING, byval anyflag as long = 0, BYREF m AS WSTRING, _
                                   byval iflag as long = 0) AS ustring
DIM u    AS ustring = w

if you have declared USTRING as CBSTR, the passed w AS WSTRING is detected as a BSTR and it is ATTACHED, not copied, whereas if USTRING is declared as CWSTR, it is copied, not attached.

Attaching was needed because FB does not make a distinction between a BSTR and a WSTRING, since BSTR is not supported. Therefore, the CBSTR constructor checks if it is a WSTRING or a BSTR, and attaches the handle if it is a BSTR or copies the contents if it is a WSTRING. If we did always copy, the intermediate BSTRings won't never we freed and we will get memory leaks.

Code: [Select]
' ========================================================================================
PRIVATE CONSTRUCTOR CBStr (BYREF bstrHandle AS AFX_BSTR = NULL, BYVAL fAttach AS LONG = TRUE)
   CBSTR_DP("--BEGIN CBSTR CONSTRUCTOR AFX_BSTR - handle: " & .WSTR(bstrHandle) & " - Attach: " & .WSTR(fAttach))
   IF bstrHandle = NULL THEN
      m_bstr = SysAllocString("")
      CBSTR_DP("CBSTR CONSTRUCTOR SysAllocString - " & .WSTR(m_bstr))
   ELSE
      ' Detect if the passed handle is an OLE string
      ' If it is an OLE string it must have a descriptor; otherwise, don't
      ' Get the length in bytes looking at the descriptor and divide by 2 to get the number of
      ' unicode characters, that is the value returned by the FreeBASIC LEN operator.
      DIM Res AS INTEGER = PEEK(DWORD, CAST(ANY PTR, bstrHandle) - 4) \ 2
      ' If the retrieved length if the same that the returned by LEN, then it must be an OLE string
      IF Res = .LEN(*bstrHandle) AND fAttach <> FALSE THEN
         CBSTR_DP("CBSTR CONSTRUCTOR AFX_BSTR - Attach handle: " & .WSTR(bstrHandle))
         ' Attach the passed handle to the class
         m_bstr = bstrHandle
      ELSE
         CBSTR_DP("CBSTR CONSTRUCTOR AFX_BSTR - Alloc handle: " & .WSTR(bstrHandle))
         ' Allocate an OLE string with the contents of the string pointer by bstrHandle
         m_bstr = SysAllocString(*bstrHandle)
      END IF
   END IF
   CBSTR_DP("--END CBSTR CONSTRUCTOR AFX_BSTR - " & .WSTR(m_bstr))
END CONSTRUCTOR
' ========================================================================================

To force a copy, you need to change DIM u AS ustring = w to DIM u AS ustring = CWSTR(w), but then w won't we freed.

If I have reserved the use of CBSTR to COM it is for a good reason.


3
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 08:38:54 PM »
Also with Remove_.

Code: [Select]
DIM ustr AS USTRING = "1234567890"
print Remove_(ustr, "23")
print ustr

Looks like these are side effects of defining a USTRING as a CBSTR instead of a CWSTR. I told you that they were'nt interchangeable. Changing the define from #define USTRING Afx.CBstr to #define USTRING Afx.CWstr works fine.
4
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 06:40:04 PM »
When using Replace_, the contents of the orginal string are sometimes changed.

Code: [Select]
DIM ustr AS USTRING = "1234567890"
print Replace_(ustr, "5", "x")
print ustr

Same behavior with Insert_.
5
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 03:29:02 PM »
Changed AfxStrParseCountAny  to be consistent with PB's PARSECOUNT:

Code: [Select]
PRIVATE FUNCTION AfxStrParseCountAny (BYREF wszMainStr AS CONST WSTRING, BYREF wszDelimiter AS WSTRING = ",") AS LONG
   DIM nCount AS LONG = 1
   FOR i AS LONG = 1 TO LEN(wszDelimiter)
      nCount += AfxStrParseCount(wszMainStr, MID(wszDelimiter, i, 1))
   NEXT
   RETURN nCount
END FUNCTION
[code]
6
General Discussion / Re: FreeBASIC CWstr
« Last post by Juergen Kuehlwein on May 26, 2018, 02:57:24 PM »
Yep, was meant the other way round! Thanks for the .zip


JK
7
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 02:41:28 PM »
Your mid_ function is buggy. Must be if n = 0 instead of <> 0.

Code: [Select]
PRIVATE FUNCTION mid_ (BYREF w AS WSTRING, BYVAL i AS ULONG, n AS ULONG = 0) AS ustring
'  if n <> 0 then
  if n = 0 then
    return mid(w, i)
  else
    return mid(w, i, n)
  end if
end function 

BTW if I were you I will always add explicit BYVAL or BYREF to the parameters; otherwise, you will get many warnings when compiling with the -w pedantic option.
8
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 02:40:22 PM »
I used RAR. New attachment with .zip extension.
9
General Discussion / Re: FreeBASIC CWstr
« Last post by Juergen Kuehlwein on May 26, 2018, 02:27:21 PM »
Hi Josť,


i can download the attachment, but 7zip cannot open it. What did you use for creating it ?


JK
10
General Discussion / Re: FreeBASIC CWstr
« Last post by Josť Roca on May 26, 2018, 02:04:40 PM »
I have modified the string functions that used cws instead of **cws.
Pages: 1 2 3 4 5 6 7 8 9 10