File: format.c

package info (click to toggle)
grass 6.0.2-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 40,044 kB
  • ctags: 31,303
  • sloc: ansic: 321,125; tcl: 25,676; sh: 11,176; cpp: 10,098; makefile: 5,025; fortran: 1,846; yacc: 493; lex: 462; perl: 133; sed: 1
file content (136 lines) | stat: -rw-r--r-- 3,506 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "segment.h"

static int _segment_format (int,int,int,int,int,int,int);
static int write_int(int,int);
static int zero_fill(int, long);

/* fd must be open for write */

/*!
 * \brief format a segment file
 *
 * The segmentation routines require a disk file
 * to be used for paging segments in and out of memory. This routine formats the
 * file open for write on file descriptor <b>fd</b> for use as a segment file.
 * A segment file must be formatted before it can be processed by other segment
 * routines. The configuration parameters <b>nrows, ncols, srows, scols</b>,
 * and <b>len</b> are written to the beginning of the segment file which is
 * then filled with zeros.
 * The corresponding nonsegmented data matrix, which is to be transferred to the
 * segment file, is <b>nrows</b> by <b>ncols.</b> The segment file is to be
 * formed of segments which are <b>srows</b> by <b>scols.</b> The data items
 * have length <b>len</b> bytes. For example, if the <i>data type is int</i>,
 * \textbf{<i>len</i> }<i>is sizeof(int).</i>
 * Return codes are: 1 ok; else -1 could not seek or write <i>fd</i>, or -3
 * illegal configuration parameter(s).
 *
 *  \param fd
 *  \param nrows
 *  \param ncols
 *  \param srows
 *  \param scols
 *  \param len
 *  \return int
 */

int segment_format (int fd,int nrows,int ncols,int srows,int scols,int len)
{
    return _segment_format (fd, nrows, ncols, srows, scols, len, 1);
}

int segment_format_nofill (
	int fd,int nrows,int ncols,int srows,int scols,int len)
{
    return _segment_format (fd, nrows, ncols, srows, scols, len, 0);
}

static int _segment_format(
	int fd,
	int nrows,int ncols,
	int srows,int scols,
	int len,int fill)
{
    long nbytes ;
    int spr, size;

    if (nrows <= 0 || ncols <= 0 || len <= 0 || srows <= 0 || scols <= 0)
    {
	G_warning (
	    "segement_format(fd,%d,%d,%d,%d,%d): illegal value(s)\n",
	    nrows, ncols, srows, scols, len);
	return -3;
    }

    if (lseek (fd, 0L, 0) == (off_t)-1)
    {
	G_warning ("Segment_format: %s\n",strerror(errno));
	return -1;
    }

    if (!write_int (fd, nrows) ||  !write_int (fd, ncols)
    ||  !write_int (fd, srows) ||  !write_int (fd, scols)
    ||  !write_int (fd, len)) return -1;

    if (!fill) return 1;

    spr = ncols / scols ;
    if(ncols % scols)
	spr++ ;

    size = srows * scols * len;

/* calculate total number of segments */
    nbytes = spr * ((nrows + srows - 1)/ srows);
    nbytes *= size ;

/* fill segment file with zeros */
/* NOTE: this could be done faster using lseek() by seeking
 * ahead nbytes and then writing a single byte of 0,
 * provided lseek() on all version of UNIX will create a file
 * with holes that read as zeros.
 */
    if(zero_fill (fd, nbytes) < 0)
	return -1;

    return 1;
}

static int write_int (int fd,int n)
{
    int x;
    int bytes_wrote;

    x = n;

    if((bytes_wrote = write (fd, &x, sizeof(int)) == sizeof(int) ) < 0)
        G_warning("%s\n",strerror(errno));
    return bytes_wrote;
}

static int zero_fill(int fd, long nbytes)
{
    char buf[10240];
    register char *b;
    register int n;

/* zero buf */
    n = nbytes > sizeof(buf) ? sizeof(buf) : nbytes ;
    b = buf;
    while (n-- > 0)
	*b++ = 0;

    while (nbytes > 0)
    {
	n = nbytes > sizeof(buf) ? sizeof(buf) : nbytes ;
	if(write (fd, buf, n) != n) {
            G_warning("%s\n",strerror(errno));
	    return -1;
        }
	nbytes -= n;
    }
    return 1;
}