RFC2646 wrapping method : Implementation example



	Hi all,
I just had time to code a function that wraps a string 
(rfc2646-compliant or not) in a rfc2646-compliant way.
Here it is

-------------------- code ----------------------
/* Wrap a string pointed by par(rfc-2646 compliant or not, depending on 
rfc_2646) to fit width
 * soft_break will be inserted to mark the wrap as specified in rfc 2646
 * in fact this function is "almost" rfc2646-compliant 
 * (it uses soft-break SPC+CR, instead of SPC+CRLF)
 * moreover it will format the string in order that each line begins
 * with the same number of quote_mark char
 * Note : the buffer pointed by par is not modified, the returned string 
is newly allocated
 * (so we can directly wrap from message body)
 */

gchar * libbalsa_wrap_rfc2646(gchar * par,gint width,gchar 
quote_mark,gboolean rfc2646)
{
    GString * result=NULL;
    gint len,quote_level;
    gchar * str,* quote_string=NULL;
    gboolean par_change,first_space;
    
    if (!par) return NULL;

    first_space=TRUE;
    while (TRUE) {

	/* Calculate quote level and quote string to append before each 
line*/
	str=par;
	for (quote_level=0;*par==quote_mark;par++,quote_level++);
	g_free(quote_string);
	if (quote_level) quote_string=g_strndup(str,quote_level);
	else quote_string=NULL;

	par_change=FALSE;
	if (quote_string) result=g_string_append(result,quote_string);
	len=0;
	first_space=TRUE;
	while (!par_change) {
	    /* strip leading white spaces */
	    while (*par==' ') par++;
	    /* We search the next space or \n */
	    for (oldpos=par;*par && *par!=' ' && *par!='\n';par++,len++)
		/* Extra tab spaces */
		if (*par=='\t') len+=7;

	    if (len>=width-quote_level && !first_space) {
		/* we have exceeded width so we insert a soft break
		 * unless it was a very long line without space (that is the 
reason
		 * of the first_space boolean) */
		result=g_string_append(result," \n");
		/* Begin new line with quote string */
		if (quote_string) result=g_string_append(result,quote_string);
		len=par-oldpos;
		first_space=TRUE;
	    }
	    else first_space=FALSE;
	    /* We add the string between oldpos and p
	     * we prepend a space because we always forget the space or the 
\n we stopped on
	     */
	    save=*par;
	    *par='\0';
	    result=g_string_append_c(result,' ');
	    result=g_string_append(result,oldpos);
	    /* We restore the char */
	    *par=save;
	    /* We count the space we have added */
	    len++; 
	    /* Test end of string */
	    par++;
	    if (!save || !*par) {
		str=result->str;
		g_string_free(result,FALSE);
		g_free(quote_string);
		return str;
	    }

	    /* Paragraph delimitig detection : will detect rfc2646 
delimiting depending on
	     * the rfc2646 parameter, else considers that we change par. 
whenever a space
	     * (ie SPC,TAB or another \n) follow the first one. I hope this 
way all kind of
	     * delimiting is covered :)
	     */
	    if (save=='\n')
		par_change=rfc2646 || isspace(*par);
	}
    }
}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]