~ubuntu-branches/ubuntu/vivid/psicode/vivid

« back to all changes in this revision

Viewing changes to src/lib/libpsio/write.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck
  • Date: 2008-06-07 16:49:57 UTC
  • mfrom: (2.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080607164957-8pifvb133yjlkagn
Tags: 3.3.0-3
* debian/rules (DEB_MAKE_CHECK_TARGET): Do not abort test suite on
  failures.
* debian/rules (DEB_CONFIGURE_EXTRA_FLAGS): Set ${bindir} to /usr/lib/psi.
* debian/rules (install/psi3): Move psi3 file to /usr/bin.
* debian/patches/07_464867_move_executables.dpatch: New patch, add
  /usr/lib/psi to the $PATH, so that the moved executables are found.
  (closes: #464867)
* debian/patches/00list: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
/*!
11
11
** PSIO_WRITE(): Writes data to a TOC entry in a PSI file.
12
12
**
13
 
**  \param unit   = The PSI unit number used to identify the file to all read
14
 
**                  and write functions.
15
 
**  \param key    = The TOC keyword identifying the desired entry.
16
 
**  \param buffer = The buffer from which the data is written.
17
 
**  \param size   = The number of bytes to write.
18
 
**  \param sadd   = The entry-relative starting page/offset to write the data.
19
 
**  \param eadd   = A pointer to the entry-relative page/offset for the next
20
 
**                  byte after the end of the write request.
 
13
**  \param unit    = The PSI unit number used to identify the file to all read
 
14
**                   and write functions.
 
15
**  \param key     = The TOC keyword identifying the desired entry.
 
16
**  \param buffer  = The buffer from which the data is written.
 
17
**  \param size    = The number of bytes to write.
 
18
**  \param start   = The entry-relative starting page/offset to write the data.
 
19
**  \param end     = A pointer to the entry-relative page/offset for the next
 
20
**                   byte after the end of the write request.
21
21
**
22
22
** \ingroup (PSIO)
23
23
*/
24
24
 
25
25
int psio_write(unsigned int unit, char *key, char *buffer, ULI size,
26
 
               psio_address rel_start, psio_address *rel_end)
 
26
               psio_address start, psio_address *end)
27
27
{
28
28
  psio_ud *this_unit;
29
29
  psio_tocentry *this_entry, *last_entry;
30
 
  psio_address address, end_address;
 
30
  psio_address start_toc, start_data, end_data; /* global addresses */
 
31
  ULI tocentry_size;
 
32
  int dirty = 0;
31
33
 
32
34
  this_unit = &(psio_unit[unit]);
33
35
 
34
36
  /* Find the entry in the TOC */
35
37
  this_entry = psio_tocscan(unit, key);
36
38
 
 
39
  tocentry_size = sizeof(psio_tocentry) - 2*sizeof(psio_tocentry *);
 
40
 
37
41
  if(this_entry == NULL) { /* New TOC entry */
38
 
    if(rel_start.page||rel_start.offset) psio_error(unit,PSIO_ERROR_BLKSTART);
 
42
    if(start.page||start.offset) psio_error(unit,PSIO_ERROR_BLKSTART);
 
43
 
 
44
    dirty = 1; /* set flag for writing the TOC header */
39
45
 
40
46
    this_entry = (psio_tocentry *) malloc(sizeof(psio_tocentry));
41
47
    strcpy(this_entry->key,key);
42
48
    this_entry->next = NULL;
43
49
    this_entry->last = NULL;
44
50
 
45
 
    /* Compute the address of the entry */
 
51
    /* Compute the global address of the new entry */
46
52
    if(!(this_unit->toclen)) { /* First TOC entry */
47
53
      this_entry->sadd.page = 0;
48
 
      this_entry->sadd.offset = 3*sizeof(ULI);
49
 
 
 
54
      this_entry->sadd.offset = sizeof(ULI); /* offset for the toclen value stored first */
50
55
      this_unit->toc = this_entry;
51
56
    }
52
57
    else {  /* Use ending address from last TOC entry */
53
58
      last_entry = psio_toclast(unit);
54
59
      this_entry->sadd = last_entry->eadd;
55
 
 
56
60
      last_entry->next = this_entry;
57
61
      this_entry->last = last_entry;
58
62
    }
59
63
 
60
 
    /* Data for the write call */
61
 
    address = this_entry->sadd;
 
64
    /* compute important global addresses for the entry */
 
65
    start_toc = this_entry->sadd;
 
66
    start_data = psio_get_address(start_toc, tocentry_size);
 
67
    start_data = psio_get_global_address(start_data, start);
 
68
    end_data = psio_get_address(start_data, size);
62
69
 
63
70
    /* Set the end address for this_entry */
64
 
    this_entry->eadd = psio_get_address(this_entry->sadd, size);
 
71
    this_entry->eadd = end_data;
65
72
 
66
73
    /* Update the unit's TOC stats */
67
74
    this_unit->toclen++;
68
 
    this_unit->tocaddress = this_entry->eadd;
 
75
    psio_wt_toclen(unit, this_unit->toclen);
69
76
 
70
 
    /* Update the rel_end argument value for the caller */
71
 
    *rel_end = psio_get_address(rel_start,size);
 
77
    /* Update end (an entry-relative address) for the caller */
 
78
    *end = psio_get_address(start,size);
72
79
  }
73
80
  else { /* Old TOC entry */
74
81
 
75
82
    /* Compute the global starting page and offset for the block */
76
 
    address = psio_get_global_address(this_entry->sadd, rel_start);
 
83
    start_toc = this_entry->sadd;
 
84
    start_data = psio_get_address(start_toc, tocentry_size);
 
85
    start_data = psio_get_global_address(start_data, start);
77
86
 
78
87
    /* Make sure this block doesn't start past the end of the entry */
79
 
    if(address.page > this_entry->eadd.page)
 
88
    if(start_data.page > this_entry->eadd.page)
80
89
      psio_error(unit,PSIO_ERROR_BLKSTART);
81
 
    else if((address.page == this_entry->eadd.page) &&
82
 
            (address.offset > this_entry->eadd.offset))
 
90
    else if((start_data.page == this_entry->eadd.page) &&
 
91
            (start_data.offset > this_entry->eadd.offset))
83
92
      psio_error(unit,PSIO_ERROR_BLKSTART);
84
93
 
85
94
    /* Compute the new global ending address for the entry, if necessary */
86
 
    end_address = psio_get_address(address, size);
87
 
    if(end_address.page > this_entry->eadd.page) {
 
95
    end_data = psio_get_address(start_data, size);
 
96
    if(end_data.page > this_entry->eadd.page) {
88
97
      if(this_entry->next != NULL) {
89
 
        fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", 
90
 
                unit, key);
 
98
        fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", unit, key);
91
99
        psio_error(unit, PSIO_ERROR_BLKEND);
92
100
      }
93
 
      this_entry->eadd = end_address;
94
 
      this_unit->tocaddress = end_address;
95
 
          
 
101
      this_entry->eadd = end_data;
 
102
      dirty = 1; /* set flag for writing the TOC header */
96
103
    }
97
 
    else if((end_address.page == this_entry->eadd.page) &&
98
 
            (end_address.offset > this_entry->eadd.offset))
 
104
    else if((end_data.page == this_entry->eadd.page) &&
 
105
            (end_data.offset > this_entry->eadd.offset))
99
106
      {
100
107
        if(this_entry->next != NULL) {
101
 
          fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", 
102
 
                  unit, key);
 
108
          fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", unit, key);
103
109
          psio_error(unit, PSIO_ERROR_BLKEND);
104
110
        }
105
 
        this_entry->eadd = end_address;
106
 
        this_unit->tocaddress = end_address;
 
111
        this_entry->eadd = end_data;
 
112
        dirty = 1; /* set flag for writing the TOC header */
107
113
      }
108
114
 
109
 
    /* Update the eadd argument value for the caller */
110
 
    *rel_end = psio_get_address(rel_start, size);
 
115
    /* Update end (an entry-relative address) for the caller */
 
116
    *end = psio_get_address(start, size);
111
117
  }
112
118
 
 
119
  if(dirty) /* Need to first write/update the TOC header for this record */
 
120
    psio_rw(unit, (char *) this_entry, start_toc, tocentry_size, 1);
 
121
 
113
122
  /* Now write the actual data to the unit */
114
 
  psio_rw(unit, buffer, address, size, 1);
 
123
  psio_rw(unit, buffer, start_data, size, 1);
115
124
 
116
125
#ifdef PSIO_STATS
117
126
  psio_writlen[unit] += size;
118
127
#endif
119
128
 
120
 
  return(0);
 
129
  return(1);
121
130
}