~ubuntu-branches/ubuntu/karmic/psicode/karmic

« back to all changes in this revision

Viewing changes to src/lib/libpsio/rw.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2009-02-23 00:12:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090223001202-rutldoy3dimfpesc
Tags: 3.4.0-1
* New upstream release.

[ Michael Banck ]
* debian/patches/01_DESTDIR.dpatch: Refreshed.
* debian/patches/02_FHS.dpatch: Removed, applied upstream.
* debian/patches/03_debian_docdir: Likewise.
* debian/patches/04_man.dpatch: Likewise.
* debian/patches/06_466828_fix_gcc_43_ftbfs.dpatch: Likewise.
* debian/patches/07_464867_move_executables: Fixed and refreshed.
* debian/patches/00list: Adjusted.
* debian/control: Improved description.
* debian/patches-held: Removed.
* debian/rules (install/psi3): Do not ship the ruby bindings for now.

[ Daniel Leidert ]
* debian/rules: Fix txtdir via DEB_MAKE_INSTALL_TARGET.
* debian/patches/01_DESTDIR.dpatch: Refreshed.

Show diffs side-by-side

added added

removed removed

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