Does MBS have UUEncode/Decode?

I’m in the process of migrating away from the Einhugur E-Crypt plugin and UUEncode/Decode is the last function is need. The shell has functions for doing uu, but I’d like to do this in memory and not file based if possible.

Sorry, no.

Old VB code for the conversion… shouldn’t be that hard to port over to Xojo:

[code] Public Class UUCodec
Public Function uuDecode(ByVal encodedString As String) As String
Dim decodedstring As String
Dim x As Long = encodedString.Length
Dim i As Long
Dim char1 As Double
Dim char2 As Double

        For i = 1 To x Step 4
            char1 = Asc(encodedString.Substring(i - 1, 1))
            char2 = Asc(encodedString.Substring(i, 1))
            If char1 = 96 Then char1 = 32
            If char2 = 96 Then char2 = 32
            decodedstring = decodedstring & Chr(((char1 - 32) * 4) + (Convert.ToInt16((char2 - 32) \\ 16)))
            char1 = Asc(encodedString.Substring(i, 1))
            char2 = Asc(encodedString.Substring(i + 1, 1))
            If char1 = 96 Then char1 = 32
            If char2 = 96 Then char2 = 32
            decodedstring = String.Concat(decodedstring, Chr(((char1 Mod 16) * 16) + (char2 - 32) \\ 4))
            char1 = Asc(encodedString.Substring(i + 1, 1))
            char2 = Asc(encodedString.Substring(i + 2, 1))
            If char1 = 96 Then char1 = 32
            If char2 = 96 Then char2 = 32
            decodedstring = String.Concat(decodedstring, Chr(((char1 Mod 4) * 64) + (char2 - 32)))
        Next
 
        Return decodedstring
    End Function
 
    Public Function uuEncode(ByVal decodedString As String) As String
        Dim encodedstring As String
        Dim x As Long = decodedString.Length
        Dim i As Long
        Dim char1 As Double
        Dim char2 As Double
 
        If x Mod 3 <> 0 Then
            Dim temp As String = New String(Chr(0), 3 - x Mod 3)
            encodedstring = String.Concat(encodedstring, temp)
        End If
 
        For i = 1 To x Step 3
            char1 = Asc(decodedString.Substring(i - 1, 1))
            If char1 = 96 Then char1 = 32
            encodedstring = String.Concat(encodedstring, Chr(char1 \\ 4 + 32))
            char1 = Asc(decodedString.Substring(i - 1, 1))
            char2 = Asc(decodedString.Substring(i, 1))
            If char1 = 96 Then char1 = 32
            If char2 = 96 Then char2 = 32
            encodedstring = String.Concat(encodedstring, Chr((((char1 Mod 4) * 16)) + (char2 \\ 16 + 32)))
            char1 = Asc(decodedString.Substring(i, 1))
            char2 = Asc(decodedString.Substring(i + 1, 1))
            If char1 = 96 Then char1 = 32
            If char2 = 96 Then char2 = 32
            encodedstring = String.Concat(encodedstring, Chr((((char1 Mod 16) * 4)) + (char2 \\ 64 + 32)))
            char1 = Asc(decodedString.Substring(i + 1, 1))
            If char1 = 96 Then char1 = 32
            encodedstring = String.Concat(encodedstring, Chr((((char1 Mod 64) + 32))))
        Next
        Return encodedstring
    End Function
End Class[/code]

I don’t know, but Bjorn just posted the announcement that the 64 bit version of eCrypt is available, and it lists UUencode…

@Eric: thanks, looks good.

@Michel: I know, so it’s not urgent. But I’m migrating away from Einhugur completely.

If you’re on Linux or OS X, you can always pass things off to the command line tools. The entire UUCP toolset is included on both platforms.

I could add uuencode…

Bored
Wrote uuencode & uudecode in Xojo
uudecode from the OS X command line will decode what xojo encodes
& Xojo will decode what uuencode from the cmd line encodes

so they seem to be correct

http://www.great-white-software.com/REALbasic_Code.html

and if speed is needed, we have UUEncodeMBS and UUDecodeMBS in next plugins :slight_smile:

third christmas day can be really boring.

@Norman: we all have different things to be bored by. I said in the first post that I know about command line. Using this for stuff that is supposed to be in memory is annoying.

