home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Python 1.1 / Lib / uu.py < prev    next >
Encoding:
Text File  |  1994-09-09  |  6.1 KB  |  215 lines  |  [TEXT/R*ch]

  1. # uu.py
  2. # Copyright 1994 by Lance Ellinghouse
  3. # Cathedral City, California Republic, United States of America.
  4. #                        All Rights Reserved
  5. # Permission to use, copy, modify, and distribute this software and its 
  6. # documentation for any purpose and without fee is hereby granted, 
  7. # provided that the above copyright notice appear in all copies and that
  8. # both that copyright notice and this permission notice appear in 
  9. # supporting documentation, and that the name of Lance Ellinghouse
  10. # not be used in advertising or publicity pertaining to distribution 
  11. # of the software without specific, written prior permission.
  12. # LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
  13. # THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  14. # FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
  15. # FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  18. # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19.  
  20. # This file implements the UUencode and UUdecode functions.
  21.  
  22. # encode(filename, mode, in_file, out_file)
  23. # decode(filename, mode, in_file)
  24. # decode(in_file, out_file)
  25. # decode(in_file)
  26.  
  27. # encode a single char to always be printable
  28. def _ENC(ch):
  29.     if type(ch) == type(''):
  30.     a = ch[:1] # only 1 char
  31.     if len(a) == 0:
  32.         raise ValueError, 'need to pass in at least 1 char'
  33.     a = ord(a)
  34.     elif type(ch) == type(0):
  35.     a = ch
  36.     else:
  37.     raise TypeError, 'must pass in an integer or single character'
  38.     return chr((a & 077) + ord(' '))
  39.  
  40. # input 3 chars, output 4 encoded chars
  41. def _outenc(str):
  42.     if len(str) > 3:
  43.     raise ValueError, 'can only accept strings of 3 chars'
  44.     p0, p1, p2 = 0, 0, 0
  45.     if len(str) > 2:
  46.     p2 = ord(str[2])
  47.     if len(str) > 1:
  48.     p1 = ord(str[1])
  49.     if len(str) > 0:
  50.     p0 = ord(str[0])
  51.     c1 = p0 >> 2
  52.     c2 = (p0 << 4) & 060 | (p1 >> 4) & 017
  53.     c3 = (p1 << 2) & 074 | (p2 >> 6) & 03
  54.     c4 = p2 & 077
  55.     rtn = _ENC(c1)
  56.     rtn = rtn + _ENC(c2)
  57.     rtn = rtn + _ENC(c3)
  58.     rtn = rtn + _ENC(c4)
  59.     return rtn
  60.  
  61. # pass in 45 bytes max, returns 62 bytes encoded
  62. def _encode(str):
  63.     if len(str) > 45:
  64.     raise ValueError, 'cannot handle more than 45 chars at once'
  65.     length = len(str)
  66.     rtn = _ENC(length)
  67.     i = 0
  68.     while i < length:
  69.     rtn = rtn + _outenc(str[i:(i+3)])
  70.     i = i + 3
  71.     rtn = rtn + '\n'
  72.     return rtn
  73.     
  74. # encode a fileobject and write out to a file object
  75. def encode(filename, mode, in_file, out_file):
  76.     out_file.write('begin %o %s\n' % ((mode&0777),filename))
  77.     str = in_file.read(45)
  78.     while len(str) > 0:
  79.     out_file.write(_encode(str))
  80.     str = in_file.read(45)
  81.     out_file.write(' \nend\n')
  82.     return None
  83.  
  84. # def decode a single char from printable to possibly non-printable
  85. def _DEC(ch):
  86.     if type(ch) != type('') or len(ch) != 1:
  87.     raise ValueError, 'need to pass in a single char'
  88.     a = ord(ch[0:1])
  89.     return (a - ord(' '))
  90.  
  91. # input 4 chars encoded, output 3 chars unencoded
  92. def _outdec(str):
  93.     if len(str) > 4:
  94.     raise ValueError, 'can only accept strings of 4 chars'
  95.     p0, p1, p2, p3 = 0, 0, 0, 0
  96.     if len(str) > 3:
  97.     p3 = _DEC(str[3])
  98.     if len(str) > 2:
  99.     p2 = _DEC(str[2])
  100.     if len(str) > 1:
  101.     p1 = _DEC(str[1])
  102.     if len(str) > 0:
  103.     p0 = _DEC(str[0])
  104.     c1 = p0 << 2 | (p1 & 060) >> 4
  105.     c2 = (p1 & 017) << 4 | (p2 & 074) >> 2
  106.     c3 = (p2 & 03) << 6 | (p3 & 077)
  107.     rtn = chr(c1)
  108.     rtn = rtn + chr(c2)
  109.     rtn = rtn + chr(c3)
  110.     return rtn
  111.  
  112. # pass in 62 bytes and return 45 bytes unencoded
  113. def _decode(str):
  114.     if len(str) > 62:
  115.     raise ValueError, 'cannot handle more than 62 chars at once'
  116.     length = _DEC(str[0])
  117.     i = 1
  118.     rtn = ''
  119.     while len(rtn) < length:
  120.     rtn = rtn + _outdec(str[i:(i+4)])
  121.     i = i + 4
  122.     return rtn[0:length]
  123.  
  124. # decode(filename, mode, in_file)
  125. # decode(in_file, out_file)
  126. # decode(in_file)
  127. def decode(*args):
  128.     ok = 1
  129.     _setup = None
  130.     out_file = None
  131.     if len(args) == 3:
  132.     filename, mode, in_file = args
  133.     if type(filename) != type(''):
  134.         ok = 0
  135.     if type(mode) != type(0):
  136.         ok = 0
  137.     try:
  138.         _ = getattr(in_file,'readline')
  139.     except AttributeError:
  140.         ok = 0
  141.     def _setup(out_file,args):
  142.         filename, mode, in_file = args
  143.         # open file as specified and assign out_file for later use
  144.         out_file = open(filename,'w',mode)
  145.         _out_file_orig = 0
  146.         _ = in_file.readline()
  147.         return (out_file,_out_file_orig)
  148.     elif len(args) == 2:
  149.     in_file, out_file = args
  150.     try:
  151.         _ = getattr(in_file,'readline')
  152.         _ = getattr(out_file,'write')
  153.     except AttributeError:
  154.         ok = 0
  155.     def _setup(out_file, args):
  156.         in_file, out_file = args
  157.         # Toss the 'begin mode filename' part.. not needed
  158.         _ = in_file.readline()
  159.         _out_file_orig = 1
  160.         return (out_file,_out_file_orig)
  161.     elif len(args) == 1:
  162.     in_file = args[0]
  163.     try:
  164.         _ = getattr(in_file,'readline')
  165.     except AttributeError:
  166.         ok = 0
  167.     def _setup(out_file, args):
  168.         import strop
  169.         in_file = args[0]
  170.         # open file as specified in uu file and 
  171.         # assign out_file for later use
  172.         i = in_file.readline()
  173.         i = strop.strip(i)
  174.         if 'begin' != i[:5]:
  175.         raise IOError, 'input file not in UUencoded format'
  176.         [dummy, mode, filename] = strop.split(i)
  177.         mode = strop.atoi(mode, 8)
  178.         out_file = open(filename,'w',mode)
  179.         _out_file_orig = 0
  180.         return (out_file,_out_file_orig)
  181.     if ok != 1:
  182.     raise SyntaxError, 'must be (filename, mode, in_file) or (in_file,out_file) or (in_file)'
  183.     out_file, _out_file_orig = _setup(out_file, args)
  184.     str = in_file.readline()
  185.     while len(str) > 0 and str != ' \n' and str != 'end\n':
  186.     out_file.write(_decode(str))
  187.     str = in_file.readline()
  188.     if _out_file_orig == 0:
  189.     out_file.close()
  190.     del out_file
  191.     return None
  192.  
  193. def test():
  194.     import sys
  195.     if sys.argv[1:2] == ['-d']:
  196.     if sys.argv[2:]:
  197.         decode(open(sys.argv[2]), sys.stdout)
  198.     else:
  199.         decode(sys.stdin, sys.stdout)
  200.     elif sys.argv[1:2] == ['-e']:
  201.     if sys.argv[2:]:
  202.         file = sys.argv[2]
  203.         fp = open(file)
  204.     else:
  205.         file = '-'
  206.         fp = sys.stdin
  207.     encode(file, 0644, fp, sys.stdout)
  208.     else:
  209.     print 'usage: uu -d [file]; (to decode)'
  210.     print 'or:    uu -e [file]; (to encode)'
  211.     sys.exit(2)
  212.  
  213. if __name__ == '__main__':
  214.     test()
  215.