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

« back to all changes in this revision

Viewing changes to tools/sfio/Sfio_dc/sfdcsubstream.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
 
 
4
/*      Discipline to treat a contiguous segment of a stream as a stream
 
5
**      in its own right. The hard part in all this is to allow multiple
 
6
**      segments of the stream to be used as substreams at the same time.
 
7
**
 
8
**      Written by David G. Korn and Kiem-Phong Vo (03/18/1998)
 
9
*/
 
10
 
 
11
typedef struct _subfile_s
 
12
{
 
13
        Sfdisc_t        disc;   /* sfio discipline */
 
14
        Sfio_t*         parent; /* parent stream */
 
15
        Sfoff_t         offset; /* starting offset */
 
16
        Sfoff_t         extent; /* size wanted */
 
17
        Sfoff_t         here;   /* current seek location */
 
18
} Subfile_t;
 
19
 
 
20
#if __STD_C
 
21
static ssize_t streamio(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc, int type)
 
22
#else
 
23
static ssize_t streamio(f, buf, n, disc, type)
 
24
Sfio_t*         f;
 
25
Void_t*         buf;
 
26
size_t          n;
 
27
Sfdisc_t*       disc;
 
28
int             type;
 
29
#endif
 
30
{
 
31
        reg Subfile_t   *su;
 
32
        reg Sfoff_t     here, parent;
 
33
        reg ssize_t     io;
 
34
 
 
35
        su = (Subfile_t*)disc;
 
36
 
 
37
        /* read just what we need */
 
38
        if(su->extent >= 0 && (ssize_t)n > (io = (ssize_t)(su->extent - su->here)) )
 
39
                n = io;
 
40
        if(n <= 0)
 
41
                return n;
 
42
 
 
43
        /* save current location in parent stream */
 
44
        parent = sfseek(su->parent,(Sfoff_t)0,1);
 
45
 
 
46
        /* read data */
 
47
        here = su->here + su->offset;
 
48
        if(sfseek(su->parent,here,0) != here)
 
49
                io = 0;
 
50
        else
 
51
        {       if(type == SF_WRITE) 
 
52
                        io = sfwrite(su->parent,buf,n);
 
53
                else    io = sfread(su->parent,buf,n);
 
54
                if(io > 0)
 
55
                        su->here += io;
 
56
        }
 
57
 
 
58
        /* restore parent current position */
 
59
        sfseek(su->parent,parent,0);
 
60
 
 
61
        return io;
 
62
}
 
63
 
 
64
#if __STD_C
 
65
static ssize_t streamwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
 
66
#else
 
67
static ssize_t streamwrite(f, buf, n, disc)
 
68
Sfio_t*         f;
 
69
Void_t*         buf;
 
70
size_t          n;
 
71
Sfdisc_t*       disc;
 
72
#endif
 
73
{
 
74
        return streamio(f,(Void_t*)buf,n,disc,SF_WRITE);
 
75
}
 
76
 
 
77
#if __STD_C
 
78
static ssize_t streamread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
 
79
#else
 
80
static ssize_t streamread(f, buf, n, disc)
 
81
Sfio_t*         f;
 
82
Void_t*         buf;
 
83
size_t          n;
 
84
Sfdisc_t*       disc;
 
85
#endif
 
86
{
 
87
        return streamio(f,buf,n,disc,SF_READ);
 
88
}
 
89
 
 
90
#if __STD_C
 
91
static Sfoff_t streamseek(Sfio_t* f, Sfoff_t pos, int type, Sfdisc_t* disc)
 
92
#else
 
93
static Sfoff_t streamseek(f, pos, type, disc)
 
94
Sfio_t*         f;
 
95
Sfoff_t         pos;
 
96
int             type;
 
97
Sfdisc_t*       disc;
 
98
#endif
 
99
{
 
100
        reg Subfile_t*  su;
 
101
        reg Sfoff_t     here, parent;
 
102
 
 
103
        su = (Subfile_t*)disc;
 
104
 
 
105
        switch(type)
 
106
        {
 
107
        case 0:
 
108
                here = 0;
 
109
                break;
 
110
        case 1:
 
111
                here = su->here;
 
112
                break;
 
113
        case 2:
 
114
                if(su->extent >= 0)
 
115
                        here = su->extent;
 
116
                else
 
117
                {       parent = sfseek(su->parent,(Sfoff_t)0,1);
 
118
                        if((here = sfseek(su->parent,(Sfoff_t)0,2)) < 0)
 
119
                                return -1;
 
120
                        else    here -= su->offset;
 
121
                        sfseek(su->parent,parent,0);
 
122
                }
 
123
                break;
 
124
        default:
 
125
                return -1;
 
126
        }
 
127
 
 
128
        pos += here;
 
129
        if(pos < 0 || (su->extent >= 0 && pos >= su->extent))
 
130
                return -1;
 
131
 
 
132
        return (su->here = pos);
 
133
}
 
134
 
 
135
#if __STD_C
 
136
static streamexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
 
137
#else
 
138
static streamexcept(f, type, data, disc)
 
139
Sfio_t*         f;
 
140
int             type;
 
141
Void_t*         data;
 
142
Sfdisc_t*       disc;
 
143
#endif
 
144
{
 
145
        if(type == SF_FINAL || type == SF_DPOP)
 
146
                free(disc);
 
147
        return 0;
 
148
}
 
149
 
 
150
#if __STD_C
 
151
int sfdcsubstream(Sfio_t* f, Sfio_t* parent, Sfoff_t offset, Sfoff_t extent)
 
152
#else
 
153
int sfdcsubstream(f, parent, offset, extent)
 
154
Sfio_t* f;      /* stream */
 
155
Sfio_t* parent; /* parent stream */
 
156
Sfoff_t offset; /* offset in parent stream */
 
157
Sfoff_t extent; /* desired size */
 
158
#endif
 
159
{
 
160
        reg Subfile_t*  su;
 
161
        reg Sfoff_t     here;
 
162
 
 
163
        /* establish that we can seek to offset */
 
164
        if((here = sfseek(parent,(Sfoff_t)0,1)) < 0 || sfseek(parent,offset,0) < 0)
 
165
                return -1;
 
166
        else    sfseek(parent,here,0);
 
167
 
 
168
        if(!(su = (Subfile_t*)malloc(sizeof(Subfile_t))) )
 
169
                return -1;
 
170
 
 
171
        su->disc.readf = streamread;
 
172
        su->disc.writef = streamwrite;
 
173
        su->disc.seekf = streamseek;
 
174
        su->disc.exceptf = streamexcept;
 
175
        su->parent = parent;
 
176
        su->offset = offset;
 
177
        su->extent = extent;
 
178
 
 
179
        if(sfdisc(f, (Sfdisc_t*)su) != (Sfdisc_t*)su)
 
180
        {       free(su);
 
181
                return -1;
 
182
        }
 
183
 
 
184
        return 0;
 
185
}