VBspeed / Language / LCase
VBspeed © 2000-10, updated: 09-Dec-2001
LCase


LCase
Visual Basic provides the UCase$ and LCase$ functions for changing case. These are smart functions that follow the rules and work correctly regardless of the language. Alas, with computers (and brains...), smart means slow. If you are a eurocentric ANSI kind of guy, the power of the native case changers is wasted on you. What you need is something fast!
Emulating UCase/LCase is straightforward stuff. If it weren't for the Stooges...
Use this function (VB5/6-compatible) to verify the correctness of your emulation code (ANSI LCase).
Code
LCase$ inline sRet = LCase$(sDum1)
LCase02
Public Function LCase02(ByRef sString As String) As String
' by Donald, donald@xbeat.net, 20011209
    Static saDst As SafeArray1D
    Static aDst%()
    Static pDst&, psaDst&
    Static init As Long
    Dim c As Long
    Dim lLen As Long
    Static iLUT(0 To 400) As Integer
    
    If init Then
    Else
        saDst.cDims = 1
        saDst.cbElements = 2
        saDst.cElements = &H7FFFFFFF
        
        pDst = VarPtr(saDst)
        psaDst = ArrPtr(aDst)
        
        ' init LUT
        For c = 0 To 255: iLUT(c) = AscW(LCase$(Chr$(c))): Next
        For c = 256 To 400: iLUT(c) = c: Next
        iLUT(352) = 353
        iLUT(338) = 339
        iLUT(381) = 382
        iLUT(376) = 255
        
        init = 1
    End If
    
    lLen = Len(sString)
    RtlMoveMemory ByVal VarPtr(LCase02), _
        SysAllocStringByteLen(StrPtr(sString), lLen + lLen), 4
    saDst.pvData = StrPtr(LCase02)
    RtlMoveMemory ByVal psaDst, pDst, 4
    
    For c = 0 To lLen - 1
      Select Case aDst(c)
      Case 65 To 381
        aDst(c) = iLUT(aDst(c))
      End Select
    Next
    
    RtlMoveMemory ByVal psaDst, 0&, 4
    
End Function
  
LCase03
Public Function LCase03(ByRef sString As String) As String
' by Donald, donald@xbeat.net, 20011209 (TLB-ed LCase02)
    Static saDst As BStrAPI.SafeArray1D
    Static aDst%()
    Static pDst&, psaDst&
    Static init As Long
    Dim c As Long
    Dim lLen As Long
    Static iLUT(0 To 400) As Integer
    
    If init Then
    Else
        saDst.cDims = 1
        saDst.cbElements = 2
        saDst.cElements1D = &H7FFFFFFF
        
        pDst = VarPtr(saDst)
        psaDst = ArrPtr(aDst)
        
        ' init LUT
        For c = 0 To 255: iLUT(c) = AscW(LCase$(Chr$(c))): Next
        For c = 256 To 400: iLUT(c) = c: Next
        iLUT(352) = 353
        iLUT(338) = 339
        iLUT(381) = 382
        iLUT(376) = 255
        
        init = 1
    End If
    
    lLen = Len(sString)
    LCase03 = BStrAPI.SysAllocStringLenPtr(ByVal StrPtr(sString), lLen)
    saDst.pvData = StrPtr(LCase03)
    FastString.RtlMoveMemory ByVal psaDst, pDst
    
    For c = 0 To lLen - 1
      Select Case aDst(c)
      Case 65 To 381
        aDst(c) = iLUT(aDst(c))
      End Select
    Next
    
    FastString.RtlMoveMemory ByVal psaDst, 0&
    
End Function
LCase04 UCase04/LCase04 is class-wrapped. Cinemascope here, preview here:

LCase05 UCase05/LCase05 is class-wrapped.
Find it inside the UCase04/LCase04 class above.
Update your TypeLibs: new FastString.
Calls
sRet = LCaseXX(sDum1)
1sDum1 = "hey"
2sDum1 = Replicate(50, "If any band epitomised the 70's, it was Sweet. ")
3sDum1 = "HEY"
4sDum1 = Replicate(50, "IF ANY BAND EPITOMISED THE 70'S, IT WAS SWEET. ")
Charts How to read all those numbers
 VB5 Charts
CodeAuthorDopingNotes
LCase$ inline VB  
LCase02 DonaldAPI 
LCase03 DonaldTLB 
LCase04 DonaldAPI,TLB 
LCase05 PaulAPI,TLB 
Call 1
52.993.622s
41.942.353s
31.581.914s
21.061.281s
11.001.213s
Call 2
58.48641s
31.73131s
42.00151s
21.1285s
11.0076s
Call 3
53.023.587s
41.972.340s
31.631.935s
21.071.276s
11.001.188s
Call 4
58.19640s
31.68132s
41.95153s
21.0884s
11.0078s
 VB6 Charts
CodeAuthorDopingNotes
LCase$ inline VB  
LCase02 DonaldAPI 
LCase03 DonaldTLB 
LCase04 DonaldAPI,TLB 
LCase05 PaulAPI,TLB 
Call 1
53.053.814s
42.402.995s
31.762.197s
21.121.404s
11.001.250s
Call 2
58.36639s
31.77135s
41.97151s
21.0983s
11.0076s
Call 3
53.103.778s
42.432.960s
31.812.201s
21.101.334s
11.001.217s
Call 4
58.55639s
31.79134s
42.00149s
21.1183s
11.0075s
Conclusions
...
NOTES
The Stooges.
A bunch of upper ANSI chars is handled by VB in a surprising manner. For example, Chr$(154) returns "". Now when you ask for Asc("") you get 154, so far so good. But AscW("") gives you 353: no zero in the upper unicode half! So VB internally translated 154 (hex 00 9A) into 353 (hex 01 61). You have to know this if you want to emulate ANSI UCase/LCase. Here is a list of ANSI chars with unicode twins, the stooges:
' UCase Stooges
'  154 / 353                138 / 352
'  156 / 339                140 / 338
'  158 / 382                142 / 381
'  255 / 255                159 / 376
' LCase Stooges
'  138 / 352                154 / 353
'  140 / 338                156 / 339
'  142 / 381                158 / 382
'  159 / 376                255 / 255
This function will print the above to your debug window:
Got comments?

top




VBspeed © 2000-10 by Donald Lessau