@Christan: thanks!

The code Eric posted seems simple enough to adapt.

I think I may actually port that over today… or attempt to, using xojo.core.memoryBlock instead of string. I’ll let you know when I get it done… assuming you haven’t started already (I know you like these challenges too, Michel).

Go ahead. I am battling Mailgun SMTP at the moment :slight_smile:

From what I see, it should be almost copy/paste for string.

[quote=238049:@Beatrix Willius]@Norman: we all have different things to be bored by. I said in the first post that I know about command line. Using this for stuff that is supposed to be in memory is annoying.
[/quote]
The code I wrote IS all in memory and free and you can tweak whatever you want
Heck the original source code for uuencode & decode is widely available in C
Apple even posts theirs as its all BSD code
http://www.opensource.apple.com/source/basic_cmds/basic_cmds-51/uuencode/uuencode.c
http://www.opensource.apple.com/source/basic_cmds/basic_cmds-51/uudecode/uudecode.c

thats the entire source for the command line apps :stuck_out_tongue:

@Norman: C is yuck. That’s the language that I tried to learn a few times before Realbasic and every time my brain gave up on the * thing. That was always clear in theory and totally incomprehensible in practice.

PS: Why do I always write your name with an L at the end?

Just saying that the code to do uuencode & uudecode is pretty simple
In C its very simple - but I didn’t even “port” the C code
I just read the wikipedia explanation and wrote my code accordingly

I wrote that in as clear a fashion as I could - not for speed
I’m sure it could be sped up a lot as it currently exists

And this way you have all the source so if there is something wrong with it you can debug it

Haven’t completely tested this; however, initial runs seem to suggest it’s pretty accurate. Feel free to optimize it, distribute it, etc. Something I put together pretty quickly… enjoy.

To use (with text)… no conversions necessary if using xojo.core.memoryBlock:

[code] dim decodedText as text
dim encodedText as text

decodedText = “this is a test”

encodedText = xojo.core.textEncoding.utf8.convertDataToText( _
uuEncode( _
xojo.core.textEncoding.utf8.convertTextToData( _
decodedText)))

decodedText = xojo.core.textEncoding.utf8.convertDataToText( _
uuDecode( _
xojo.core.textEncoding.utf8.convertTextToData( _
encodedText)))

// - console output (using a console application)
stdOut.writeLine(encodedText)
stdOut.writeLine("")
stdOut.writeLine(decodedText)[/code]

[code]Function uuEncode(decodedContent as xojo.core.memoryBlock) As xojo.core.memoryBlock

const BLOCK_SIZE = 45 ’ standard block size for uuencode compatibility (in bytes)
const EOF = 96 ’ eof indicator for standard uuencode compatibility

dim lastBlock as boolean
dim encodedByte(3) as byte
dim padByte(0) as byte
dim footer(0) as byte
dim header(0) as byte
dim originalSize as int32
dim loopIndex as int32
dim workSize as int32
dim workBlock as new xojo.core.mutableMemoryBlock(decodedContent)
dim encodedContent as new xojo.core.mutableMemoryBlock(0)

try

padByte(0) = 0   ' pad byte for content lengths that are not mod 3
footer(0)  = EOF ' footer byte for standard uuencode compatibility

// - pad {workBlock} if necessary to length conforming to mod 3 using {padByte}
for loopIndex = 1 to (workBlock.size mod 3)
  
  workBlock.append(padByte)
  
next loopIndex

originalSize = decodedContent.size ' original length of {decodedContent} without padding appended
workSize     = workBlock.size      ' revised length of {decodedContent} with padding appended

