@Keya
Very nice for fast string management, but is better you rename your BSTR to FastStr then there is no discusion about the structures used.
BSTR is not equal to FastStr and finished!
Property times a code written to create BSTR manually.
BSTR is only needed under Windows and there are ready APIs.
Update for Keya
Code: Select all
; BSTR Functions; Created by mk-soft; Date 19.03.017
; *****************************************************************************
Structure udtArrayChar
c.c[0]
EndStructure
Structure udtBStr;Align 4
len.l
str.udtArrayChar
EndStructure
; -----------------------------------------------------------------------------
Procedure CreateBStr(Text.s)
Protected *bstr.udtBStr, len
len = StringByteLength(Text)
*bstr = AllocateMemory(len + SizeOf(Long) + SizeOf(character))
*bstr\len = len
CopyMemory(@Text, @*bstr\str, len)
ProcedureReturn @*bstr\str
EndProcedure
; -----------------------------------------------------------------------------
Procedure FreeBStr(*Bstr)
Protected *mem = *Bstr - SizeOf(Long)
FreeMemory(*mem)
EndProcedure
; -----------------------------------------------------------------------------
Procedure ConcatBStr(T1, T2)
Protected *t1.udtBStr, *t2.udtBStr, *r1.udtBStr, len
*t1 = t1 - SizeOf(Long)
*t2 = t2 - SizeOf(Long)
If *t1\len And *t2\len
len = *t1\len + *t2\len
*r1 = AllocateMemory(len + SizeOf(Long) + SizeOf(character))
*r1\len = len
CopyMemory(@*t1\str, @*r1\str, *t1\len)
CopyMemory(@*t2\str, @*r1\str + *t1\len, *t2\len)
ElseIf *t1\len
len = MemorySize(*t1)
*r1 = AllocateMemory(len)
CopyMemory(*t1, *r1, len)
ElseIf *t2\len
len = MemorySize(*t2)
*r1 = AllocateMemory(len)
CopyMemory(*t2, *r1, len)
Else
*r1 = AllocateMemory(SizeOf(long) + SizeOf(character))
EndIf
ProcedureReturn @*r1\str
EndProcedure
; -----------------------------------------------------------------------------
Procedure _AddBStr(BStr, Text.s)
Protected *bstr.udtBStr, len, len2
*bstr = Bstr - SizeOf(Long)
len = StringByteLength(Text)
len2 = *bstr\len + len
*bstr = ReAllocateMemory(*bstr, len2 + SizeOf(Long) + SizeOf(character))
CopyMemory(@Text, @*bstr\str + *bstr\len, len)
*bstr\len = len2
ProcedureReturn @*bstr\str
EndProcedure
Macro AddBstr(BStr, Text)
BStr = _AddBStr(BStr, Text)
EndMacro
; -----------------------------------------------------------------------------
Procedure LenBStr(*Bstr)
Protected *mem.udtBStr = *Bstr - SizeOf(Long)
ProcedureReturn (*mem\len / SizeOf(character))
EndProcedure
; -----------------------------------------------------------------------------
Procedure LeftBStr(BStr, Lenght)
Protected *r1.udtBStr, *BStr.udtBStr, len
*BStr.udtBStr = Bstr - SizeOf(Long)
len = Lenght * SizeOf(character)
If len > *BStr\len
len = *BStr\len
EndIf
*r1 = AllocateMemory(len + SizeOf(Long) + SizeOf(character))
*r1\len = len
CopyMemory(@*BStr\str, @*r1\str, len)
ProcedureReturn @*r1\str
EndProcedure
; -----------------------------------------------------------------------------
Procedure RightBStr(BStr, Lenght)
Protected *r1.udtBStr, *BStr.udtBStr, len, pos
*BStr.udtBStr = Bstr - SizeOf(Long)
len = Lenght * SizeOf(character)
If len > *BStr\len
len = *BStr\len
EndIf
*r1 = AllocateMemory(len + SizeOf(Long) + SizeOf(character))
*r1\len = len
pos = *BStr\len - len
CopyMemory(@*BStr\str + Pos, @*r1\str, len)
ProcedureReturn @*r1\str
EndProcedure
; -----------------------------------------------------------------------------
Procedure MidBStr(BStr, Position, Lenght = 0)
Protected *r1.udtBStr, *BStr.udtBStr, len, ofs
*BStr.udtBStr = Bstr - SizeOf(Long)
ofs = (position - 1) * SizeOf(character)
len = Lenght * SizeOf(character)
Repeat
If ofs >= *BStr\len Or ofs < 0
*r1 = AllocateMemory(SizeOf(Long) + SizeOf(character))
Break
EndIf
If Not len
len = *BStr\len
EndIf
If ofs + len > *BStr\len
len = *BStr\len - ofs
EndIf
*r1 = AllocateMemory(len + SizeOf(Long) + SizeOf(character))
*r1\len = len
CopyMemory(@*BStr\str + ofs, @*r1\str, len)
Until #True
ProcedureReturn @*r1\str
EndProcedure
; -----------------------------------------------------------------------------
Procedure.s BStrString(*BStr)
Protected *value.String = @*Bstr
ProcedureReturn *value\s
EndProcedure
; -----------------------------------------------------------------------------
Procedure BStrVal(*BStr)
Protected *value.String = @*Bstr
ProcedureReturn Val(*value\s)
EndProcedure
; -----------------------------------------------------------------------------
Procedure.f BStrValF(*BStr)
Protected *value.String = @*Bstr
ProcedureReturn ValF(*value\s)
EndProcedure
; -----------------------------------------------------------------------------
Procedure.d BStrValD(*BStr)
Protected *value.String = @*Bstr
ProcedureReturn ValD(*value\s)
EndProcedure
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
;- Test
CompilerIf #PB_Compiler_Debugger
Define t1, t2, t3, r1
t1 = CreateBStr("Hello World")
t2 = CreateBStr(", Purebasic Power")
t3 = ConcatBStr(t1,t2)
AddBStr(t3, " !")
Debug LenBStr(t3)
Debug BStrString(t3)
r1 = LeftBStr(t3, 5)
Debug BStrString(r1)
FreeBStr(r1)
r1 = RightBStr(t3, 7)
Debug BStrString(r1)
FreeBStr(r1)
r1 = MidBStr(t3, 14, 9)
Debug BStrString(r1)
Debug LenBStr(r1)
FreeBStr(r1)
r1 =CreateBStr("12345.12345")
Debug BStrVal(r1)
Debug BStrValF(r1)
Debug BStrValD(r1)
FreeBStr(r1)
FreeBStr(t1)
FreeBStr(t2)
FreeBStr(t3)
CompilerElse
Define t1, append$ ;a BString and a normal String$
append$ = ""
Time1=ElapsedMilliseconds()
For i = 1 To 20000
append$ + "Append This"
Next i
Time2=ElapsedMilliseconds()
A$ = "Str$ Time=" + Str(Time2 - Time1) + ~"ms\n"
t1 = CreateBStr("")
Time1=ElapsedMilliseconds()
For i = 1 To 20000
AddBStr(t1, "Append This")
Next i
Time2=ElapsedMilliseconds()
A$ + "BSTR Time=" + Str(Time2 - Time1) + "ms"
MessageRequester("BSTR timings",A$)
;Str$ Time=7716ms
;BSTR Time=26ms
CompilerEndIf
P.S. Only Unicode