1 | /*!
|
---|
2 | \file rw.c
|
---|
3 | \ingroup (PSIO)
|
---|
4 | */
|
---|
5 |
|
---|
6 | #include <stdio.h>
|
---|
7 | #include <unistd.h>
|
---|
8 | #include <util/psi3/libpsio/psio.h>
|
---|
9 |
|
---|
10 | namespace psi3 {
|
---|
11 | namespace libpsio {
|
---|
12 |
|
---|
13 | /*!
|
---|
14 | ** PSIO_RW()
|
---|
15 | **
|
---|
16 | ** \ingroup (PSIO)
|
---|
17 | */
|
---|
18 | int psio_rw(unsigned int unit, char *buffer, psio_address address, ULI size, int wrt)
|
---|
19 | {
|
---|
20 | int errcod;
|
---|
21 | unsigned int i;
|
---|
22 | ULI errcod_uli;
|
---|
23 | ULI page, offset;
|
---|
24 | ULI buf_offset;
|
---|
25 | ULI this_page, this_page_max, this_page_total;
|
---|
26 | unsigned int first_vol, this_vol, numvols;
|
---|
27 | ULI bytes_left, num_full_pages;
|
---|
28 | psio_ud *this_unit;
|
---|
29 |
|
---|
30 | this_unit = &(psio_unit[unit]);
|
---|
31 | numvols = this_unit->numvols;
|
---|
32 | page = address.page;
|
---|
33 | offset = address.offset;
|
---|
34 |
|
---|
35 | /* Seek all volumes to correct starting positions */
|
---|
36 | first_vol = page % numvols;
|
---|
37 | errcod = psio_volseek(&(this_unit->vol[first_vol]), page, offset, numvols);
|
---|
38 | if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
|
---|
39 | for(i=1,this_page=page+1; i < numvols; i++,this_page++) {
|
---|
40 | this_vol = this_page % numvols;
|
---|
41 | errcod = psio_volseek(&(this_unit->vol[this_vol]), this_page,
|
---|
42 | (ULI) 0, numvols);
|
---|
43 | if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
|
---|
44 | }
|
---|
45 |
|
---|
46 | /* Number of bytes left on the first page */
|
---|
47 | this_page_max = PSIO_PAGELEN - offset;
|
---|
48 |
|
---|
49 | /* If we have enough room on this page, use it */
|
---|
50 | if(size <= this_page_max) this_page_total = size;
|
---|
51 | else this_page_total = this_page_max;
|
---|
52 |
|
---|
53 | buf_offset = 0;
|
---|
54 | if(wrt) {
|
---|
55 | errcod_uli = write(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
|
---|
56 | this_page_total);
|
---|
57 | if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
|
---|
58 | }
|
---|
59 | else {
|
---|
60 | errcod_uli = read(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
|
---|
61 | this_page_total);
|
---|
62 | if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
|
---|
63 | }
|
---|
64 |
|
---|
65 | /* Total number of bytes remaining to be read/written */
|
---|
66 | bytes_left = size - this_page_total;
|
---|
67 |
|
---|
68 | /* Read/Write all the full pages */
|
---|
69 | num_full_pages = bytes_left/PSIO_PAGELEN;
|
---|
70 | buf_offset += this_page_total;
|
---|
71 | for(i=0,this_page=page+1; i < num_full_pages; i++,this_page++) {
|
---|
72 | this_vol = this_page % numvols;
|
---|
73 | this_page_total = PSIO_PAGELEN;
|
---|
74 | if(wrt) {
|
---|
75 | errcod_uli = write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
|
---|
76 | this_page_total);
|
---|
77 | if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
|
---|
78 | }
|
---|
79 | else {
|
---|
80 | errcod_uli = read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
|
---|
81 | this_page_total);
|
---|
82 | if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
|
---|
83 | }
|
---|
84 | buf_offset += this_page_total;
|
---|
85 | }
|
---|
86 |
|
---|
87 | /* Read/Write the final partial page */
|
---|
88 | bytes_left -= num_full_pages * PSIO_PAGELEN;
|
---|
89 | this_vol = this_page % numvols;
|
---|
90 | if(bytes_left) {
|
---|
91 | if(wrt) {
|
---|
92 | errcod_uli = write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
|
---|
93 | bytes_left);
|
---|
94 | if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_WRITE);
|
---|
95 | }
|
---|
96 | else {
|
---|
97 | errcod_uli = read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
|
---|
98 | bytes_left);
|
---|
99 | if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_READ);
|
---|
100 | }
|
---|
101 | }
|
---|
102 |
|
---|
103 | return(0);
|
---|
104 | }
|
---|
105 |
|
---|
106 | }
|
---|
107 | }
|
---|