/***************************************************************************
 *   copyright           : (C) 2004 by Hendrik Sattler                     *
 *   mail                : post@hendrik-sattler.de                         *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "versit.h"

#include "helper.h"

#include <string.h>
#include <stdio.h>

int is_eightbit (uint8_t* s) {
  if (s != NULL)
    while (*s != 0) {
      if (*s > 0x7F) return 1;
      ++s;
    }
  return 0;
}

const char* base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* encoding_string[4] = {
  "7BIT",
  "8BIT",
  "QUOTED-PRINTABLE",
  "BASE64",
};


unsigned char* encode_chars (enum encoding_value enc,
			     unsigned char* input)
{
  unsigned char* retval;
  size_t i = 0;
  size_t len = str_len((char*)input);
  unsigned int base = 0;

  switch (enc) {
  case ENC_SEVENBIT:
    retval = (unsigned char*)str_dup((char*)input);
    for (; i < str_len((char*)retval); ++i) {
      if (retval[i] >= 0x80) retval[i] = ' ';
    }
    return retval;
  case ENC_EIGHTBIT:
    return (unsigned char*)str_dup((char*)input);
  case ENC_QUOTEDPRINTABLE:
    //quoted printable as described in RFC 2045, chapter 6.7
    retval = mem_alloc((len*3)+1,1);
    while (*input != 0) {
      if ((33 <= *input && *input <= 60) ||
	  (62 <= *input && *input <= 126) ||
	  ((*input == 9 || *input == 32) && *(input+1) != 0)) {
	retval[i] = *input;
	++i;
      } else {
	sprintf((char*)retval+i,"=%02X",*input);
	i += 3;
      }
      ++input;
    }
    return retval;
  case ENC_BASE64:
    retval = mem_alloc(((len-(len%3)+3)*4)+1,1);
    for (i = 0; i < len; i += 3) {
      retval[base++] = base64[(input[i]>>2)&63];
      retval[base++] = base64[((input[i]<<4)+((input[i+1]>>4)&15))&63];
      if (i+1 < len)
	retval[base++] = base64[((input[i+1]<<2)+((input[i+2]>>6)&3))&63];
      else
	retval[base++] = '=';
      if (i+2 < len)
	retval[base++] = base64[input[i+2]&63];
      else
	retval[base++] = '=';
    }
    return retval;
  default:
    return NULL;
  }
}
