Merge branch 'master' into cde-next
[oweals/cde.git] / cde / lib / tt / mini_isam / isfileio.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
24 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
25 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
26 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
27 /*%%  $XConsortium: isfileio.c /main/3 1995/10/23 11:39:26 rswiston $                                                    */
28 /*
29  * Copyright (c) 1988 by Sun Microsystems, Inc.
30  */
31
32 /*
33  * isfileio.c
34  *
35  * Description:
36  *      I/O operations on UNIX files associated with FCB
37  */
38
39 #include "isam_impl.h"
40
41 static int _getoffset();
42 static Blkno _getblkno();
43
44
45 /*
46  * _cp_tofile(fcb, unixfd, data, pos, len)
47  *
48  * Copy data to a file associated with FCB (unixfd distinguishes among 
49  * .rec, .ind., and .var file). The data are copied from buffer data to
50  * the file at offset pos. The number of bytes to copy is in len.
51  */
52
53 void
54 _cp_tofile(Fcb *fcb, int unixfd, char *data, long pos, int len)
55 {
56     int         offset;                      /* Offset within a page */
57     Blkno       blkno;
58     Bufhdr      *bufhdr;
59     int         nbytes;
60
61     /*
62      * Data may span multiple blocks.
63      */
64     while (len > 0) {
65         blkno = _getblkno(pos);
66         offset = _getoffset(pos);
67         nbytes = (len < ISPAGESIZE - offset) ? len : ISPAGESIZE - offset;
68
69         bufhdr = _isdisk_fix(fcb, unixfd, blkno, ISFIXWRITE);
70         memcpy( bufhdr->isb_buffer + offset,data, nbytes);
71         _isdisk_unfix(bufhdr);
72
73         pos  += nbytes;
74         data += nbytes;
75         len  -= nbytes;
76     }
77 }
78
79 /*
80  * _cp_fromfile(fcb, unixfd, data, pos, len)
81  *
82  * Copy data from a file associated with FCB (unixfd distinguishes among 
83  * .rec, .ind., and .var file). The data are copied to buffer data from
84  * the file at offset pos. The number of bytes to copy is in len.
85  */
86
87 void
88 _cp_fromfile(Fcb *fcb, int unixfd, char *data, long pos, int len)
89 {
90     int         offset;                      /* Offset within a page */
91     Blkno       blkno;
92     Bufhdr      *bufhdr;
93     int         nbytes;
94
95     /*
96      * Data may span multiple blocks.
97      */
98     while (len > 0) {
99         blkno = _getblkno(pos);
100         offset = _getoffset(pos);
101         nbytes = (len < ISPAGESIZE - offset) ? len : ISPAGESIZE - offset;
102
103         bufhdr = _isdisk_fix(fcb, unixfd, blkno, ISFIXREAD);
104         memcpy( data,bufhdr->isb_buffer + offset, nbytes);
105         _isdisk_unfix(bufhdr);
106
107         pos  += nbytes;
108         data += nbytes;
109         len  -= nbytes;
110     }
111 }
112
113 /*
114  * extend_file(fcb, unixfd, oldsize)
115  *
116  * Extend UNIX file by one block.
117  */
118
119 Blkno 
120 _extend_file(Fcb *fcb, int unixfd, Blkno oldsize)
121 {
122     Bufhdr              *bufhdr;
123     char                buf[ISPAGESIZE];
124
125     /* 
126      * We must write something to the buffer, or we will get 
127      * segmentation fault when using mapped I/O.
128      */
129     _isseekpg(unixfd, oldsize);
130     _iswritepg(unixfd, buf);
131
132     bufhdr = _isdisk_fix(fcb, unixfd, oldsize, ISFIXNOREAD); 
133     _isdisk_unfix(bufhdr);
134
135     return (oldsize + 1);
136 }
137
138 /*
139  * off = _getoffset(pos)
140  *
141  * Calculate offset relative to the beginning of page
142  */
143
144 Static int
145 _getoffset(long pos)
146 {
147     return ((int)(pos % ISPAGESIZE));
148 }
149
150 /*
151  * blkno = _getblkno(pos)
152  *
153  * Calculate block number of the block containing position pos.
154  */
155
156 Static Blkno
157 _getblkno(long pos)
158 {
159     return ((int)(pos / ISPAGESIZE));
160 }