ModXString.pbi multi type string wrangller

Share your advanced PureBasic knowledge/code with the community.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

ModXString.pbi multi type string wrangller

Post by idle »

ModXString

Might be useful if you need to work with multiple string formats and can't remember the ins and outs.
logic may be a bit bent so feel free to modify and add to it.
Facilitates using strings in any format, which may be useful when interacting with external libs
that require either utf8, unicode, wchar, ascii or Bstr

Needs testing on OSX may need imports fixed
Windows see if the Chinese prints, doesn't do it on xp vm but probably the font or local settings!

v1.3
Added Bstr
fixed catchXstring

v1.2
added
AddXString
AppendXString
LeftXString
MidXString
RightXString
ClearXString

v1.1
Added CopyXstring

Code: Select all

;;======================================================================
; Module:            ModXString.pbi
; Author:             Idle 
; Date:                Aug 08, 2013
; Version:            1.3
; Target Compiler:    PureBasic 5.2+
; Target OS:        Linux, OSX, Windows 
;Compiler Mode  Unicode 
; License:             Free, unrestricted, no warranty whatsoever ,use at your own risk
;
; Description       multi type string wrangller  
; Useage 
; 
;    *str.Xstring = NewXString(pbString,xStringType)     
;     makes a string of the desired type where type can be Ascii, unicode, utf8, wchar,Bstr  
;    
;    *str.Xstring = CatchXString(*ptr,xStringCastType,xStringSourceType=0,len=-1)  
;     catch a string from memory or data , len may need to be specified    
;     
;     pbstring = PeekXString(*string.XString)  
;     returns a gui printable string from a given xstring, assumes you've compiled in unicode mode unless the strings are printable in ascii values 
;
;     *newXstring = CopyXString(*src.xstring,*dest.xString=0,typecast=0)  
;      copys an xString returns the pointer to the new or replaced xstring 
;     ;dest can be null of an existing xstring  
;      ;typecast allows you to overide and cast dest to the specified format 
;           
;     *newXstring = AppendXString(*str.xstring,text.s,xStringType=0) 
;      add text to the string and optionlly recast it, returns a new string 
;
;     *newXstring = AddXString(*a.xstring,*b.xstring,xStringType=0) 
;      joins two xtrigns together returning the new string optioanlly casting it  
;
;      *newXstring = LeftXString(*str.xString,len,xStringType=0) 
;       returns the left portion of a string optional casting to it 
;
;     to pass an xString to an external libray function, pass the strings char buffer pointer     
;     *str\char
;      
;     to get an xString from an external library function use CatchXstring 
;       
;     for fast string itteration use the opaque itterators, ensure you pick the right one for the string type
;      *str\char\a[index]    ascii , utf8 ;
;      *str\char\u[index]    unicode, Bstr (note bStr index starts from 2  
;      *str\char\w[index]   wide char :  .l on linux and osx, .u on windows  
;      
;      String length reports the byte length in ascii and utf8 (since it's variable length) 
;      bytelen =  *strAscii\len
;      bytelen = *strUTF8\len
;      For unicode and Wchar mutliply by the size of the structure  
;      bytelen =  *strUnicode\len * SizeOf(unicode) 
;      bytelen =  *strWchar\len * SizeOf(Wchar)
;      or 
;      bytelen = *strUnicode\bytelen 
;
;====================================================================== 


DeclareModule ModXString 

Structure _xStrptr      ;internal for Xstring Strucutre        
   StructureUnion      ;char buffer itterators 
      a.a[0]                     ;ascii and utf8              
      u.u[0]                     ;unicode   
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS
         w.l[0]                 ;wide char 32 bits linux osx 
      CompilerElse 
         w.u[0]                ;wide char windows 16 bit unicode  
      CompilerEndIf   
   EndStructureUnion
EndStructure    

;dummy structure for sizeof(wChar)
CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS 
   Structure wChar 
      char.l
   EndStructure
CompilerElse      
   Structure wChar 
      char.u
   EndStructure   
CompilerEndIf

Structure XString 
   type.a                       
   len.l
   bytelen.l
   *char._xStrptr   
EndStructure    

#Ascii = #PB_Ascii
#Unicode = #PB_Unicode
#UTF8 = #PB_UTF8
#Wchar = 255
#BStr = 254

;-Declare
Declare NewXString(string.s,xStrType)          ;Create a string with a type 
Declare CatchXString(*ptr,xStringSourceType,xStringCastType=0,len=-1)   ;Catch a string from memory or data section 
Declare.s PeekXString(*string.xString)                ;converts the string to the native mode for gui output 
Declare CopyXString(*src.xstring,*dest.xString=0,typecast=0)  ;copy an xstring returns either *dest or a new xstring 
Declare AppendXString(*str.xstring,text.s,xStringType=0)  ;append an xstring and optionally recast to another type 
Declare AddXString(*a.xstring,*b.xstring,xStringType=0)   ;add join two xtrings together returns a new xstring  
Declare LeftXString(*str.xstring,len,xStringType=0)  ;returns left by len in a new xstring 
Declare MidXString(*str.xString,pos,len,xStringType=0)  ;returns mid from position by len in a new xstring
Declare RightXString(*str.xString,len,xStringType=0)   ;returns right by len in a new xstring   
Declare ClearXString(*str.xString)    ;clear an xstring = "" 
Declare FreeXString(*string.xString)  ;free string  

EndDeclareModule 

Module ModXString 

CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS
   ImportC ""
      mbstowcs(*dest,*src,n)
      wcstombs(*dest,*src,n)   
   EndImport 
   
CompilerEndIf 

Procedure NewXString(string.s,type)
   Protected *tmem,*str.xstring,len,blen
   
   len = Len(string)
   If len > 0
      
      *tmem = AllocateMemory(len*6)
      
      CompilerIf #PB_Compiler_Unicode 
         CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS
            If type = #BStr
               blen = PokeS(*tmem,PeekS(@string,#PB_Unicode),-1,#PB_Unicode)
            ElseIf type <> #Wchar 
               blen = PokeS(*tmem,PeekS(@string,#PB_Unicode),-1,type)
            Else  
               *mem = AllocateMemory(len*6)
               len = PokeS(*mem,PeekS(@string,#PB_Unicode),-1,#PB_UTF8) 
            EndIf
         CompilerElse 
            If type = #BStr
               blen = PokeS(*tmem,PeekS(@string,#PB_Unicode),-1,#PB_Unicode)
           ElseIf type <> #Wchar 
               blen = PokeS(*tmem,PeekS(@string,#PB_Unicode),-1,type)
            Else    
               blen = PokeS(*tmem,PeekS(@string,#PB_Unicode),-1,#PB_Unicode)
            EndIf   
         CompilerEndIf  
      CompilerElse 
         CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS
            If type = #Bstr 
               blen = PokeS(*tmem,PeekS(@string,#PB_Ascii),-1,#PB_Unicode)
           ElseIf type <> #Wchar 
               blen = PokeS(*tmem,PeekS(@string,#PB_Ascii),-1,type) 
            Else 
               *mem = AllocateMemory(len*6)
               len = PokeS(*mem,PeekS(@string,#PB_Ascii),-1,#PB_UTF8) 
            EndIf    
         CompilerElse 
            If type = #Bstr
               blen = PokeS(*tmem,PeekS(@string,#PB_Ascii),-1,#PB_Unicode)
           ElseIf type <> #Wchar 
               blen = PokeS(*tmem,PeekS(@string,#PB_Ascii),-1,type)  
            ElseIf type = #wchar 
               blen = PokeS(*tmem,PeekS(@string,#PB_Ascii),-1,#PB_Unicode)
            EndIf   
         CompilerEndIf  
      CompilerEndIf 
      
      CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or#PB_Compiler_OS = #PB_OS_MacOS
         If type = #Wchar  
            If  mbstowcs(*tmem,*mem,len) > 0
               blen = len*4
               FreeMemory(*mem)
            EndIf    
         EndIf 
      CompilerEndIf    
      
      If type = #PB_UTF8 
         len = blen 
      EndIf  
      
      *str = AllocateMemory(SizeOf(xString)) 
      *str\type = type 
      *str\len = len 
      
      If type <> #bstr 
         *str\bytelen = blen
         *str\char = AllocateMemory(blen+1) 
         CopyMemory(*tmem,*str\char,blen+1)
         FreeMemory(*tmem)
      Else 
         *str\bytelen = blen + 4 
         *str\char = AllocateMemory(blen+5) 
         CopyMemory(*tmem,*str\char+4,blen+1)
         PokeL(*str\char,len*2)
         FreeMemory(*tmem)
      EndIf 
      ProcedureReturn *str 
   Else 
      *str = AllocateMemory(SizeOf(xString)) 
      *str\type = type 
      ProcedureReturn *str       
   EndIf 
EndProcedure    

Procedure CatchXString(*ptr,xStringSourceType,xStringCastType=0,len=-1)
   Protected string.s
   If  xStringCastType=0 
      xStringCastType = xStringSourceType
   EndIf
   Select xStringSourceType
      Case #Ascii,#unicode,#utf8 
         string = PeekS(*ptr,len,xStringSourceType)
      Case #bstr 
         string = PeekS(*ptr+4,PeekL(*ptr),#PB_Unicode) 
      Case #wchar   
         CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or #PB_Compiler_OS = #PB_OS_MacOS
            len = wcstombs(0,*ptr,0)
            If len 
               *tmp = AllocateMemory(len)
               wcstombs(*tmp,*ptr,len)
               string = PeekS(*tmp,-1,#PB_UTF8) 
               FreeMemory(*tmp)
            Else 
               ProcedureReturn 0 
            EndIf    
         CompilerElse 
            string =  PeekS(*ptr,-1,#PB_Unicode)   
         CompilerEndIf  
   EndSelect         
   ProcedureReturn NewXString(string,xStringCastType)
EndProcedure   

Procedure FreeXString(*string.xstring)
   If *string 
      If *string\len > 0 
         FreeMemory(*string\char)
      EndIf  
      FreeMemory(*string)
   EndIf     
EndProcedure   

Procedure.s PeekXString(*string.XString) 
   Protected out.s,*tmp 
   If *string 
      If *string\len > 0
         Select *string\type 
            Case #Ascii 
               ProcedureReturn PeekS(*string\char,-1,#PB_Ascii)    
            Case #Unicode
               ProcedureReturn PeekS(*string\char,-1,#PB_Unicode) 
            Case #UTF8
               ProcedureReturn PeekS(*string\char,-1,#PB_UTF8) 
            Case #Wchar 
               CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or #PB_Compiler_OS = #PB_OS_MacOS
                  *tmp = AllocateMemory(*string\len*4)
                  wcstombs(*tmp,*string\char,*string\len*4+1)
                  out = PeekS(*tmp,-1,#PB_UTF8) 
                  FreeMemory(*tmp)
                  ProcedureReturn out    
               CompilerElse 
                  ProcedureReturn PeekS(*string\char,-1,#PB_Unicode)   
               CompilerEndIf  
            Case #bstr 
                 ProcedureReturn PeekS(*string\char+4,PeekL(*string\char)>>1,#PB_Unicode)
         EndSelect
       EndIf
   EndIf
   
EndProcedure   

Procedure CopyXString(*src.xstring,*dest.xString=0,typecast=0) 
   
   Protected blen,*psrc 
   If typecast = 0 
      typecast = *src\type 
   EndIf    
   
   If *dest = 0 
      ProcedureReturn CatchXString(*src\char,*src\type,typecast,*src\bytelen)
   ElseIf  typecast <> *src\type 
      If *dest\len 
         FreeMemory(*dest\char) 
      EndIf
      FreeMemory(*dest) 
      ProcedureReturn CatchXString(*src\char,*src\type,typecast,*src\bytelen) 
   ElseIf *dest\len > 0 
      FreeMemory(*dest\char) 
   EndIf
 
   *dest\len = *src\len 
   *dest\type = *src\type 
   *dest\char = AllocateMemory(*src\bytelen)
   CopyMemory(*src\char,*dest\char,*src\bytelen) 
   ProcedureReturn *dest
   
EndProcedure   

Procedure AppendXString(*str.xstring,text.s,xStringType=0) 
   Protected *out.xstring,temp.s 
   If *str
      temp.s = PeekXString(*str) 
      temp + text 
      If xStringType =0 
         xStringType = *str\type 
      EndIf
      *out = NewXString(temp,xStringType)
      FreeXString(*str)
      ProcedureReturn *out
   Else 
      *out = NewXString(temp,xStringType) 
      ProcedureReturn *out
   EndIf
EndProcedure 

Procedure AddXString(*a.xstring,*b.xstring,xStringType=0) 
   Protected *out.xstring, text.s  
   If *a And *b 
      text = PeekXString(*a) 
      text + PeekXString(*b)
      If xStringType =0 
         xStringType = *a\type 
      EndIf
      *out = NewXString(text,xStringType)
      FreeXString(*a)
      FreeXString(*b)
      ProcedureReturn *out 
   EndIf
EndProcedure     

Procedure LeftXString(*str.xstring,len,xStringType=0)
   Protected *out.xstring, text.s 
   If *str
      text = Peekxstring(*str) 
      text = Left(text,len) 
      If xStringType =0 
         xStringType = *str\type 
      EndIf
      *out= NewXString(text,xStringType) 
      ProcedureReturn *out
   EndIf
EndProcedure    

Procedure MidXString(*str.xString,pos,len,xStringType=0) 
   Protected *out.xstring, text.s 
   If *str
      text = Peekxstring(*str) 
      text = Mid(text,pos,len) 
      If xStringType =0 
         xStringType = *str\type 
      EndIf
      *out= NewXString(text,xStringType) 
      ProcedureReturn *out
   EndIf 
EndProcedure 

Procedure RightXString(*str.xString,len,xStringType=0) 
   Protected *out.xstring, text.s 
   If *str
      text = Peekxstring(*str) 
      text = Right(text,len) 
      If xStringType =0 
         xStringType = *str\type  
      EndIf
      *out= NewXString(text,xStringType) 
      ProcedureReturn *out 
   EndIf
EndProcedure    

Procedure ClearXString(*str.xString) 
   If *str
      If *str\len 
         FreeMemory(*str\char) 
         *str\len=0   
      EndIf   
   EndIf
EndProcedure 

EndModule 



;compile in console mode 
CompilerIf #PB_Compiler_IsMainFile
   
   EnableExplicit   
   
   OpenConsole()
   
   UseModule ModXString 
   
   Define.xstring *sasc,*suni,*sut8,*swc,*sBstr,*x,*y,*z,*copyWc,*copyBstr
   
   *sasc = NewXString("hello@",#Ascii) 
   *suni = NewXString("hello@",#Unicode) 
   *sut8 = NewXString("hello@",#UTF8)
   *swc = NewXString("hello@",#Wchar) 
   *sBstr = NewXString("hello@",#Bstr) 
   
   *x = CatchXString(?textc,#UTF8,0,9)
   
   Define.i a 
   
   For a = 0 To *sasc\len            ;len holds the number of bytes in ascii and utf8   
      Print(Str(*sasc\char\a[a])+ " ")       ;use the \a[index] itterator  
   Next                                        
   
   
   PrintN("Ascii " + PeekXString(*sasc))
   
   PrintN("+++++++++++++++++++++++++") 
   ; 
   For a = 0 To *suni\len         ;len holds number of characters use len * sizeof(unicode) to get number of byte if needed   
      Print(Str(*suni\char\u[a]) + " ");     ;use the \u[index] itterator 
   Next 
   
   PrintN("Unicode " + PeekXString(*suni))
   
   PrintN("+++++++++++++++++++++++++") 
   
   For a = 0 To *sut8\len       ; utf reports number of bytes in buffer  
      Print(Str(*sut8\char\a[a]) + " ")    ;use \a[index] itterator  
   Next 
   
   PrintN("UTF8 " + PeekXString(*sut8))  ; 
   
   PrintN("+++++++++++++++++++++++++") 
   
   For a = 0 To *swc\len      ;len holds number of characters call string\blen for length of bytes   
      Print(Str(*swc\char\w[a])+ " ")  ;use \w[index] itterator 
   Next 
   
   PrintN("Wchar " + PeekXString(*swc))
      
   PrintN("+++++++++++++++++++++++++")  
   
   *copyWc = CopyXString(*swc) 
   PrintN("copy wchar " + PeekXString(*copyWc))
   
   PrintN("+++++++++++++++++++++++++")
   
   For a = 2 To *sbstr\len+2      ;len holds number of characters but a bStr index starts from 2 to len +2    
      Print(Str(*sbstr\char\u[a])+ " ")  ;use \u[index] itterator 
   Next 
   
   PrintN("bStr " + PeekXString(*sbstr))
   
   PrintN("+++++++++++++++++++++++++")  
   
    *copyBstr = CopyXString(*sBstr) 
   PrintN("copy bstr " + PeekXString(*copyBstr))
   
   PrintN("+++++++++++++++++++++++++")
   
   For a = 0 To *x\len         ;debug utf8 string      
      Print(Str(*x\char\a[a])+ " " ) 
   Next 
   
   PrintN("UTF8 " + PeekXString(*x))   ;prints the utf8 string masheled through the compilers mode -> unicode! 
   
   PrintN("+++++++++++++++++++++++++")  
   
   *y = CopyXString(*x)  ;copy *x casts *x to *y 
   
   PrintN("copy utf8 " + PeekXString(*y))
   
   PrintN("+++++++++++++++++++++++++")  
   
   *y = CopyXString(*suni,*y,#Ascii)   ;copy *suni which is unicode to *y which is utf8 but cast y to ascii   
   
   PrintN("copy a unicode string to a utf8 string recasting it as ascii " + PeekXString(*y))
   
   PrintN("+++++++++++++++++++++++++")  
   
   *y = AppendXString(*y," world") 
   
   PrintN("append  " + PeekXString(*y))
   
   PrintN("+++++++++++++++++++++++++") 
   
   *z = LeftXString(*y,5) 
   
   PrintN("left 5 " + PeekXString(*z))
   
   FreeXString(*z)
   
   PrintN("+++++++++++++++++++++++++") 
   
   *z = RightXString(*y,5) 
   
   PrintN("right 5 " + PeekXString(*z))
   
   FreeXString(*z)
   
   PrintN("+++++++++++++++++++++++++") 
   
   *z = MidXString(*y,6,1)
   
   PrintN("mid 5,1 " + PeekXString(*z))
   
   PrintN("+++++++++++++++++++++++++") 
   
   ClearXstring(*z) 
   *z = AppendXString(*z,"hello world 123")
   PrintN("append " + PeekXString(*z))
   
   FreeXString(*sasc)  ;free the strings pb can't free them for you 
   FreeXString(*suni)
   FreeXString(*sut8)
   FreeXString(*swc) 
   FreeXString(*sBstr)
   FreeXString(*copyWc)
   FreeXString(*copyBstr)
   FreeXString(*x)
   FreeXString(*y)
   FreeXString(*z)
   
   DataSection
      textc:
      Data.a 231,186,175,229,159,186,231,161,128  ;pure basic in chinese google translation
   EndDataSection 
   
   UnuseModule ModXString 
   
   PrintN("press key to end") 
   Input()
   
    
CompilerEndIf   
Windows 11, Manjaro, Raspberry Pi OS
Image
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ModXString.pbi multi type string wangller

Post by Little John »

Interesting, thanks for sharing!

I tested your code with PB 5.20 beta 8 on Windows XP x86 ( yes, compiled in Unicode mode :-) ), and got the following Debug output:
104
101
108
108
111
64
0
But in your code, it reads 5 times

Code: Select all

Debug 11111111
I'm puzzled because this doesn't appear anywhere in the output.

Is this a bug in PB 5.20 beta 8, or does your code confuse the Debugger? :-)
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: ModXString.pbi multi type string wangller

Post by Bisonte »

I think its like a line... like Debug "-------"
to show the single blocks
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ModXString.pbi multi type string wangller

Post by Little John »

Bisonte wrote:I think its like a line... like Debug "-------"
to show the single blocks
I'm not concerned about its meaning.
But as I wrote, I wonder why this doesn't appear in my output.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: ModXString.pbi multi type string wangller

Post by c4s »

@Little John
After the first debug block a message box pops up which you have to confirm. Only then comes next (separated with "1111111") etc. I guess you've overlooked that...
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ModXString.pbi multi type string wangller

Post by Little John »

c4s wrote:@Little John
After the first debug block a message box pops up which you have to confirm. Only then comes next (separated with "1111111") etc. I guess you've overlooked that...
Oops.
Yes, I looked at the debug output (and copied it here) before confirming the message requester. :oops:
Thank you so much for detecting my absent-mindedness!
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: ModXString.pbi multi type string wangller

Post by idle »

Little John wrote:Interesting, thanks for sharing!

I tested your code with PB 5.20 beta 8 on Windows XP x86 ( yes, compiled in Unicode mode :-) ), and got the following Debug output:
104
101
108
108
111
64
0
But in your code, it reads 5 times

Code: Select all

Debug 11111111
I'm puzzled because this doesn't appear anywhere in the output.

Is this a bug in PB 5.20 beta 8, or does your code confuse the Debugger? :-)
Some thing confusing the debugger on system for sure, the IDE and stand alone debuggers are both unusable!

The debug 1111111 is used as the console can't debug strings in unicode mode

changed it to use console.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: ModXString.pbi multi type string wangller

Post by idle »

v1.2 Added

AddXString
AppendXString
LeftXString
MidXString
RightXString
ClearXString
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: ModXString.pbi multi type string wrangller

Post by idle »

v1.3
Added Bstr
fixed catchXstring
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: ModXString.pbi multi type string wrangller

Post by Bisonte »

An error occurs : [COMPILER] Error : *string has no structure after I copy it in IDE and press F5

Code: Select all

Procedure CatchXString(*ptr,xStringSourceType,xStringCastType=0,len=-1)
   Protected string.s
   If  xStringCastType=0
      xStringCastType = xStringSourceType
   EndIf
   Select xStringSourceType
      Case #Ascii,#unicode,#utf8
         string = PeekS(*ptr,len,xStringSourceType)
      Case #bstr
         string = PeekS(*ptr+4,PeekL(*ptr),#PB_Unicode)
      Case #wchar   
         CompilerIf #PB_Compiler_OS = #PB_OS_Linux Or #PB_Compiler_OS = #PB_OS_MacOS
            len = wcstombs(0,*ptr,0)
            If len
               *tmp = AllocateMemory(len)
               wcstombs(*tmp,*ptr,len)
               string = PeekS(*tmp,-1,#PB_UTF8)
               FreeMemory(*tmp)
            Else
               ProcedureReturn 0
            EndIf   
         CompilerElse
            string =  PeekS(*string\char,-1,#PB_Unicode)   ; <--- [COMPILER] Error : *string has no structure
         CompilerEndIf 
   EndSelect         
   ProcedureReturn NewXString(string,xStringCastType)
EndProcedure 
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: ModXString.pbi multi type string wrangller

Post by idle »

:oops: fixed, I didn't check it on windows before posting it
Windows 11, Manjaro, Raspberry Pi OS
Image
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ModXString.pbi multi type string wrangller

Post by Little John »

Cool.
Thanks again, idle!
Post Reply