static char const rcsid[] = "$Id: text.c,v 1.15 2005/03/10 08:50:49 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#ifndef CL_DEBUG
#define NDEBUG
#endif
#include <stdlib.h>
#ifdef C_DARWIN
#include <sys/types.h>
#include <sys/malloc.h>
#else
#ifdef HAVE_MALLOC_H
#ifndef C_BSD
#include <malloc.h>
#endif
#endif
#endif
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <stdio.h>
#include "line.h"
#include "mbox.h"
#include "blob.h"
#include "text.h"
#include "others.h"
static text *textCopy(const text *t_head);
static void addToFileblob(const line_t *line, void *arg);
static void getLength(const line_t *line, void *arg);
static void addToBlob(const line_t *line, void *arg);
static void *textIterate(const text *t_text, void (*cb)(const line_t *line, void *arg), void *arg);
void
textDestroy(text *t_head)
{
while(t_head) {
text *t_next = t_head->t_next;
if(t_head->t_line)
(void)lineUnlink(t_head->t_line);
free(t_head);
t_head = t_next;
}
}
text *
textClean(text *t_head)
{
return t_head;
}
static text *
textCopy(const text *t_head)
{
text *first = NULL, *last = NULL;
while(t_head) {
if(first == NULL)
last = first = (text *)cli_malloc(sizeof(text));
else {
last->t_next = (text *)cli_malloc(sizeof(text));
last = last->t_next;
}
if(last == NULL) {
if(first)
textDestroy(first);
return NULL;
}
if(t_head->t_line)
last->t_line = lineLink(t_head->t_line);
else
last->t_line = NULL;
t_head = t_head->t_next;
}
if(first)
last->t_next = NULL;
return first;
}
text *
textAdd(text *t_head, const text *t)
{
text *ret;
int count;
if(t_head == NULL)
return textCopy(t);
if(t == NULL)
return t_head;
ret = t_head;
count = 0;
while(t_head->t_next) {
count++;
t_head = t_head->t_next;
}
cli_dbgmsg("textAdd: count = %d\n", count);
while(t) {
t_head->t_next = (text *)cli_malloc(sizeof(text));
t_head = t_head->t_next;
assert(t_head != NULL);
if(t->t_line)
t_head->t_line = lineLink(t->t_line);
else
t_head->t_line = NULL;
t = t->t_next;
}
t_head->t_next = NULL;
return ret;
}
text *
textAddMessage(text *aText, message *aMessage)
{
assert(aMessage != NULL);
if(messageGetEncoding(aMessage) == NOENCODING)
return textAdd(aText, messageGetBody(aMessage));
else {
text *anotherText = messageToText(aMessage);
if(aText) {
aText = textAdd(aText, anotherText);
textDestroy(anotherText);
return aText;
}
return anotherText;
}
}
blob *
textToBlob(const text *t, blob *b)
{
size_t s;
if(t == NULL)
return NULL;
s = 0;
(void)textIterate(t, getLength, &s);
if(s == 0)
return b;
if(b == NULL) {
b = blobCreate();
if(b == NULL)
return NULL;
}
blobGrow(b, s);
(void)textIterate(t, addToBlob, b);
blobClose(b);
return b;
}
fileblob *
textToFileblob(const text *t, fileblob *fb)
{
assert(fb != NULL);
assert(t != NULL);
if(fb == NULL) {
fb = fileblobCreate();
if(fb == NULL)
return NULL;
}
return textIterate(t, addToFileblob, fb);
}
static void
getLength(const line_t *line, void *arg)
{
size_t *length = (size_t *)arg;
if(line)
*length += strlen(lineGetData(line)) + 1;
else
(*length)++;
}
static void
addToBlob(const line_t *line, void *arg)
{
blob *b = (blob *)arg;
if(line) {
const char *l = lineGetData(line);
blobAddData(b, (unsigned char *)l, strlen(l));
}
blobAddData(b, (unsigned char *)"\n", 1);
}
static void
addToFileblob(const line_t *line, void *arg)
{
fileblob *fb = (fileblob *)arg;
if(line) {
const char *l = lineGetData(line);
fileblobAddData(fb, (unsigned char *)l, strlen(l));
}
fileblobAddData(fb, (unsigned char *)"\n", 1);
}
static void *
textIterate(const text *t_text, void (*cb)(const line_t *item, void *arg), void *arg)
{
while(t_text) {
(*cb)(t_text->t_line, arg);
t_text = t_text->t_next;
}
return arg;
}