1 /* ========================================================================
2  * Copyright 1988-2007 University of Washington
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *
11  * ========================================================================
12  */
13 
14 /*
15  * Program:	File descriptor string routines
16  *
17  * Author:	Mark Crispin
18  *		Networks and Distributed Computing
19  *		Computing & Communications
20  *		University of Washington
21  *		Administration Building, AG-44
22  *		Seattle, WA  98195
23  *		Internet: MRC@CAC.Washington.EDU
24  *
25  * Date:	15 April 1997
26  * Last Edited:	4 April 2007
27  */
28 
29 #include "mail.h"
30 #include "osdep.h"
31 #include "misc.h"
32 #include "fdstring.h"
33 
34 /* String driver for fd stringstructs */
35 
36 static void fd_string_init (STRING *s,void *data,unsigned long size);
37 static char fd_string_next (STRING *s);
38 static void fd_string_setpos (STRING *s,unsigned long i);
39 
40 STRINGDRIVER fd_string = {
41   fd_string_init,		/* initialize string structure */
42   fd_string_next,		/* get next byte in string structure */
43   fd_string_setpos		/* set position in string structure */
44 };
45 
46 
47 /* Initialize string structure for fd stringstruct
48  * Accepts: string structure
49  *	    pointer to string
50  *	    size of string
51  */
52 
fd_string_init(STRING * s,void * data,unsigned long size)53 static void fd_string_init (STRING *s,void *data,unsigned long size)
54 {
55   FDDATA *d = (FDDATA *) data;
56 				/* note fd */
57   s->data = (void *) (unsigned long) d->fd;
58   s->data1 = d->pos;		/* note file offset */
59   s->size = size;		/* note size */
60   s->curpos = s->chunk = d->chunk;
61   s->chunksize = (unsigned long) d->chunksize;
62   s->offset = 0;		/* initial position */
63 				/* and size of data */
64   s->cursize = min (s->chunksize,size);
65 				/* move to that position in the file */
66   lseek (d->fd,d->pos,L_SET);
67   read (d->fd,s->chunk,(size_t) s->cursize);
68 }
69 
70 /* Get next character from fd stringstruct
71  * Accepts: string structure
72  * Returns: character, string structure chunk refreshed
73  */
74 
fd_string_next(STRING * s)75 static char fd_string_next (STRING *s)
76 {
77   char c = *s->curpos++;	/* get next byte */
78   SETPOS (s,GETPOS (s));	/* move to next chunk */
79   return c;			/* return the byte */
80 }
81 
82 
83 /* Set string pointer position for fd stringstruct
84  * Accepts: string structure
85  *	    new position
86  */
87 
fd_string_setpos(STRING * s,unsigned long i)88 static void fd_string_setpos (STRING *s,unsigned long i)
89 {
90   if (i > s->size) i = s->size;	/* don't permit setting beyond EOF */
91   s->offset = i;		/* set new offset */
92   s->curpos = s->chunk;		/* reset position */
93 				/* set size of data */
94   if (s->cursize = min (s->chunksize,SIZE (s))) {
95 				/* move to that position in the file */
96     lseek ((long) s->data,s->data1 + s->offset,L_SET);
97     read ((long) s->data,s->curpos,(size_t) s->cursize);
98   }
99 }
100