Announcement

Collapse
No announcement yet.

How to convert byte-array to string

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to convert byte-array to string

    LOCAL ByteArray() AS BYTE
    REDIM ByteArray(2)
    ByteArray(0) = &H31
    ByteArray(1) = &H32
    ByteArray(2) = &H33
    How to convert this byte-array to a string variable??

    PS: Without using CHR$.

    IN VB6
    We actually can do it easily.
    DIM ByteArray(2) AS BYTE
    ByteArray(0) = &H31
    ByteArray(1) = &H32
    ByteArray(2) = &H33
    Print ByteArray
    Print StrConv(ByteArray, 64)
    Last edited by Ivan Chan; 21 Mar 2008, 09:21 AM.

  • #2
    Two methods come to mind:

    1. Access the same data with a pointer...

    Code:
    Local pszText As Asciiz Ptr
    pszText = VarPtr(ByteArray(0))
    Note: you should terminate the byte array with a single NULL byte if you want to access the data.


    2. Copy the data to a string variable...

    Code:
    Local sText As String
    sText = Peek$(VarPtr(ByteArray(0)), UBOUND(ByteArray)+1)
    kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

    Comment


    • #3
      ...Or you could also use a union.

      Code:
      union myUnion
         byteData(3) as byte
        stringData as string * 3
      end union
      Software: Win XP Pro x64 SP2, PB/Win 8.04, PB/CC 4.04
      Hardware: AMD Athlon 64 3200+ (Clock speed 2.00 GHz) on a Gigabyte K8N Pro nForce3-150 mobo, 1 GB PC3200/DDR400 RAM, GeForce 7300 GT 256 MB DDR2 video

      Comment


      • #4
        Code:
        LOCAL ByteArray() AS BYTE
        local BytearrayPtr as DWORD
        REDIM ByteArray(2)
        ByteArray(0) = &H31
        ByteArray(1) = &H32
        ByteArray(2) = &H33
        BytearrayPtr = VARPTR(ByteArray(0))
        DIM Text as STRING * 3 at BytearrayPtr
        As you can see many ways to do it, I suspect all much faster than VB6 which probably converts to a varient in the process. Also PB has no equivalint to the Print statement of VB6 which as you used it prints to the current form (window) PB has specific methods depending on where you want the output. This means a programmer must think a little but the resultant reduction in code size and increase in speed are well worth it

        Comment


        • #5
          This is similar to above examples but slightly different:
          Code:
          #COMPILE EXE
          #DIM ALL
          
          FUNCTION PBMAIN () AS LONG
          
            LOCAL strConv AS STRING
          
            strConv = SPACE$(64)                          '64 byte long string
            REDIM ByteArray(2) AS BYTE AT STRPTR(strConv) 'overlap 3-byte array with string in memory
            ARRAY ASSIGN ByteArray() = &H31,&H32,&H33     'give byteArray() some values
          
            ? "|" & strConv & "|"                         'display result with end-post markers
          
          END FUNCTION

          Comment


          • #6
            Thanks! This works like MID
            Code:
            'ByteArray2String.bas
            #COMPILE EXE
            #DIM ALL
            DECLARE FUNCTION b2s(b AS BYTE, OPTIONAL BYVAL Length AS LONG) AS STRING
            FUNCTION PBMAIN () AS LONG
              LOCAL dummy AS LONG
              REDIM b(0 TO 26) AS BYTE     'alway dimension with LBOUND 0
              FOR dummy = 1 TO 26
                b(dummy) = dummy + 64
              NEXT
              ? b2s (b(4),2)               'DE  byte 4 for 2
              ? b2s (b(1))                 'entire string (no length passed)
              SLEEP 1000
            END FUNCTION
            FUNCTION b2s(MyData AS BYTE, OPTIONAL BYVAL length AS LONG) AS STRING
              LOCAL p AS ASCIIZ POINTER
              p = VARPTR(MyData)
              IF length THEN
                FUNCTION =PEEK$(p,length)  'length specified
              ELSE
                FUNCTION = @p              'no length, return entire string
              END IF
            END FUNCTION
            How long is an idea? Write it down.

            Comment


            • #7
              Code:
              FUNCTION = @p              'no length, return entire string
              You have to remember (as I mentioned) there is a possibility that will fail if the array data does not have NULL in the the last byte. Anything past the allocated array data is undefined, so it could cause a GPF if you read beyond that, which is what the above statement does. This is the reason many API functions also include a size parameter for the buffer.
              kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

              Comment


              • #8
                Could you use dim at?
                Roy Cline

                Comment


                • #9
                  Is passing a byte array MyData() without () valid?

                  Previous code passed MyData AS BYTE.
                  This passes MyData() as BYTE.
                  Is passing MyData AS BYTE even valid?
                  Anyway, haven't been able to break this with lots of error checking.

                  Code:
                  'ByteArray2String2.bas
                  #COMPILE EXE
                  #DIM ALL
                  DECLARE FUNCTION b2s(MyData() AS BYTE, StartByte AS LONG, OPTIONAL BYVAL length AS LONG) AS STRING
                  FUNCTION PBMAIN () AS LONG
                    LOCAL dummy&, NumberOfElements&,counter&
                    NumberOfElements = 26
                    REDIM arr(0 TO NumberOfElements-1) AS BYTE
                    counter = 64
                    FOR dummy = LBOUND(arr) TO UBOUND(arr)
                      INCR counter
                      arr(dummy) = counter
                    NEXT
                    ? "Test1:" +  b2s (arr(),0)            'A-Z
                    ? "Test2:" +  b2s (arr(),0,0)          'A-Z zero length passed returns all
                    ? "Test3:" +  b2s (arr(),LBOUND(arr))  'A-Z
                    ? "Test4:" +  b2s (arr(),0,1)          'A
                    ? "Test5:" +  b2s (arr(),0,2)          'AB
                    ? "Test6:" +  b2s (arr(),24,2)         'YZ"
                    ? "Test7:" +  b2s (arr(),25)           'Z
                    ? "Test8:" +  b2s (arr(),UBOUND(arr))  'Z
                   
                    ? "Now test errors:"
                   
                    ? "Test9:"   +  b2s (arr(),-1)          'start byte < LBOUND
                    ? "Test10:"   +  b2s (arr(),26)          'start byte > UBOUND
                    ? "Test11:"  +  b2s (arr(),0,-1)        'length < 0
                    ? "Test12:"  +  b2s (arr(),24,3)        'UBOUND exceeded
                    ? "Test13:"  +  b2s (arr(),-1,2)        'start byte < LBOUND
                   
                    #IF(%DEF(%PB_CC32))
                      ? "Press any key to exit";WAITKEY$
                    #ENDIF
                  END FUNCTION
                  FUNCTION b2s(MyData() AS BYTE, StartByte AS LONG,OPTIONAL BYVAL length AS LONG) AS STRING
                    %DEBUG = -1   '0 = do not return error message in return value
                   
                    LOCAL p AS ASCIIZ POINTER
                   
                    'Error checking with any array dimensions hopefully covered
                    IF StartByte < LBOUND(MyData) THEN
                      #IF %DEBUG
                        FUNCTION = "ERROR, StartByte < LBOUND"  'for testing only
                      #ENDIF
                       EXIT FUNCTION
                    ELSEIF StartByte > UBOUND(MyData) THEN
                      #IF %DEBUG
                        FUNCTION = "ERROR, StartByte > UBOUND"   'for testing only
                      #ENDIF
                       EXIT FUNCTION
                    ELSEIF Length < 0 THEN
                      #IF %DEBUG
                        FUNCTION = "ERROR, Length < 0"          'for testing only
                      #ENDIF
                      EXIT FUNCTION
                    ELSEIF StartByte + Length -1 > UBOUND(MyData) THEN
                      #IF %DEBUG
                        FUNCTION = "ERROR, StartByte + Length -1 > UBOUND"
                      #ENDIF
                      EXIT FUNCTION
                    END IF
                   
                    'calculate length of entire string
                    IF length = 0 THEN length = UBOUND(MyData)-StartByte + 1
                   
                    p = VARPTR(MyData(StartByte))               'pointer to first byte in array
                   
                    FUNCTION =PEEK$(p,length)
                  END FUNCTION
                  How long is an idea? Write it down.

                  Comment


                  • #10
                    No error checking.
                    Code:
                    FUNCTION b2s(MyData() AS BYTE, StartByte AS LONG,OPTIONAL BYVAL length AS LONG) AS STRING
                      LOCAL p AS ASCIIZ POINTER
                      IF length = 0 THEN length = UBOUND(MyData)-StartByte + 1
                      p = VARPTR(MyData(StartByte))
                      FUNCTION =PEEK$(p,length)
                    END FUNCTION
                    How long is an idea? Write it down.

                    Comment


                    • #11
                      I see passing a byte of the array is done if no () is specified.
                      Code:
                      DECLARE FUNCTION b2s(MyData AS BYTE) AS LONG
                      FUNCTION PBMAIN () AS LONG
                        LOCAL x AS LONG
                        REDIM test(0 TO 2) AS BYTE
                        test(1) = 65: test(2) = 66
                        FOR x = LBOUND(test) TO UBOUND(test)
                          ?  STR$(VARPTR(test(x)))
                          ?  STR$(b2s(test(x)))
                        NEXT
                        SLEEP 3000
                      END FUNCTION
                      FUNCTION b2s(MyData AS BYTE) AS LONG
                        FUNCTION = VARPTR(MyData)
                      END FUNCTION
                      How long is an idea? Write it down.

                      Comment


                      • #12
                        Found this whilst looking for something else.

                        It is a bit over the top compared with some of the above suggestions and for the problem posed but it will knock out a hex string as well as a binary copy; and others if you check out the SDK.

                        Code:
                        Declare Function CryptBinaryToString Lib "Crypt32.dll" Alias "CryptBinaryToStringA" _
                        ( Byte, ByVal Dword, ByVal Dword, Asciiz, Dword) As Long 
                        
                        %CRYPT_STRING_BINARY = 2 
                        %CRYPT_STRING_HEX = 4
                        
                        Function PBMain( ) As Long
                        
                          Local ByteArray() As Byte
                          ReDim ByteArray(2)
                          ByteArray(0) = &H31
                          ByteArray(1) = &H32
                          ByteArray(2) = &H33
                          
                          Local MyStr As Asciiz * 256 ' or whatever
                          Local datalen As Long
                          
                          CryptBinaryToString( ByteArray(0), 3, %CRYPT_STRING_BINARY, "", datalen ) ' "" -> datalen for next call
                          CryptBinaryToString( ByteArray(0), 3, %CRYPT_STRING_BINARY, MyStr, datalen )
                          
                          MsgBox MyStr
                          
                          CryptBinaryToString( ByteArray(0), 3, %CRYPT_STRING_HEX, "", datalen ) ' "" -> datalen for next call
                          CryptBinaryToString( ByteArray(0), 3, %CRYPT_STRING_HEX, MyStr, datalen )
                          
                          MsgBox Remove$(RTrim$(Mid$(MyStr, 2), $CrLf), " ")
                        
                        END FUNCTION
                        Last edited by David Roberts; 25 Mar 2008, 09:07 PM. Reason: Added Remove$

                        Comment

                        Working...
                        X