#include <stdio.h>
#include "line.h"
#include "qp.h"

unsigned char qp_atoh(unsigned char);
unsigned char qp_hex2asc(unsigned char, unsigned char);

int qp_decode(line_t *l, char *str)
{
  unsigned char c = 0;
  unsigned long bytes = 0;
  char *h = NULL, *t = NULL;

  t = NULL;
  bytes = 0;

  for (h = str; *h;) {
      if (*h == '=') {
         if (t)
            line_inject(l, t, bytes);

         t = (h + 1);

         /*
            Require at least *one* byte after the equal
            sign (even though we should require two).
         */
         if (!(*(h + 1)))
            return 0;

         /*
            Wrap?
         */
         if ((*(h + 1) == '\n') || (*(h + 1) == '\r')) {

            /*
               Hope clients encode correctly...
            */
            if ((*(h + 2) == '\n') || (*(h + 2) == '\r'))
               h += 3;

            /*
               ..but if they dont, we'll hafta accept that.
            */
            else
               h += 2;

            t = NULL;
            bytes = 0;
            continue;
         }

         if (!(*(h + 2)))
            return 0;

         c = qp_hex2asc(*(h + 1), *(h + 2));
         line_inject(l, &c, 1);

         t = NULL;
         bytes = 0;

         h += 3;
         continue;
      }

      else {
         if (!t)
            t = h;

         bytes++;
         h++;
      }
  }

  if (t)
     line_inject(l, t, bytes);

  return 1;
}

unsigned char qp_atoh(unsigned char x)
{
  unsigned char c = 0;

  if ((x >= 'a') && (x <= 'f')) {
     c = x - 87;
     return c;
  }

  if ((x >= 'A') && (x <= 'F')) {
     c = x - 55;
     return c;
  }

  if ((x >= '0') && (x <= '9')) {
     c = x - 48;
     return c;
  }

  return 0;
}

unsigned char qp_hex2asc(unsigned char s, unsigned char f)
{
  unsigned char val1 = 0, val2 = 0, val3 = 0;

  val1 = qp_atoh(f);
  val2 = qp_atoh(s);
  val3 = val1 + (val2 * 15) + val2;

  return val3;
}

