/*
 * article.c Copyright 1999 Christopher M Sedore. All Rights Reserved.
 * Please see the "COPYING" file for license details.
 *
 * This file contains simple routines to extract headers from buffers.
 */ 

#include "main.h"

unsigned int
GetHeaderFromBuf(char *buffer, char *header, char *buf, unsigned int max, unsigned int buflen) 
{

	char *s,*s1,offset=0;
	unsigned int l=strlen(header);
	static char *hdrterm="\r\n\r\n";

	s=buffer;

    if (buflen<1)
		return 0;

	while ((unsigned int)(s-buffer)<(buflen-l)) {
		if ((((s==buffer) || (*(s-1)=='\n') || *(s-1)=='\r')) && 
			(!strncasecmp(s,header,l))) {
			s+=l;
			while (*s==' ') s++;
                        s1=s;
			while ((*s1!='\r') && (*s1!='\n') && ((unsigned int)(s1-buffer)<buflen)) {
				buf[s1-(s+offset)]=*s1;
				if (!--max) {
					buf[(s1-(s+offset))+1]=0;
					return s1-(s+offset);
				}

				s1++;

				if (!((*s1!='\r') && (*s1!='\n'))) {

					s1++; 
					offset++;

					if (*s1=='\n') { s1++; offset++; }

					if ((*s1==' ') || (*s1=='\t')) {
							while ((*s1==' ') || (*s1=='\t')) {
								s1++;
								offset++;
							}
							continue;
					}

					s1--;
					offset--;
					if ((*s1=='\n') && (*(s1-1)=='\r')) { s1--; offset--; }
					break;
				}
			}
			buf[(s1-(s+offset))]=0;
			return s1-s;
		}
		s++;
	}

	return 0;
}


unsigned int
GetHeader(struct article *art, char *header, char *buf,unsigned int max) 
{

	unsigned int l=strlen(header);

    return GetHeaderFromBuf(art->buf,header,buf,max,art->len);

}

int
GetHeaderRange(struct article *art, char *header, unsigned int *start, unsigned int *length, int *continuation)
{

	char *s,*s1;
	unsigned int l=strlen(header);
	static char *hdrterm="\r\n\r\n";

	s=art->buf;

	*continuation=FALSE;

	while ( (*((unsigned int *)s)!=*((unsigned int *)hdrterm)) && ((unsigned int)(s-art->buf)<art->len)) {
		if ((((s==art->buf) || (*(s-1)=='\n') || *(s-1)=='\r')) && 
			(!strncasecmp(s,header,l))) {
			s+=l;
			while (*s==' ') s++;
            s1=s;
			*start=s-art->buf;
			while (1) {
				while ((*s1!='\r') && (*s1!='\n') && ((unsigned int)(s1-art->buf)<art->len)) {
					s1++;
				}
				if ((unsigned int)(s1-art->buf)==art->len)
					return FALSE;
				*length=s1-s;
				if (*s1=='\r') s1++;
				if (*s1=='\n') s1++;
				if (*s1=='\t' || *s1==' ') {
					*continuation=TRUE;
				} else {
					return TRUE;
				}
			}
		}
		s++;
	}

	return FALSE;
}

int
GetHeaderRangeFull(struct article *art, char *header, unsigned int *start, unsigned int *length, int *continuation)
{
	char *s,*s1;
	unsigned int l=strlen(header);
	static char *hdrterm="\r\n\r\n";

	s=art->buf;

	*continuation=FALSE;
	while ( (*((unsigned int *)s)!=*((unsigned int *)hdrterm)) && ((unsigned int)(s-art->buf)<art->len)) {
		if ((((s==art->buf) || (*(s-1)=='\n') || *(s-1)=='\r')) && 
			(!strncasecmp(s,header,l))) {
            s1=s;
			*start=s-art->buf;
			while (1) {
				while ((*s1!='\r') && (*s1!='\n') && ((unsigned int)(s1-art->buf)<art->len)) {
					s1++;
				}
				if ((unsigned int)(s1-art->buf)==art->len)
					return FALSE;
				if (*s1=='\r') s1++;
				if (*s1=='\n') s1++;
				*length=s1-s;
				if (*s1=='\t' || *s1==' ') {
					*continuation=TRUE;
				} else {
					return TRUE;
				}
			}
		}
		s++;
	}

	return FALSE;
}


