Random MAVs

BlitzMax Forums/BlitzMax Programming/Random MAVs

Hi,

I tried the base64 encoder from the code archives ( http://www.blitzmax.com/codearcs/codearcs.php?code=1724 ), and it throws random errors. But I can't find any error in the code. More details in the archives entry.

Today I got another random bug when calling EndGraphics and the debugger pointed me to a line in glgraphics mod that does nothing big (setting an integer, so there can't go anything wrong). Maybe this is a 1.28 problem, I never got weird errors like this before.

Even if I run in debugmode from within the IDE all I get is an unnamed "Memory access violation", no more details :(

Anyone else getting such weird random errors?

Jake

This means you're passing an incorrect buffer size or that you're just not passing a buffer, but some random memory location that does not correspond to what you're trying to encode. Check to make sure you're passing correct data and the correct size to the encoder.

I thought the same until I wrote a little test app. I can't see anything wrong with this:

Const etable$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Global dtable@[256]
For Local __di:Int = 0 To etable.Length-1
    dtable[etable[__di]] = __di
Next

for local i%=0 to 20000
	print "try to encode, run #"+i
	TryEncode()
Next
end

function TryEncode()
	local buf:Byte[]=New Byte[4096]
	local s$=EncodeBase64 (buf,sizeof(buf))		

end function

Function EncodeBase64$( in@ Ptr, sizein:Int )
    If sizein <= 0 Then Return Null
    Local out:Byte[64]
    Local s$
    
    Local p@ Ptr = out
    Local cc% = 0
    
    For Local i% = 0 To sizein-1 Step 3
        Local c1@, c2@
        c1 = in[i]&$FF
        c2 = in[i+1]&$FF
        
        p[0] = etable[in[0] Shr 2]
        If i+1 < sizein Then
            p[1] = etable[((in[0] & $3) Shl 4) | ((in[1] & $F0) Shr 4)]
            If i+2 < sizein Then
                p[2] = etable[((in[1] & $F) Shl 2) | ((in[2] & $C0) Shr 6)]
                p[3] = etable[in[2] & $3F]
            ElseIf i+1 < sizein Then
                p[2] = etable[((in[1] & $F) Shl 2)]
            EndIf
        Else
            p[1] = etable[((in[0] & $3) Shl 4)]
        EndIf
        
        in :+ 3
        p :+ 4
        cc :+ 4
        If cc = 64 Then
            s :+ String.FromBytes(out,cc)
            p = out
            cc = 0
        EndIf
    Next
    Select sizein Mod 3
        Case 0
            s :+ String.FromBytes(out, cc)
        Case 1
            s :+ String.FromBytes(out, cc-2)+"=="
        Case 2
            s :+ String.FromBytes(out, cc-1)+"="
    End Select
    Return s
End Function

' Assumes you're passing a valid string to it
Function DecodeBase64:Byte[]( in$ )
    Local f% = in.Find("=")
    in = in.Replace("=","~0")
    Local rm% = 0
    If f = -1 Then
        rm = 0
        f = in.Length-1
    ElseIf f = in.Length-1 Then
        rm = 1
    ElseIf f = in.Length-2 Then
        rm = 2
    EndIf
    Local out@[((in.Length/4)*3)-rm]
    Local p@ Ptr = out
    Local bc% = 0
    For Local cc:Int = 0 To f Step 4
        p[0] = (dtable[in[cc]] Shl 2) | (dtable[in[cc+1]] Shr 4)
        If out.Length > (bc+1) Then p[1] = ((dtable[in[cc+1]] & $F) Shl 4) | ((dtable[in[cc+2]]&$3C) Shr 2)
        If out.Length > (bc+2) Then p[2] = ((dtable[in[cc+2]] & $3) Shl 6) | dtable[in[cc+3]]
        bc :+ 3
        p :+ 3
    Next
    Return out
End Function 


Actually, looking over the code again, that's absolutely horrible what I wrote. I guess that's another lesson to not do things at 3am. I'll see about rewriting this. My fault here.

Right in time Brucey did it again and made a Base64 class. Horray!

Does it work okay?

I only gave it some limited testing.

Works like a charm, as all your modules do!

Nice, the less work I have to do, the better.