/* --------------------------------------------------------------- */
/* base64 -- encode a string to Base64                             */
/* --------------------------------------------------------------- */
/*                                                                 */
/* Copyright (c) Mike Cowlishaw, 1993-2012.  All rights reserved.  */
/* Parts Copyright (c) IBM, 1993-2009.                             */
/*                                                                 */
/* Permission to use, copy, modify, and distribute this software   */
/* for any non-commercial purpose without fee is hereby granted,   */
/* provided that the above copyright notice and this permission    */
/* notice appear in all copies, and that notice and the date of    */
/* any modifications be added to the software.                     */
/*                                                                 */
/* This software is provided "as is".  No warranties, whether      */
/* express, implied, or statutory, including, but not limited to,  */
/* implied warranties of merchantability and fitness for a         */
/* particular purpose apply to this software.  The author shall    */
/* not, in any circumstances, be liable for special, incidental,   */
/* or consequential damages, for any reason whatsoever.            */
/*                                                                 */
/* --------------------------------------------------------------- */
/* Argument is string to encode                                    */
/* Returns encoded string                                          */
/*                                                                 */
/* This is a raw encode; there is no chopping into segments for    */
/* MIME.                                                           */
/* --------------------------------------------------------------- */

alpha64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef',
      ||'ghijklmnopqrstuvwxyz0123456789+/'

parse arg data

out=''

len=length(data)
do in=1 to len by 3                -- 3 chars -> 4

  seg=substr(data, in, 3, '00'x)   -- 3 chars, padded if need be

  bits=x2b(c2x(seg))               -- 24 1s &/| 0s

  six=substr(bits,  1, 6)          -- six bits
  dec=x2d(b2x(six))+1              -- -> decimal
  out=out||substr(alpha64, dec, 1) -- add

  six=substr(bits,  7, 6)
  dec=x2d(b2x(six))+1
  out=out||substr(alpha64, dec, 1)
  six=substr(bits, 13, 6)
  dec=x2d(b2x(six))+1
  out=out||substr(alpha64, dec, 1)
  six=substr(bits, 19, 6)
  dec=x2d(b2x(six))+1
  out=out||substr(alpha64, dec, 1)

  end in

-- patch up ending now
over=3-(len//3)
olen=length(out)
if over\=3 then out=overlay('==', out, olen-over+1, over)
-- say out

return out