// - uuencode {workBlock} to {encodedContent}
for loopIndex = 1 to workSize step 3
  
  // - handle of standard uuencode compatibility blocks with header bytes
  if originalSize >= BLOCK_SIZE then
    
    if loopIndex <= originalSize - (originalSize mod BLOCK_SIZE) then
      
      if (loopIndex = 1) or ((loopIndex - 1) mod BLOCK_SIZE = 0) then
        
        header(0) = BLOCK_SIZE + 32
        
        encodedContent.append(header)
        
      end if
      
    else
      
      if not lastBlock then
        
        header(0) = ((originalSize - loopIndex) + 1) + 32
        
        encodedContent.append(header)
        
        lastBlock = true
        
      end if
      
    end if
    
  else
    
    if not lastBlock then
      
      header(0) = originalSize + 32
      
      encodedContent.append(header)
      
      lastBlock = true
      
    end if
    
  end if
  
  encodedByte(0) = ((workBlock.int8Value(loopIndex - 1) \\ 4) + 32)
  encodedByte(1) = ((workBlock.int8Value(loopIndex - 1) mod 4) * 16) + ((workBlock.int8Value(loopIndex) \\ 16) + 32)
  encodedByte(2) = ((workBlock.int8Value(loopIndex) mod 16) * 4) + ((workBlock.int8Value(loopIndex + 1) \\ 64) + 32)
  encodedByte(3) = ((workBlock.int8Value(loopIndex + 1) mod 64) + 32)
  
  if encodedByte(0) = 32 then encodedByte(0) = 96
  if encodedByte(1) = 32 then encodedByte(1) = 96
  if encodedByte(2) = 32 then encodedByte(2) = 96
  if encodedByte(3) = 32 then encodedByte(3) = 96
  
  encodedContent.append(encodedByte)
  
next loopIndex

encodedContent.append(footer)

return encodedContent

catch

return nil

end try

End Function[/code]

[code]Function uuDecode(encodedContent as xojo.core.memoryBlock) As xojo.core.memoryBlock

dim decodedByte(2) as byte
dim header as byte
dim padByte(0) as byte
dim originalSize as int32
dim loopIndex as int32
dim workBlock as new xojo.core.mutableMemoryBlock(0)
dim decodedContent as new xojo.core.mutableMemoryBlock(0)

try

originalSize = encodedContent.size ' original length of {encodedContent} without padding appended

do until loopIndex >= originalSize - 4
  
  header = encodedContent.int8Value(loopIndex) - 32
  
  workBlock.append(encodedContent.mid(loopIndex + 1, xojo.math.ceil(header * 1.333)))
  
  loopIndex = loopIndex + xojo.math.ceil(header * 1.333) + 1
  
loop

padByte(0) = 96 ' pad byte for content lengths that are not mod 4

for loopIndex = 1 to (workBlock.size mod 4)
  
  workBlock.append(padByte)
  
next loopIndex

// - uudecode {encodedContent} to {decodedContent}
for loopIndex = 1 to workBlock.size step 4
  
  if workBlock.int8Value(loopIndex - 1) = 96 then workBLock.int8Value(loopIndex - 1) = 32
  if workBlock.int8Value(loopIndex)     = 96 then workBLock.int8Value(loopIndex)     = 32
  if workBlock.int8Value(loopIndex + 1) = 96 then workBLock.int8Value(loopIndex + 1) = 32
  if workBlock.int8Value(loopIndex + 2) = 96 then workBLock.int8Value(loopIndex + 2) = 32
  
  decodedByte(0) = ((workBlock.int8Value(loopIndex - 1) - 32) * 4) + ((workBlock.int8Value(loopIndex) - 32) \\ 16)
  decodedByte(1) = ((workBlock.int8Value(loopIndex) mod 16) * 16) + ((workBlock.int8Value(loopIndex + 1) - 32) \\ 4)
  decodedByte(2) = ((workBlock.int8Value(loopIndex + 1) mod 4) * 64) + (workBlock.int8Value(loopIndex + 2) - 32)
  
  decodedContent.append(decodedByte)
  
next loopIndex

return decodedContent

catch

return nil

end try

End Function[/code]

Test sites:

http://www.textencode.com/encoder/uuencodeEncoder
http://www.textencode.com/decoder/uudecodeDecoder

What I provided converts text and memoryBlocks only. If you want to convert files, you need to include the format for the following as provided here:

https://www.mkssoftware.com/docs/man4/uuencode.4.asp

Which includes:

begin mode pathname
lines of encoded text
.
.
.

end

The output lines need to be wrapped at a maximum length of 62 characters also (also explained at the page I linked). All of that should be EASILY achievable with the data returned by these functions.

Bravo Eric. And thank you :slight_smile:

you could try it against the one in my plugin.

Christian can I hire you to lead our sales organization??? :slight_smile: