' Pack/unpack binary data with string-buffer manipulation
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL buf AS STRING
    LOCAL magic AS STRING
    LOCAL name AS STRING
    LOCAL ver AS LONG
    LOCAL fl AS LONG
    LOCAL sz AS LONG
    LOCAL chk AS LONG
    LOCAL id AS LONG
    LOCAL score AS LONG
    LOCAL act AS LONG
    LOCAL i AS LONG
    LOCAL b0 AS LONG
    LOCAL b1 AS LONG
    LOCAL b2 AS LONG
    LOCAL b3 AS LONG
    LOCAL tmpBuf AS STRING

    PRINT "=== Packed Binary Structures ==="
    PRINT

    buf = LEFT$("PBXB" & SPACE$(4), 4)
    b0 = 100 MOD 256
    b1 = (100 / 256) MOD 256
    buf = buf & CHR$(b0) & CHR$(b1)
    b0 = 3 MOD 256
    b1 = (3 / 256) MOD 256
    buf = buf & CHR$(b0) & CHR$(b1)
    b0 = 1024 MOD 256
    b1 = (1024 / 256) MOD 256
    b2 = (1024 / 65536) MOD 256
    b3 = (1024 / 16777216) MOD 256
    buf = buf & CHR$(b0) & CHR$(b1) & CHR$(b2) & CHR$(b3)
    buf = buf & CHR$(0) & CHR$(0) & CHR$(0) & CHR$(0)

    PRINT "Packed header (" & FORMAT$(LEN(buf)) & " bytes):"
    FOR i = 1 TO LEN(buf)
        PRINT RIGHT$("0" & HEX$(ASC(MID$(buf, i))), 2)
    NEXT i
    PRINT

    IF LEN(buf) >= 12 THEN
        magic = MID$(buf, 1, 4)
        ver = ASC(MID$(buf, 5, 1)) + ASC(MID$(buf, 6, 1)) * 256
        fl = ASC(MID$(buf, 7, 1)) + ASC(MID$(buf, 8, 1)) * 256
        b0 = ASC(MID$(buf, 9, 1))
        b1 = ASC(MID$(buf, 10, 1))
        b2 = ASC(MID$(buf, 11, 1))
        b3 = ASC(MID$(buf, 12, 1))
        sz = b0 + b1 * 256 + b2 * 65536 + b3 * 16777216
    END IF
    PRINT "  Magic: " & TRIM$(magic)
    PRINT "  Version: " & FORMAT$(ver)
    PRINT "  Flags: " & FORMAT$(fl)
    PRINT "  DataSize: " & FORMAT$(sz)
    PRINT

    buf = ""
    id = 42
    b0 = id MOD 256
    b1 = (id / 256) MOD 256
    b2 = (id / 65536) MOD 256
    b3 = (id / 16777216) MOD 256
    buf = buf & CHR$(b0) & CHR$(b1) & CHR$(b2) & CHR$(b3)
    buf = buf & LEFT$("Alice" & SPACE$(16), 16)
    score = 95
    b0 = score MOD 256
    b1 = (score / 256) MOD 256
    b2 = (score / 65536) MOD 256
    b3 = (score / 16777216) MOD 256
    buf = buf & CHR$(b0) & CHR$(b1) & CHR$(b2) & CHR$(b3)
    buf = buf & CHR$(1)

    PRINT "Packed record (" & FORMAT$(LEN(buf)) & " bytes)"
    FOR i = 1 TO 12
        PRINT RIGHT$("0" & HEX$(ASC(MID$(buf, i))), 2) & " "
    NEXT i
    PRINT "..."
    PRINT

    b0 = ASC(MID$(buf, 1, 1))
    b1 = ASC(MID$(buf, 2, 1))
    b2 = ASC(MID$(buf, 3, 1))
    b3 = ASC(MID$(buf, 4, 1))
    id = b0 + b1 * 256 + b2 * 65536 + b3 * 16777216
    name = TRIM$(MID$(buf, 5, 16))
    b0 = ASC(MID$(buf, 21, 1))
    b1 = ASC(MID$(buf, 22, 1))
    b2 = ASC(MID$(buf, 23, 1))
    b3 = ASC(MID$(buf, 24, 1))
    score = b0 + b1 * 256 + b2 * 65536 + b3 * 16777216
    act = ASC(MID$(buf, 25, 1))
    PRINT "  ID: " & FORMAT$(id)
    PRINT "  Name: " & name
    PRINT "  Score: " & FORMAT$(score)
    PRINT "  Active: " & FORMAT$(act)
    PRINT

    PRINT "Packed struct tests complete."
    FUNCTION = 0
END FUNCTION
