~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/Sfio_dc/sfdcseekable.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfdchdr.h"
 
2
 
 
3
/*      Discipline to make an unseekable read stream seekable
 
4
**
 
5
**      Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
 
6
*/
 
7
 
 
8
typedef struct _skable_s
 
9
{       Sfdisc_t        disc;   /* sfio discipline */
 
10
        Sfio_t*         shadow; /* to shadow data */
 
11
        int             eof;    /* if eof has been reached */
 
12
} Seek_t;
 
13
 
 
14
#if __STD_C
 
15
static ssize_t skwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
 
16
#else
 
17
static ssize_t skwrite(f, buf, n, disc)
 
18
Sfio_t*         f;      /* stream involved */
 
19
Void_t*         buf;    /* buffer to read into */
 
20
size_t          n;      /* number of bytes to read */
 
21
Sfdisc_t*       disc;   /* discipline */
 
22
#endif
 
23
{
 
24
        return (ssize_t)(-1);
 
25
}
 
26
 
 
27
#if __STD_C
 
28
static ssize_t skread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
 
29
#else
 
30
static ssize_t skread(f, buf, n, disc)
 
31
Sfio_t*         f;      /* stream involved */
 
32
Void_t*         buf;    /* buffer to read into */
 
33
size_t          n;      /* number of bytes to read */
 
34
Sfdisc_t*       disc;   /* discipline */
 
35
#endif
 
36
{
 
37
        Seek_t*         sk;
 
38
        Sfio_t*         sf;
 
39
        Sfoff_t         addr, extent;
 
40
        ssize_t         r, w;
 
41
 
 
42
        sk = (Seek_t*)disc;
 
43
        sf = sk->shadow;
 
44
        if(sk->eof)
 
45
                return sfread(sf,buf,n);
 
46
 
 
47
        addr = sfseek(sf,(Sfoff_t)0,1);
 
48
        extent = sfsize(sf);
 
49
 
 
50
        if(addr+n <= extent)
 
51
                return sfread(sf,buf,n);
 
52
 
 
53
        if((r = (ssize_t)(extent-addr)) > 0)
 
54
        {       if((w = sfread(sf,buf,r)) != r)
 
55
                        return w;
 
56
                buf = (char*)buf + r;
 
57
                n -= r;
 
58
        }
 
59
                
 
60
        /* do a raw read */
 
61
        if((w = sfrd(f,buf,n,disc)) <= 0)
 
62
        {       sk->eof = 1;
 
63
                w = 0;
 
64
        }
 
65
        else if(sfwrite(sf,buf,w) != w)
 
66
                sk->eof = 1;
 
67
 
 
68
        return r+w;
 
69
}
 
70
 
 
71
#if __STD_C
 
72
static Sfoff_t skseek(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
 
73
#else
 
74
static Sfoff_t skseek(f, addr, type, disc)
 
75
Sfio_t*         f;
 
76
Sfoff_t         addr;
 
77
int             type;
 
78
Sfdisc_t*       disc;
 
79
#endif
 
80
{
 
81
        Sfoff_t         extent;
 
82
        Seek_t*         sk;
 
83
        Sfio_t*         sf;
 
84
        char            buf[SF_BUFSIZE];
 
85
        ssize_t         r, w;
 
86
 
 
87
        if(type < 0 || type > 2)
 
88
                return (Sfoff_t)(-1);
 
89
 
 
90
        sk = (Seek_t*)disc;
 
91
        sf = sk->shadow;
 
92
 
 
93
        extent = sfseek(sf,(Sfoff_t)0,2);
 
94
        if(type == 1)
 
95
                addr += sftell(sf);
 
96
        else if(type == 2)
 
97
                addr += extent;
 
98
 
 
99
        if(addr < 0)
 
100
                return (Sfoff_t)(-1);
 
101
        else if(addr > extent)
 
102
        {       if(sk->eof)
 
103
                        return (Sfoff_t)(-1);
 
104
 
 
105
                /* read enough to reach the seek point */
 
106
                while(addr > extent)
 
107
                {       if(addr > extent+sizeof(buf) )
 
108
                                w = sizeof(buf);
 
109
                        else    w = (int)(addr-extent);
 
110
                        if((r = sfrd(f,buf,w,disc)) <= 0)
 
111
                                w = r-1;
 
112
                        else if((w = sfwrite(sf,buf,r)) > 0)
 
113
                                extent += r;
 
114
                        if(w != r)
 
115
                        {       sk->eof = 1;
 
116
                                break;
 
117
                        }
 
118
                }
 
119
 
 
120
                if(addr > extent)
 
121
                        return (Sfoff_t)(-1);
 
122
        }
 
123
 
 
124
        return sfseek(sf,addr,0);
 
125
}
 
126
 
 
127
/* on close, remove the discipline */
 
128
#if __STD_C
 
129
static skexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
 
130
#else
 
131
static skexcept(f,type,data,disc)
 
132
Sfio_t*         f;
 
133
int             type;
 
134
Void_t*         data;
 
135
Sfdisc_t*       disc;
 
136
#endif
 
137
{
 
138
        if(type == SF_FINAL || type == SF_DPOP)
 
139
        {       sfclose(((Seek_t*)disc)->shadow);
 
140
                free(disc);
 
141
        }
 
142
        return 0;
 
143
}
 
144
 
 
145
#if __STD_C
 
146
int sfdcseekable(Sfio_t* f)
 
147
#else
 
148
int sfdcseekable(f)
 
149
Sfio_t* f;
 
150
#endif
 
151
{
 
152
        reg Seek_t*     sk;
 
153
 
 
154
        /* see if already seekable */
 
155
        if(sfseek(f,(Sfoff_t)0,1) >= 0)
 
156
                return 0;
 
157
 
 
158
        if(!(sk = (Seek_t*)malloc(sizeof(Seek_t))) )
 
159
                return -1;
 
160
 
 
161
        sk->disc.readf = skread;
 
162
        sk->disc.writef = skwrite;
 
163
        sk->disc.seekf = skseek;
 
164
        sk->disc.exceptf = skexcept;
 
165
        sk->shadow = sftmp(SF_BUFSIZE);
 
166
        sk->eof = 0;
 
167
 
 
168
        if(sfdisc(f, (Sfdisc_t*)sk) != (Sfdisc_t*)sk)
 
169
        {       sfclose(sk->shadow);
 
170
                free(sk);
 
171
                return -1;
 
172
        }
 
173
 
 
174
        return 0;
 
175
}