1 /* 2 ** Copyright (C) 2006-2020 by Carnegie Mellon University. 3 ** 4 ** @OPENSOURCE_LICENSE_START@ 5 ** See license information in ../../LICENSE.txt 6 ** @OPENSOURCE_LICENSE_END@ 7 */ 8 #ifndef _SKIOBUF_H 9 #define _SKIOBUF_H 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 #include <silk/silk.h> 15 16 RCSIDENTVAR(rcsID_SKIOBUF_H, "$SiLK: skiobuf.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 17 18 /* 19 ** skiobuf.h 20 ** 21 ** Routines for buffered file io. 22 ** 23 */ 24 25 #if SK_ENABLE_ZLIB 26 #include <zlib.h> 27 #endif 28 29 30 /** 31 * The default uncompressed block size. 32 */ 33 #define SKIOBUF_DEFAULT_BLOCKSIZE SKSTREAM_DEFAULT_BLOCKSIZE 34 35 36 /** 37 * The maximum compressed or uncompressed block size. 38 */ 39 #define SKIOBUF_MAX_BLOCKSIZE 0x100000 /* One megabyte */ 40 41 42 /** 43 * The default record size. A single record is guaranteed not to 44 * span multiple blocks. 45 */ 46 #define SKIOBUF_DEFAULT_RECORDSIZE 1 47 48 49 /** 50 * The type of IO buffer objects 51 */ 52 typedef struct sk_iobuf_st sk_iobuf_t; 53 54 55 /* 56 * skIOBuf can wrap an abstract file descriptor 'fd' if it 57 * implements some of the following functions. A reading skIOBuf 58 * requires the skio_read_fn_t; a writing skIOBuf requires the 59 * skio_write_fn_t. 60 */ 61 62 /** 63 * Implements a read(2)-like call: skIOBuf is requesting that the 64 * 'fd' add 'count' bytes of data into 'dest' for input, returning 65 * the number of bytes actually added. Should return a number less 66 * than count for a short read, -1 for an error. 67 */ 68 typedef ssize_t 69 (*skio_read_fn_t)( 70 void *fd, 71 void *dest, 72 size_t count); 73 74 /** 75 * Implements a write(2)-like call: skIOBuf is requesting that the 76 * 'fd' accept 'count' bytes of data from 'src' for output, 77 * returning the number of bytes actually accepted. Should return 78 * a number less than count for a short write (is this even 79 * meaningful?), -1 for an error. 80 */ 81 typedef ssize_t 82 (*skio_write_fn_t)( 83 void *fd, 84 const void *src, 85 size_t count); 86 87 /** 88 * Implements an lseek(2)-like call: skIOBuf is requesting that the 89 * read pointer be positioned relative to 'whence' by 'offset' 90 * bytes, returning the new offset of the read pointer. 'whence' 91 * can be SEEK_SET, SEEK_CUR, or SEEK_END. Returns (off_t)(-1) on 92 * error. If seek cannot work on a particular fd because it is not 93 * a seekable file, set errno to ESPIPE. 94 */ 95 typedef off_t 96 (*skio_seek_fn_t)( 97 void *fd, 98 off_t offset, 99 int whence); 100 101 /** 102 * Implements an fflush(3)-like call: skIOBuf is requesting that 103 * the 'fd' syncronize its output buffers with the physical media. 104 * Returns 0 on success, or -1 on error. This function may be 105 * NULL. 106 */ 107 typedef int (*skio_flush_fn_t)( 108 void *fd); 109 110 /** 111 * Implements a strerror(3)-like call: skIOBuf is requesting a 112 * human-readable error message given the error code 'fd_errno'. 113 */ 114 typedef const char * 115 (*skio_strerror_fn_t)( 116 void *fd, 117 int fd_errno); 118 119 /** 120 * skIOBuf is requesting that the 'fd' deallocate itself. 121 */ 122 typedef void 123 (*skio_free_fn_t)( 124 void *fd); 125 126 127 /** 128 * All supported operations on an abstract file descriptor. Either 129 * 'read' or 'write' must be specified. 130 */ 131 typedef struct skio_abstract_st { 132 skio_read_fn_t read; 133 skio_write_fn_t write; 134 skio_seek_fn_t seek; 135 skio_flush_fn_t flush; 136 skio_free_fn_t free_fd; 137 skio_strerror_fn_t strerror; 138 } skio_abstract_t; 139 140 141 /** 142 * Creates a new IO buffer for either reading or writing according 143 * to 'mode'. A 'mode' of SK_IO_APPEND creates a writing IO 144 * buffer. 145 * 146 * Returns the new IO buffer or NULL on allocation error. 147 */ 148 sk_iobuf_t * 149 skIOBufCreate( 150 skstream_mode_t mode); 151 152 153 /** 154 * Destroys the IO buffer 'iobuf'. If the IO buffer is a writer, 155 * the buffer will be flushed before destruction. Does nothing 156 * when 'iobuf' is NULL. 157 */ 158 void 159 skIOBufDestroy( 160 sk_iobuf_t *iobuf); 161 162 163 /** 164 * Binds the file descriptor 'fd' to the IO buffer 'iobuf'. 165 * 166 * If the IO buffer is a reader, any data read from the stream and 167 * held in the IO buffer is lost. 168 * 169 * If the IO buffer is a writer and is already associated with a 170 * file descriptor, the buffer will be flushed before binding. 171 * 172 * Binding a file descriptor resets the write/read count of the IO 173 * buffer. 'compmethod' is a valid compression method from 174 * silk_files.h. 175 * 176 * Returns 0 on success, -1 on failure. 177 */ 178 int 179 skIOBufBind( 180 sk_iobuf_t *iobuf, 181 int fd, 182 sk_compmethod_t compmethod); 183 184 185 /** 186 * Binds the abstract file descriptor 'fd' to the IO buffer 'iobuf'. 187 * 188 * If the IO buffer is a reader, any data read from the stream and 189 * held in the IO buffer is lost. 190 * 191 * If the IO buffer is a writer and is already associated with a 192 * file descriptor, the buffer will be flushed before binding. 193 * 194 * Binding a file descriptor resets the write/read count of the IO 195 * buffer. 'compmethod' is a valid compression method from 196 * silk_files.h. 'fd_ops' is a pointer to a struct of file 197 * operations on the abstract file descriptor 'fd'. 198 */ 199 int 200 skIOBufBindAbstract( 201 sk_iobuf_t *iobuf, 202 void *fd, 203 sk_compmethod_t compmethod, 204 skio_abstract_t *fd_ops); 205 206 207 /** 208 * Reads 'count' uncompressed bytes into 'data' from the IO buffer 209 * 'iobuf'. When 'data' is NULL, moves the read location 'count' 210 * bytes forward in the stream and that data is lost. 211 * 212 * Returns the number of uncompressed bytes read/skipped on 213 * success. The return value is always 'count' if the stream 214 * contained at least that number of bytes. If the return value is 215 * a positive number less than 'count', the IO buffer was only able 216 * to read that number of bytes before reaching the end of the 217 * stream. Returns 0 when there is no more data in the stream. 218 * Returns -1 on failure. 219 */ 220 ssize_t 221 skIOBufRead( 222 sk_iobuf_t *iobuf, 223 void *data, 224 size_t count); 225 226 227 /** 228 * Copies 'count' bytes from 'data' back into the read buffer of 229 * the IO buffer 'iobuf' so those bytes will be returned by the 230 * next call to skIOBufRead(). 231 * 232 * Adjusts the IO buffer's total read byte count by 'adjust_total' 233 * bytes. 'adjust_total' should 0 when returning bytes from a 234 * previous skIOBufRead(). 235 * 236 * Returns 'count' if the call was successful. Returns -1 if 237 * 'iobuf' has not been bound, if 'iobuf' is not a reader, if the 238 * 'data' parameter is NULL, or on allocation failure. 239 * 240 * Any other return value indicates the 'iobuf' does not have space 241 * for 'count' bytes and that 'iobuf' is unchanged. The return 242 * value is the number of bytes 'iobuf' has available for unget. 243 */ 244 ssize_t 245 skIOBufUnget( 246 sk_iobuf_t *iobuf, 247 const void *data, 248 size_t count, 249 off_t adjust_total); 250 251 252 /** 253 * Reads no more than 'count' uncompressed bytes into 'data' from 254 * the IO buffer 'iobuf', stopping at the first occurrence of the 255 * character 'c' in the stream and including that character in 256 * 'data'. The 'data' parameter may be NULL. 257 * 258 * Return values are identical to those for skIOBufRead(). 259 */ 260 ssize_t 261 skIOBufReadToChar( 262 sk_iobuf_t *iobuf, 263 void *data, 264 size_t count, 265 int c); 266 267 268 /** 269 * Writes 'count' uncompressed bytes from 'data' into the IO buffer 270 * 'iobuf'. 271 * 272 * Returns the number of uncompressed bytes written on success, -1 273 * on failure. This function will never return a number of bytes 274 * less than 'count'. 275 */ 276 ssize_t 277 skIOBufWrite( 278 sk_iobuf_t *iobuf, 279 const void *data, 280 size_t count); 281 282 283 /** 284 * Flushes the IO buffer writer 'iobuf'. This does not close the 285 * buffer or the underlying file descriptor. 286 * 287 * Returns the number of compressed bytes written to the underlying 288 * file descriptor since it was bound to the IO buffer on success. 289 * 290 * Returns -1 on failure on when invoked on a IO buffer created for 291 * reading. 292 */ 293 off_t 294 skIOBufFlush( 295 sk_iobuf_t *iobuf); 296 297 298 /** 299 * Returns the compressed number of bytes that have been actually 300 * been read/written from/to the underlying file descriptor. 301 * Returns -1 on error. 302 */ 303 off_t 304 skIOBufTotal( 305 sk_iobuf_t *iobuf); 306 307 308 /** 309 * Returns an upper bound on the number of compressed bytes that 310 * would be written to the underlying file descriptor since the 311 * binding of the buffer if the buffer were flushed. Returns -1 on 312 * error. 313 */ 314 off_t 315 skIOBufTotalUpperBound( 316 sk_iobuf_t *iobuf); 317 318 319 /** 320 * Sets the block size for the IO buffer. This function can only 321 * be called immediately after creation or binding of the IO 322 * buffer. Returns 0 on success, -1 on error. 323 */ 324 int 325 skIOBufSetBlockSize( 326 sk_iobuf_t *iobuf, 327 uint32_t size); 328 329 330 /** 331 * Returns the maximum possible compressed block size. 332 */ 333 uint32_t 334 skIOBufUpperCompBlockSize( 335 sk_iobuf_t *iobuf); 336 337 338 /** 339 * Sets the record size for the IO buffer. This function can only 340 * be called immediately after creation or binding of the IO 341 * buffer. Returns 0 on success, -1 on error. 342 */ 343 int 344 skIOBufSetRecordSize( 345 sk_iobuf_t *iobuf, 346 uint32_t size); 347 348 349 /** 350 * Returns a string representing the error state of the IO buffer 351 * 'buf'. This is a static string similar to that used by 352 * strerror. This function also resets the error state of the IO 353 * buffer. 354 */ 355 const char * 356 skIOBufStrError( 357 sk_iobuf_t *iobuf); 358 359 #ifdef __cplusplus 360 } 361 #endif 362 #endif /* _SKIOBUF_H */ 363 364 /* 365 ** Local Variables: 366 ** mode:c 367 ** indent-tabs-mode:nil 368 ** c-basic-offset:4 369 ** End: 370 */ 371