/* 
   elmo - ELectronic Mail Operator

   Copyright (C) 2002 rzyjontko

   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; version 2.

   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.  

   ----------------------------------------------------------------------

   line with 0-terminated string
   
*/
/****************************************************************************
 *    IMPLEMENTATION HEADERS
 ****************************************************************************/

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

#include "line.h"
#include "xmalloc.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/

#define MIN(a,b) (((a)<(b))?(a):(b))

/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/
/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/

static void write_spaces (line_t *line, size_t len);

/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/


/**
 * Write so many spaces, so that line can be of length len.
 * Then update line->filled.
 */
static void
write_spaces (line_t *line, size_t len)
{
  if (line->filled > len){
    memset (line->str + len, ' ', line->filled - len);
  }
  line->filled = len;
}


/****************************************************************************
 *    INTERFACE FUNCTIONS
 ****************************************************************************/

line_t *
line_create (int size)
{
  line_t *result;

  if (size <= 0)
    return NULL;
  
  result = xmalloc (sizeof (line_t));

  result->filled    = size;
  result->size      = size;
  result->str       = xmalloc (size + 1);
  result->str[size] = '\0';

  line_put_str_len (result, NULL, 0);

  return result;
}



void
line_destroy (line_t *line)
{
  xfree (line->str);
  xfree (line);
}



void
line_clear (line_t *line)
{
  line->filled = line->size;

  line_put_str_len (line, NULL, 0);
}




void
line_put_str_len (line_t *line, const char *str, size_t len)
{
  len = MIN (len, line->size - 1);
  memcpy (line->str, str, len);
  write_spaces (line, len);
}



void
line_put_str (line_t *line, const char *str)
{
  size_t len = strlen (str);
  line_put_str_len (line, str, len);
}



void
line_add_str_len (line_t *line, const char *str, size_t len)
{
  len = MIN (len, line->size - 1 - line->filled);
  memcpy (line->str + line->filled, str, len);
  line->filled += len;
}



void
line_add_str_len_dots (line_t *line, const char *str, size_t len)
{
  if (len + line->filled < line->size - 1){
    memcpy (line->str + line->filled, str, len);
    line->filled += len;
  }
  else if (line->filled < line->size - 4){
    memcpy (line->str + line->filled, str, line->size - 4 - line->filled);
    line->filled += line->size - 4 - line->filled;
    line_add_str (line, "...");
  }
}



void
line_add_str_len_end (line_t *line, const char *str, size_t len)
{
  int space = line->size - (line->filled + len + 2);

  if (space < 0)
    space = 0;

  line->filled += space;
  line_add_str_len (line, str, len);
}



void
line_add_str_limit (line_t *line, const char *str, size_t limit)
{
  size_t len = MIN (strlen (str), limit);
  line_add_str_len (line, str, len);
}



void
line_add_str_pad (line_t *line, const char *str, size_t pad_len)
{
  int    i;
  size_t len;

  len = (str) ? strlen (str) : 0;

  if (len < pad_len){
    line_add_str_len (line, str, len);
    for (i = 0; i < pad_len - len; i++)
      line_add_char (line, ' ');
  }
  else {
    line_add_str_len (line, str, pad_len);
  }
}



void
line_add_str (line_t *line, const char *str)
{
  size_t len;

  if (str == NULL)
    return;
  
  len = strlen (str);
  line_add_str_len (line, str, len);
}


void
line_add_str_dots (line_t *line, const char *str)
{
  size_t len;

  if (str == NULL)
    return;

  len = strlen (str);
  line_add_str_len_dots (line, str, len);
}



void
line_add_str_end (line_t *line, const char *str)
{
  size_t len;

  if (str == NULL)
    return;

  len = strlen (str);
  line_add_str_len_end (line, str, len);
}



void
line_add_char (line_t *line, char c)
{
  if (line->filled >= line->size - 1)
    return;
  line->str[line->filled] = c;
  line->filled++;
}



void
line_add_int (line_t *line, int x)
{
  char buf[16];

  sprintf (buf, "%4d", x);
  line_add_str (line, buf);
}


/****************************************************************************
 *    INTERFACE CLASS BODIES
 ****************************************************************************/
/****************************************************************************
 *
 *    END MODULE line.c
 *
 ****************************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1