Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

uudecode Example

Part of TutorialAdvanced

Description

D port of Clem Dye's uudecode.c

Example

/*
 
UUDECODE - a Win32 utility to uudecode single files.

Copyright (C) 1998 Clem Dye

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Modified 13 July 2001 by Clem Dye to allow any character in the range 0 to 
7 in the 'begin' statement within the header of the uuencoded file being 
decoded.

Ported to D: J C Calvarese, 14 May 2004 

Updated by J C Calvarese, 15 Mar 2004
* Recompiled with DMD 0.116
* Retested with the attachment to digitalmars.D:19334 
 (http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=19334).


************* Instructions ************* 

Compile:
dmd uudecode.d

Usage:
uudecode.exe d4676.txt 

(where d4676.txt would be the input file)

The input file should start with something like this: "begin 0644 stlport.zip"
and end with "end".

*/

import std.stream;
import std.string;


char[] toStringFromChar(char c)

/*  
    based on code posted by Helmut Leitner (helmut.leitner@chello.at), 
    23 Oct 2003 at http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=18497 
*/

{
    char[] s = "?";
    s[0] = c;
    return s;
}


char DEC(char c)
{
    return (c - ' ') & 077;
}


char[] outname;


char[] uudecode (File f)
{
    int n;
    char ch;
    char[] buf, p;
    int pos;
    File outI = new File();
    
    
    do 
    {
          buf = f.readLine();
    }

    while (buf.length < 4 || buf[0..6] == "begin");
    pos = 6;
    
    while(pos != 0 && find(" 01234567", buf[pos..pos+1]) != -1) pos++;
    outname = buf[pos..buf.length];
    
    /* Create output file and set mode.  */ 
    outI.create(outname, FileMode.Out);
    
    /* For each input line:  */

    while(!f.eof)
    {
        buf = f.readLine();
        if (buf.length > 2 && buf[0..5] == "end") break;

        /* n is used to avoid writing out all the characters at the end of the file.  */

        pos = 0;

        n = DEC (buf[pos]);
        if (n <= 0)

        break;
        for (++pos; n > 0; /+ p += 4 +/ pos += 4, n -= 3)
        {
            p = buf[pos..buf.length];  
            if (n >= 3)
            {
                ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4; 
                outI.write(ch); //fputc(ch,outI);

                ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2; 
                outI.write(ch);  //fputc (ch,outI);
                ch = DEC (p[2]) << 6 | DEC (p[3]);
                outI.write(ch);  //fputc (ch,outI);

            }
            else
            {
                if (n >= 1)
                {
                    ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4; 
                    outI.write(ch);
                }
                if (n >= 2)
                {
                    ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2; 
                    outI.write(ch);
                }
            }
        }
    }
    outI.close();
    return outname;
}


int main(char[][] argv)
{
    File f;

    int argc = argv.length;
    debug for(int i; i<argv.length; i++)
    {
        printf("Argument %d: %.*s\n", i, argv[i]);
    }

    if (argc <= 1) {
            printf("Usage: %.*s <input file>\n", argv[0]); 
            return 1;
    }
    f = new File(argv[1]);

    uudecode(f);
    f.close();
    
    printf("Result decoded in %.*s\n", outname); 
    return 0;
}

Ideas for Future Enhancement

I'd be nice to have a D port that is licensed less restrictively than GPL (see the related links below). Then it could be used with any GUI library to create a GUI-based decoder.

Source

Revised from digitalmars.D:4744.