GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
segment/format.c
Go to the documentation of this file.
1 
15 #include <grass/config.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <limits.h>
21 #include <grass/segment.h>
22 
23 
24 static int _segment_format(int, int, int, int, int, int, int);
25 static int write_int(int, int);
26 static int zero_fill(int, off_t);
27 
28 /* fd must be open for write */
29 
30 
62 int segment_format(int fd, int nrows, int ncols, int srows, int scols,
63  int len)
64 {
65  return _segment_format(fd, nrows, ncols, srows, scols, len, 1);
66 }
67 
102 int segment_format_nofill(int fd, int nrows, int ncols, int srows, int scols,
103  int len)
104 {
105  return _segment_format(fd, nrows, ncols, srows, scols, len, 0);
106 }
107 
108 
109 static int _segment_format(int fd,
110  int nrows, int ncols,
111  int srows, int scols, int len, int fill)
112 {
113  off_t nbytes;
114  int spr, size;
115 
116  if (nrows <= 0 || ncols <= 0 || len <= 0 || srows <= 0 || scols <= 0) {
117  G_warning("segment_format(fd,%d,%d,%d,%d,%d): illegal value(s)",
118  nrows, ncols, srows, scols, len);
119  return -3;
120  }
121 
122  if (lseek(fd, 0L, SEEK_SET) == (off_t) -1) {
123  G_warning("segment_format(): Unable to seek (%s)", strerror(errno));
124  return -1;
125  }
126 
127  if (!write_int(fd, nrows) || !write_int(fd, ncols)
128  || !write_int(fd, srows) || !write_int(fd, scols)
129  || !write_int(fd, len))
130  return -1;
131 
132  if (!fill)
133  return 1;
134 
135  spr = ncols / scols;
136  if (ncols % scols)
137  spr++;
138 
139  size = srows * scols * len;
140 
141  /* calculate total number of segments */
142  nbytes = spr * ((nrows + srows - 1) / srows);
143  nbytes *= size;
144 
145  /* fill segment file with zeros */
146  /* NOTE: this could be done faster using lseek() by seeking
147  * ahead nbytes and then writing a single byte of 0,
148  * provided lseek() on all version of UNIX will create a file
149  * with holes that read as zeros.
150  */
151  if (zero_fill(fd, nbytes) < 0)
152  return -1;
153 
154  return 1;
155 }
156 
157 
158 static int write_int(int fd, int n)
159 {
160  if (write(fd, &n, sizeof(int)) != sizeof(int)) {
161  G_warning("segment_format(): Unable to write (%s)", strerror(errno));
162  return 0;
163  }
164 
165  return 1;
166 }
167 
168 
169 static int zero_fill(int fd, off_t nbytes)
170 {
171 #ifndef USE_LSEEK
172  char buf[10240];
173  register char *b;
174  register int n;
175 
176  /* zero buf */
177  n = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
178  b = buf;
179  while (n-- > 0)
180  *b++ = 0;
181 
182  while (nbytes > 0) {
183  n = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
184  if (write(fd, buf, n) != n) {
185  G_warning("segment zero_fill(): Unable to write (%s)", strerror(errno));
186  return -1;
187  }
188  nbytes -= n;
189  }
190  return 1;
191 #else
192  /* Using lseek (faster upon initialization).
193  NOTE: This version doesn't allocate disk storage for the file; storage will
194  be allocated dynamically as blocks are actually written. This could
195  result in zero_fill() succeeding but a subsequent call to write() failing
196  with ENOSPC ("No space left on device").
197  */
198 
199  static const char buf[10];
200 
201  G_debug(3, "Using new segmentation code...");
202  if (lseek(fd, nbytes - 1, SEEK_CUR) < 0) {
203  G_warning("segment zero_fill(): Unable to seek (%s)", strerror(errno));
204  return -1;
205  }
206  if (write(fd, buf, 1) != 1) {
207  G_warning("segment zero_fill(): Unable to write (%s)", strerror(errno));
208  return -1;
209  }
210 
211  return 1;
212 #endif
213 }
int nbytes
Definition: G.h:58
float b
Definition: named_colr.c:8
FILE * fd
Definition: g3dcolor.c:368
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
int segment_format(int fd, int nrows, int ncols, int srows, int scols, int len)
Format a segment file.
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int errno
int n
Definition: dataquad.c:291
int segment_format_nofill(int fd, int nrows, int ncols, int srows, int scols, int len)
Format a segment file.