Johnn
asked on
Shifting Byte arrays?
Experts...I need to shift a byte array say 10, 20 or whatever number of elements up to make room for other information such as a header. How can I do this WITHOUT using a loop of some kind. CopyMemory? Sample code that works please...
PS It's gotta be really FAST
PS It's gotta be really FAST
I think the questioner meant something else. He want to move memory.
Here is a sample:
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Call CopyMem(udtVerBuffer, ByVal lplpBuffer, Len(udtVerBuffer))
Here is a sample:
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Call CopyMem(udtVerBuffer, ByVal lplpBuffer, Len(udtVerBuffer))
ASKER
What I want to do is "insert" bytes to the beginning of an existing byte array, not append...
Hello Mirkwood,
As I read the question, Johnn's byte array might contain something line "ABC" (looking at byte array as if it were a string)
Now what Johnn wants to do is insert 10 "blanks" before:
" ABC" so that he has room to put in some "header" information.
In VB6 this can be achieved like I said.
Johnn, if you haven't got VB6 I think Mirkwood's suggestion might be the best alternative.
As I read the question, Johnn's byte array might contain something line "ABC" (looking at byte array as if it were a string)
Now what Johnn wants to do is insert 10 "blanks" before:
" ABC" so that he has room to put in some "header" information.
In VB6 this can be achieved like I said.
Johnn, if you haven't got VB6 I think Mirkwood's suggestion might be the best alternative.
"concatenate the 10 characters"
or of course:
concatenate it to 10 characters (to insert it before)
or of course:
concatenate it to 10 characters (to insert it before)
caraf_g:
It could be that the byte array is a string but you never know.
Btw: VB5 support also the assigning byte array to string and vice versa as far as I rememeber. The problem with this that this is different under NT and win95 because of unicode.
It could be that the byte array is a string but you never know.
Btw: VB5 support also the assigning byte array to string and vice versa as far as I rememeber. The problem with this that this is different under NT and win95 because of unicode.
ASKER
The solution you posted(VB5 works as well) works for all strings, however I'm mixing string and numeric data. No that I've played with the idea I might want something like this...
dim myByte() as byte
redim myByte(0 to 3)'four byte long header info, aka length of string
mybyte(0)=0
mybyte(1)=0
mybyte(2)=5
mybyte(3)=1
'now I want to "append" to this byte array a string, how do we do it without a loop? OR we could build the string byte array first and then insert this in front...
dim myByte() as byte
redim myByte(0 to 3)'four byte long header info, aka length of string
mybyte(0)=0
mybyte(1)=0
mybyte(2)=5
mybyte(3)=1
'now I want to "append" to this byte array a string, how do we do it without a loop? OR we could build the string byte array first and then insert this in front...
ASKER
How does that unicode affect things? Which os uses which? From my tests(win95), assigning a string to a byte array doubles it which is not something I want(I know it recreates it properly, but we could be talking alot of loop cycles here)
It depends on your string and OS.
In general win95 uses 1 byte characters
and winnt uses 2 byte characters
In general win95 uses 1 byte characters
and winnt uses 2 byte characters
ASKER
are you sure you didn't get the two os' mixed up? I'm using win95 and my bytearrays were double the size of the string.
Hello Johnn,
Can you reject my answer please - it looks like Mirkwood is getting close to having a solution for you.
Can you reject my answer please - it looks like Mirkwood is getting close to having a solution for you.
ASKER
as requested, although neither is close yet...
>>How does that unicode affect things?
Unicode uses a word (16 bits = TWO bytes) for each character.
Unicode uses a word (16 bits = TWO bytes) for each character.
VB5 Internally uses unicode or at least 2-byte strings: See following code.
This code prefixes 4 bytes to an existing byte array. But to make sure I set sensible data I set the first two bytes to 65 and 0 (making up a capital A in unicode) and the second two bytes to 66 and 0 (making up a capital B)
Dim barTEST() As Byte
Dim barTEST2(1 To 4) As Byte
Dim strTEST1 As String
Dim strTEST2 As String
strTEST2 = "Hello"
barTEST = strTEST2
MsgBox barTEST
barTEST2(1) = 65
barTEST2(2) = 0
barTEST2(3) = 66
barTEST2(4) = 0
strTEST1 = barTEST2
strTEST2 = strTEST1 & strTEST2
barTEST = strTEST2
MsgBox barTEST
This code prefixes 4 bytes to an existing byte array. But to make sure I set sensible data I set the first two bytes to 65 and 0 (making up a capital A in unicode) and the second two bytes to 66 and 0 (making up a capital B)
Dim barTEST() As Byte
Dim barTEST2(1 To 4) As Byte
Dim strTEST1 As String
Dim strTEST2 As String
strTEST2 = "Hello"
barTEST = strTEST2
MsgBox barTEST
barTEST2(1) = 65
barTEST2(2) = 0
barTEST2(3) = 66
barTEST2(4) = 0
strTEST1 = barTEST2
strTEST2 = strTEST1 & strTEST2
barTEST = strTEST2
MsgBox barTEST
PS - I'm running Windows NT 4.0 + SP3
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
If you want it fast, and you don't need any Wide character, use this mapping:
1 character (2 bytes) <-> 1 byte
Using CopyMemory is >2x faster than copying array members.
Paste this to your form:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dest As Any, ByVal bytes As Long)
Dim myByte() As Byte
Private Sub Form_Click()
ReDim myByte(0 To 5) 'four byte long header info, aka length of string
myByte(0) = 1
myByte(1) = 1
myByte(2) = 5
myByte(3) = 5
myByte(4) = 7
myByte(5) = 7
'we could build the string byte array first and then insert this in front...
Dim mystring As String, mylen As Long, ub As Long
ub = UBound(myByte)
mystring = "A A"
mylen = Len(mystring)
ReDim Preserve myByte(0 To ub + mylen)
report
CopyMemory ByVal VarPtr(myByte(mylen)), ByVal VarPtr(myByte(0)), ub + 1
ZeroMemory ByVal VarPtr(myByte(0)), mylen
report
' insert string
CopyMemory myByte(0), ByVal mystring, mylen
report
End Sub
Private Sub report()
Dim i As Long, msg As String
For i = 0 To UBound(myByte)
msg = msg & myByte(i) & ","
Next
Debug.Print msg
End Sub
1 character (2 bytes) <-> 1 byte
Using CopyMemory is >2x faster than copying array members.
Paste this to your form:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dest As Any, ByVal bytes As Long)
Dim myByte() As Byte
Private Sub Form_Click()
ReDim myByte(0 To 5) 'four byte long header info, aka length of string
myByte(0) = 1
myByte(1) = 1
myByte(2) = 5
myByte(3) = 5
myByte(4) = 7
myByte(5) = 7
'we could build the string byte array first and then insert this in front...
Dim mystring As String, mylen As Long, ub As Long
ub = UBound(myByte)
mystring = "A A"
mylen = Len(mystring)
ReDim Preserve myByte(0 To ub + mylen)
report
CopyMemory ByVal VarPtr(myByte(mylen)), ByVal VarPtr(myByte(0)), ub + 1
ZeroMemory ByVal VarPtr(myByte(0)), mylen
report
' insert string
CopyMemory myByte(0), ByVal mystring, mylen
report
End Sub
Private Sub report()
Dim i As Long, msg As String
For i = 0 To UBound(myByte)
msg = msg & myByte(i) & ","
Next
Debug.Print msg
End Sub
ASKER
I see your invading my other thread! :) I'm looking into your solution...thanks
Johnn,
I'm a bit confused now. You've just accepted my answer but from your comments it looks like you're responding to ameba's comments.
I don't mind getting a few points but maybe in this case they should have gone to ameba? Or did you genuinely intend to accept my answer?
I'm a bit confused now. You've just accepted my answer but from your comments it looks like you're responding to ameba's comments.
I don't mind getting a few points but maybe in this case they should have gone to ameba? Or did you genuinely intend to accept my answer?
In VB6 you are allowed to assign the value of a byte array to a string and vice versa.
Simply move your byte array to a string, concatenate the 10 characters and move it back.