UCase
|
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 UCase).
|
|
Code |
UCase$ inline |
sRet = UCase$(sDum1)
|
UCase02 |
Public Function UCase02(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(UCase$(Chr$(C))): Next
For C = 256 To 400: iLUT(C) = C: Next
iLUT(353) = 352
iLUT(339) = 338
iLUT(382) = 381
init = 1
End If
lLen = Len(sString)
RtlMoveMemory ByVal VarPtr(UCase02), _
SysAllocStringByteLen(StrPtr(sString), lLen + lLen), 4
saDst.pvData = StrPtr(UCase02)
RtlMoveMemory ByVal psaDst, pDst, 4
For C = 0 To lLen - 1
Select Case aDst(C)
Case 97 To 382
aDst(C) = iLUT(aDst(C))
End Select
Next
RtlMoveMemory ByVal psaDst, 0&, 4
End Function
|
UCase03 |
Public Function UCase03(ByRef sString As String) As String
' by Donald, donald@xbeat.net, 20011209 (TLB-ed UCase02)
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(UCase$(Chr$(C))): Next
For C = 256 To 400: iLUT(C) = C: Next
iLUT(353) = 352
iLUT(339) = 338
iLUT(382) = 381
init = 1
End If
lLen = Len(sString)
UCase03 = BStrAPI.SysAllocStringLenPtr(ByVal StrPtr(sString), lLen)
saDst.pvData = StrPtr(UCase03)
FastString.RtlMoveMemory ByVal psaDst, pDst
For C = 0 To lLen - 1
Select Case aDst(C)
Case 97 To 382
aDst(C) = iLUT(aDst(C))
End Select
Next
FastString.RtlMoveMemory ByVal psaDst, 0&
End Function
|
UCase04 |
UCase04/LCase04 is class-wrapped.
Cinemascope here, preview here:
|
UCase05 |
UCase05/LCase05 is class-wrapped.
Find it inside the UCase04/LCase04 class above.
Update your TypeLibs: new FastString.
|
Calls |
| sRet = UCaseXX(sDum1)
|
1 | sDum1 = "hey"
|
2 | sDum1 = Replicate(50, "If any band epitomised the 70's, it was Sweet. ")
|
3 | sDum1 = "HEY"
|
4 | sDum1 = Replicate(50, "IF ANY BAND EPITOMISED THE 70'S, IT WAS SWEET. ")
|
Charts |
 |
|
VB5 Charts |
|
Call 1 |
5 | 3.17 | 3.904µs |
4 | 1.98 | 2.436µs |
3 | 1.59 | 1.955µs |
2 | 1.01 | 1.239µs |
1 | 1.00 | 1.231µs |
|
Call 2 |
5 | 8.02 | 613µs |
4 | 2.16 | 165µs |
3 | 2.05 | 157µs |
2 | 1.27 | 97µs |
1 | 1.00 | 76µs |
|
Call 3 |
5 | 3.17 | 3.904µs |
4 | 1.94 | 2.388µs |
3 | 1.58 | 1.943µs |
2 | 1.01 | 1.239µs |
1 | 1.00 | 1.230µs |
|
Call 4 |
5 | 8.62 | 661µs |
2 | 1.20 | 92µs |
4 | 1.29 | 99µs |
3 | 1.26 | 96µs |
1 | 1.00 | 77µs |
|
|
VB6 Charts |
|
Call 1 |
5 | 3.11 | 3.862µs |
4 | 2.24 | 2.790µs |
3 | 1.72 | 2.134µs |
2 | 1.16 | 1.436µs |
1 | 1.00 | 1.243µs |
|
Call 2 |
5 | 8.07 | 614µs |
4 | 2.32 | 177µs |
3 | 1.94 | 148µs |
2 | 1.07 | 82µs |
1 | 1.00 | 76µs |
|
Call 3 |
5 | 3.20 | 3.858µs |
4 | 2.29 | 2.751µs |
3 | 1.79 | 2.154µs |
2 | 1.19 | 1.432µs |
1 | 1.00 | 1.204µs |
|
Call 4 |
5 | 8.29 | 614µs |
4 | 1.78 | 132µs |
3 | 1.31 | 97µs |
2 | 1.11 | 82µs |
1 | 1.00 | 74µs |
|
|
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?
|
|