Commit 90450be6 90450be6f2f902b26c3b63c901b729503a056ec3 by Sergey Poznyakoff

mh: Optimize for speed.

* mh/burst.c (transtab): Revamp as a proper translation table.
It is indexed by the current state offset by 1 and the last read
caracter.
(token_num): Remove.
(finish_stream, flush_stream): Inline functions.
(burst_digest): Change transtab indexing.
1 parent 08562ac4
......@@ -192,31 +192,169 @@ burst_mime (mu_message_t msg)
#define S5 5
/* Negative state means no write */
int transtab[][4] = {
/* DEF '\n' ' ' '-' */
/* S1 */ { S2, S1, S2, -S3 },
/* S2 */ { S2, S1, S2, S2 },
/* S3 */ { -S4, -S4, -S2, -S4 },
/* S4 */ { -S4, -S5, -S4, -S4 },
/* S5 */ { S2, -S5, S2, S2 }
int transtab[5][256] = {
/* S1 */ { S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S1, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, -S3, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2 },
/* S2 */ { S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S1, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2 },
/* S3 */ { -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S2, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4 },
/* S4 */ { -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S5, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4,
-S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4 },
/* S5 */ { S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, -S5, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2,
S2, S2, S2, S2, S2, S2, S2, S2 }
};
static int
token_num(int c)
{
switch (c)
{
case '\n':
return 1;
case ' ':
return 2;
case '-':
return 3;
default:
return 0;
}
}
#define F_FIRST 0x01 /* First part of the message (no EB seen so far) */
#define F_ENCAPS 0x02 /* Within encapsulated part */
......@@ -228,7 +366,7 @@ struct burst_stream
size_t partno; /* Number of the part within the message */
};
static void
static inline void
finish_stream (struct burst_stream *bs)
{
if (bs->stream)
......@@ -249,7 +387,7 @@ finish_stream (struct burst_stream *bs)
}
}
static void
static inline void
flush_stream (struct burst_stream *bs, char *buf, size_t size)
{
int rc;
......@@ -297,7 +435,7 @@ int
burst_digest (mu_message_t msg)
{
mu_stream_t is;
char c;
unsigned char c;
size_t n;
int state = S1;
int eb_length = 0;
......@@ -312,7 +450,7 @@ burst_digest (mu_message_t msg)
mu_message_get_streamref (msg, &is);
while (mu_stream_read (is, &c, 1, &n) == 0 && n == 1)
{
int newstate = transtab[state - 1][token_num (c)];
int newstate = transtab[state - 1][c];
int silent = 0;
if (newstate < 0)
......@@ -358,7 +496,7 @@ burst_digest (mu_message_t msg)
}
state = newstate;
if (!silent)
flush_stream (&bs, &c, 1);
flush_stream (&bs, (char*)&c, 1);
}
mu_stream_destroy (&is);
......
/* Generate FSA states for RFC 934 bursting agent.
Copyright (C) 2010 Free Software Foundation, Inc.
GNU Mailutils 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; either version 3, or (at your option)
any later version.
GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
/* Bursting FSA states accoring to RFC 934:
S1 :: "-" S3
| CRLF {CRLF} S1
| c {c} S2
S2 :: CRLF {CRLF} S1
| c {c} S2
S3 :: " " S2
| c S4 ;; the bursting agent should consider the current
;; message ended.
S4 :: CRLF S5
| c S4
S5 :: CRLF S5
| c {c} S2 ;; The bursting agent should consider a new
;; message started
*/
static int
token_num (int c)
{
switch (c)
{
case '\n':
return 1;
case ' ':
return 2;
case '-':
return 3;
default:
return 0;
}
}
#define S1 1
#define S2 2
#define S3 3
#define S4 4
#define S5 5
/* Negative state means no write */
int transtab[][4] = {
/* DEF '\n' ' ' '-' */
/* S1 */ { S2, S1, S2, -S3 },
/* S2 */ { S2, S1, S2, S2 },
/* S3 */ { -S4, -S4, -S2, -S4 },
/* S4 */ { -S4, -S5, -S4, -S4 },
/* S5 */ { S2, -S5, S2, S2 }
};
int
main()
{
int i, state;
for (state = S1; state <= S5; state++)
{
printf ("/* S%d */ { ", state);
for (i = 0; i < 256; i++)
{
int newstate = transtab[state - 1][token_num (i)];
if (i > 0)
{
putchar (',');
if (i % 8 == 0)
printf ("\n ");
}
putchar (' ');
if (newstate < 0)
{
putchar ('-');
newstate = -newstate;
}
else
putchar (' ');
printf ("S%d", newstate);
}
printf (" },\n");
}
return 0;
}