/* flush out any data in a stream buffer. Return -1 on failure */ static int flush_buffer(struct stream_info *sinfo, int stream) { int c_type = CTYPE_NONE; i64 c_len = sinfo->s[stream].buflen; if (seekto(sinfo, sinfo->s[stream].last_head) != 0) return -1; if (write_i64(sinfo->fd, sinfo->cur_pos) != 0) return -1; sinfo->s[stream].last_head = sinfo->cur_pos + 17; if (seekto(sinfo, sinfo->cur_pos) != 0) return -1; if (!(control.flags & FLAG_NO_COMPRESS)) { if (LZMA_COMPRESS(control.flags)) lzma_compress_buf(&sinfo->s[stream], &c_type, &c_len); else if (control.flags & FLAG_LZO_COMPRESS) lzo_compress_buf(&sinfo->s[stream], &c_type, &c_len); else if (control.flags & FLAG_BZIP2_COMPRESS) bzip2_compress_buf(&sinfo->s[stream], &c_type, &c_len); else if (control.flags & FLAG_ZLIB_COMPRESS) gzip_compress_buf(&sinfo->s[stream], &c_type, &c_len); else if (control.flags & FLAG_ZPAQ_COMPRESS) zpaq_compress_buf(&sinfo->s[stream], &c_type, &c_len); else fatal("Dunno wtf compression to use!\n"); } if (write_u8(sinfo->fd, c_type) != 0 || write_i64(sinfo->fd, c_len) != 0 || write_i64(sinfo->fd, sinfo->s[stream].buflen) != 0 || write_i64(sinfo->fd, 0) != 0) { return -1; } sinfo->cur_pos += 25; if (write_buf(sinfo->fd, sinfo->s[stream].buf, c_len) != 0) return -1; sinfo->cur_pos += c_len; sinfo->s[stream].buflen = 0; free(sinfo->s[stream].buf); sinfo->s[stream].buf = malloc(sinfo->bufsize); if (!sinfo->s[stream].buf) return -1; return 0; }
dsk_err_t nwasp_format(DSK_DRIVER *self, DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, const DSK_FORMAT *format, unsigned char filler) { /* * Note that we completely ignore the "format" parameter, since raw NWASP * images don't hold track headers. */ NWASP_DSK_DRIVER *nwself; unsigned long offset; unsigned long trklen; dsk_err_t err; (void)format; if (!self || !geom || self->dr_class != &dc_nwasp) return DSK_ERR_BADPTR; nwself = (NWASP_DSK_DRIVER *)self; if (!nwself->nw_fp) return DSK_ERR_NOTRDY; if (nwself->nw_readonly) return DSK_ERR_RDONLY; /* Convert from physical to logical sector. However, unlike the dg_* * functions, this _always_ uses "SIDES_OUTOUT" mapping */ offset = 204800L * head + 5120L * cylinder;/* + 512 * skew[sector-1];*/ trklen = 5120L; err = seekto(nwself, offset); if (err) return err; if (nwself->nw_filesize < offset + trklen) nwself->nw_filesize = offset + trklen; while (trklen--) if (fputc(filler, nwself->nw_fp) == EOF) return DSK_ERR_SYSERR; return DSK_ERR_OK; }
dsk_err_t nwasp_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_psect_t sector) { NWASP_DSK_DRIVER *nwself; unsigned long offset; dsk_err_t err; if (!buf || !self || !geom || self->dr_class != &dc_nwasp) return DSK_ERR_BADPTR; nwself = (NWASP_DSK_DRIVER *)self; if (!nwself->nw_fp) return DSK_ERR_NOTRDY; if (nwself->nw_readonly) return DSK_ERR_RDONLY; /* Convert from physical to logical sector. However, unlike the dg_* * functions, this _always_ uses "SIDES_OUTOUT" mapping */ offset = 204800L * head + 5120L * cylinder + 512 * skew[sector-1]; err = seekto(nwself, offset); if (err) return err; if (fwrite(buf, 1, geom->dg_secsize, nwself->nw_fp) < geom->dg_secsize) { return DSK_ERR_NOADDR; } if (nwself->nw_filesize < offset + geom->dg_secsize) nwself->nw_filesize = offset + geom->dg_secsize; return DSK_ERR_OK; }
/* * Go forward in 1GB chunks until you can't. * Go backwards in 128MB chunks until you can. * Go forwards in 1MB chunks until you can't and return that -1. */ uint64 disksize(char *disk) { int fd = open(disk, 0); char buf[512]; uint64 off = 0; if (fd == -1) { perror("usage: disksize device"); return(0); } /* * Go forward until it doesn't work. */ for ( ;; ) { off += FORWARD; if (seekto(fd, off, SEEK_SET) != off) { debug((stdout, "seekto(%dM) failed\n", (int)(off>>20))); off -= FORWARD; break; } if ((read(fd, buf, sizeof(buf)) != sizeof(buf))) { debug((stdout, "read @ %dM failed\n", (int)(off>>20))); off -= FORWARD; break; }
dsk_err_t logical_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_psect_t sector) { LOGICAL_DSK_DRIVER *lpxself; dsk_lsect_t offset; dsk_err_t err; if (!buf || !self || !geom || self->dr_class != &dc_logical) return DSK_ERR_BADPTR; lpxself = (LOGICAL_DSK_DRIVER *)self; if (!lpxself->lpx_fp) return DSK_ERR_NOTRDY; if (lpxself->lpx_readonly) return DSK_ERR_RDONLY; err = dg_ps2ls(geom, cylinder, head, sector, &offset); if (err) return err; offset *= geom->dg_secsize; err = seekto(lpxself, offset); if (err) return err; if (fwrite(buf, 1, geom->dg_secsize, lpxself->lpx_fp) < geom->dg_secsize) { return DSK_ERR_NOADDR; } if (lpxself->lpx_filesize < offset + geom->dg_secsize) lpxself->lpx_filesize = offset + geom->dg_secsize; return DSK_ERR_OK; }
dsk_err_t posix_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_psect_t sector) { POSIX_DSK_DRIVER *pxself; unsigned long offset; dsk_err_t err; if (!buf || !self || !geom || self->dr_class != &dc_posix) return DSK_ERR_BADPTR; pxself = (POSIX_DSK_DRIVER *)self; if (!pxself->px_fp) return DSK_ERR_NOTRDY; if (pxself->px_readonly) return DSK_ERR_RDONLY; /* Convert from physical to logical sector. However, unlike the dg_* * functions, this _always_ uses "SIDES_ALT" mapping; this is the * mapping that both the Linux and NT floppy drivers use to convert * offsets back into C/H/S. */ offset = (cylinder * geom->dg_heads) + head; /* Drive track */ offset *= geom->dg_sectors; offset += (sector - geom->dg_secbase); offset *= geom->dg_secsize; err = seekto(pxself, offset); if (err) return err; if (fwrite(buf, 1, geom->dg_secsize, pxself->px_fp) < geom->dg_secsize) { return DSK_ERR_NOADDR; } if (pxself->px_filesize < offset + geom->dg_secsize) pxself->px_filesize = offset + geom->dg_secsize; return DSK_ERR_OK; }
/** * Read a tag segment with sorting. * * @param[in] gtop #GTOP structure <br> * Output: @CODE{gtop->gtp_array} segment table <br> * Output: @CODE{gtop->gtp_count} segment table size <br> * Output: @CODE{gtop->gtp_index} segment table index (initial value = 0) <br> * Output: @CODE{gtop->cur_tagname} current tag name * * A segment is a set of tag records which have same tag name. <br> * This function read a segment from tag file, sort it and put it on segment table. <br> * This function can treat both of standard format and compact format. * * Sorting is done by three keys. * - 1st key: tag name * - 2nd key: file name * - 3rd key: line number * * Since all records in a segment have same tag name, you need not think about 1st key. */ void segment_read(GTOP *gtop) { const char *tagline, *fid, *path, *lineno; GTP *gtp; struct sh_entry *sh; /* * Save tag lines. */ gtop->cur_tagname[0] = '\0'; while ((tagline = dbop_next(gtop->dbop)) != NULL) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* * get tag name and line number. * * tagline = <file id> <tag name> <line number> */ if (gtop->cur_tagname[0] == '\0') { strlimcpy(gtop->cur_tagname, gtop->dbop->lastkey, sizeof(gtop->cur_tagname)); } else if (strcmp(gtop->cur_tagname, gtop->dbop->lastkey) != 0) { /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); break; } gtp = varray_append(gtop->vb); gtp->tagline = pool_strdup(gtop->segment_pool, tagline, 0); gtp->tag = (const char *)gtop->cur_tagname; /* * convert fid into hashed path name to save memory. */ fid = (const char *)strmake(tagline, " "); path = gpath_fid2path(fid, NULL); if (path == NULL) die("gtags_first: path not found. (fid=%s)", fid); sh = strhash_assign(gtop->path_hash, path, 1); gtp->path = sh->name; lineno = seekto(gtp->tagline, SEEKTO_LINENO); if (lineno == NULL) die("illegal tag record.\n%s", tagline); gtp->lineno = atoi(lineno); } /* * Sort tag lines. */ gtop->gtp_array = varray_assign(gtop->vb, 0, 0); gtop->gtp_count = gtop->vb->length; gtop->gtp_index = 0; if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->gtp_array, gtop->gtp_count, sizeof(GTP), compare_tags); }
dsk_err_t posix_format(DSK_DRIVER *self, DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, const DSK_FORMAT *format, unsigned char filler) { /* * Note that we completely ignore the "format" parameter, since raw POSIX * images don't hold track headers. */ POSIX_DSK_DRIVER *pxself; unsigned long offset; unsigned long trklen; dsk_err_t err; (void)format; if (!self || !geom || self->dr_class != &dc_posix) return DSK_ERR_BADPTR; pxself = (POSIX_DSK_DRIVER *)self; if (!pxself->px_fp) return DSK_ERR_NOTRDY; if (pxself->px_readonly) return DSK_ERR_RDONLY; /* Convert from physical to logical sector. However, unlike the dg_* * functions, this _always_ uses "SIDES_ALT" mapping; this is the * mapping that both the Linux and NT floppy drivers use to convert * offsets back into C/H/S. */ offset = (cylinder * geom->dg_heads) + head; /* Drive track */ trklen = geom->dg_sectors * geom->dg_secsize; offset *= trklen; err = seekto(pxself, offset); if (err) return err; if (pxself->px_filesize < offset + trklen) pxself->px_filesize = offset + trklen; while (trklen--) if (fputc(filler, pxself->px_fp) == EOF) return DSK_ERR_SYSERR; return DSK_ERR_OK; }
dsk_err_t logical_format(DSK_DRIVER *self, DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, const DSK_FORMAT *format, unsigned char filler) { /* * Note that we completely ignore the "format" parameter, since raw LOGICAL * images don't hold track headers. */ LOGICAL_DSK_DRIVER *lpxself; dsk_lsect_t offset; unsigned long trklen; dsk_err_t err; (void)format; if (!self || !geom || self->dr_class != &dc_logical) return DSK_ERR_BADPTR; lpxself = (LOGICAL_DSK_DRIVER *)self; if (!lpxself->lpx_fp) return DSK_ERR_NOTRDY; if (lpxself->lpx_readonly) return DSK_ERR_RDONLY; trklen = geom->dg_sectors * geom->dg_secsize; err = dg_ps2ls(geom, cylinder, head, geom->dg_secbase, &offset); if (err) return err; offset *= geom->dg_secsize; err = seekto(lpxself, offset); if (err) return err; if (lpxself->lpx_filesize < offset + trklen) lpxself->lpx_filesize = offset + trklen; while (trklen--) if (fputc(filler, lpxself->lpx_fp) == EOF) return DSK_ERR_SYSERR; return DSK_ERR_OK; }
GeglBuffer * gegl_buffer_load (const gchar *path) { GeglBuffer *ret; LoadInfo *info = g_slice_new0 (LoadInfo); info->path = g_strdup (path); info->i = g_open (info->path, O_RDONLY, 0770); GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "starting to load buffer %s", path); if (info->i == -1) { GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "failed top open %s for reading", path); return NULL; } { GeglBufferItem *header = gegl_buffer_read_header (info->i, &info->offset); g_assert (header); /*memcpy (&(info->header), header, sizeof (GeglBufferHeader));*/ info->header = *(&header->header); info->offset = info->header.next; /*g_free (header);*/ /* is there a pointer to a string or something we're missing? */ } info->tile_size = info->header.tile_width * info->header.tile_height * info->header.bytes_per_pixel; info->format = babl_format (info->header.description); ret = g_object_new (GEGL_TYPE_BUFFER, "format", info->format, "tile-width", info->header.tile_width, "tile-height", info->header.tile_height, "height", info->header.height, "width", info->header.width, "path", path, NULL); /* sanity check, should probably report error condition and return safely instead */ g_assert (babl_format_get_bytes_per_pixel (info->format) == info->header.bytes_per_pixel); info->tiles = gegl_buffer_read_index (info->i, &info->offset); /* load each tile */ { GList *iter; gint i = 0; for (iter = info->tiles; iter; iter = iter->next) { GeglBufferTile *entry = iter->data; guchar *data; GeglTile *tile; tile = gegl_tile_source_get_tile (GEGL_TILE_SOURCE (ret), entry->x, entry->y, entry->z); if (info->offset != entry->offset) { seekto (info, entry->offset); } /*g_assert (info->offset == entry->offset);*/ g_assert (tile); gegl_tile_lock (tile); data = gegl_tile_get_data (tile); g_assert (data); { ssize_t sz_read = read (info->i, data, info->tile_size); if(sz_read != -1) info->offset += sz_read; } /*g_assert (info->offset == entry->offset + info->tile_size);*/ gegl_tile_unlock (tile); gegl_tile_unref (tile); i++; } GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "%i tiles loaded",i); } GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "buffer loaded %s", info->path); load_info_destroy (info); return ret; }
int zone(char *disk, int oflag, int bsize) { char *buf; int usecs; int error; int n; int fd; uint64 off; int stride; if ((fd = open(disk, oflag)) == -1) { perror(disk); exit(1); } buf = valloc(bsize); if (!buf) { perror("valloc"); exit(1); } bzero(buf, bsize); #ifdef linux flushdisk(fd); #endif /* * We want ZONEPOINTS data points * but the stride has to be at least 512 and a 512 multiple. * Weird code below for precision. */ off = disksize(disk); off /= ZONEPOINTS; stride = off; if (stride < 512) stride = 512; stride += 511; stride >>= 9; stride <<= 9; /* * Very small disks such as ZIP drives get a 256K blocksize. * As measured on my SCSI ZIP, there seems to be no * difference between 256K and 1MB for sequential reads. * XXX - there is a rotational delay difference but that's tough. */ if (bsize > stride) bsize = 256<<10; if (bsize > stride) stride = bsize; off *= ZONEPOINTS; debug((stdout, "stride=%d bs=%d size=%dM points=%d\n", stride, bsize, (int)(off >> 20), (int)(off/stride))); /* * Read buf's worth of data every stride and time it. * Don't include the rotational delay. * This first I/O outside the loop is to catch read/write permissions. */ #define IO(a,b,c) (oflag == 0 ? (n = read(a,b,c)) : (n = write(a,b,c))) error = IO(fd, buf, 512); if (error == -1) { perror(disk); exit(1); } off = 512; for ( ;; ) { if (IO(fd, buf, 1024) != 1024) { exit(0); } off += 1024; start(0); if (IO(fd, buf, bsize) != bsize) { exit(0); } usecs = stop(0, 0); off += bsize; fprintf(stderr, "%.01f %.2f\n", off/1000000.0, (double)bsize/usecs); off += stride; if (seekto(fd, off)) { exit(0); } } exit(0); }
int seek(char *disk, int oflag) { char *buf; int fd; off64_t size; off64_t begin, end; int usecs; int error; int tot_msec = 0, tot_io = 0; int stride; if ((fd = open(disk, oflag)) == -1) { perror(disk); return (-1); } #ifdef linux flushdisk(fd); #endif size = disksize(disk); buf = valloc(IOSIZE); bzero(buf, IOSIZE); /* * We flip back and forth, in strides of 1MB (typically). * If we have a 100MB fd, that means we do * 1, 99, 2, 98, etc. * * We want around SEEK POINTS data points * but the stride has to be at least 512 and a 512 multiple. */ stride = size / SEEKPOINTS; if (stride < 512) stride = 512; stride += 511; stride >>= 9; stride <<= 9; debug((stdout, "stride=%d size=%dM points=%d\n", stride, (int)(size >> 20), (int)(size/stride))); end = size; begin = 0; seekto(fd, begin); IO(fd, buf, IOSIZE); while (end >= begin + stride*2) { end -= stride; start(0); seekto(fd, end); IO(fd, buf, IOSIZE); usecs = stop(0, 0); if (usecs > TOOSMALL && usecs < TOOBIG) { tot_io++; tot_msec += usecs/1000; fprintf(stderr, "%.01f %.02f\n", (end - begin - stride) / 1000000., usecs/1000.); } begin += stride; start(0); seekto(fd, begin); IO(fd, buf, IOSIZE); usecs = stop(0, 0); if (usecs > TOOSMALL && usecs < TOOBIG) { tot_io++; tot_msec += usecs/1000; fprintf(stderr, "%.01f %.02f\n", (end + stride - begin) / 1000000., usecs/1000.); } } /* * This is wrong, it should take the 1/3 stroke seek average. avg_msec = (double)tot_msec/tot_io; fprintf(stderr, "Average time == %.04f\n", avg_msec); */ return (0); }
/* fill a buffer from a stream - return -1 on failure */ static int fill_buffer(struct stream_info *sinfo, int stream) { uchar c_type; i64 header_length; i64 u_len, c_len; if (seekto(sinfo, sinfo->s[stream].last_head) != 0) return -1; if (read_u8(sinfo->fd, &c_type) != 0) return -1; /* Compatibility crap for versions < 0.4 */ if (control.major_version == 0 && control.minor_version < 4) { u32 c_len32, u_len32, last_head32; if (read_u32(sinfo->fd, &c_len32) != 0) return -1; if (read_u32(sinfo->fd, &u_len32) != 0) return -1; if (read_u32(sinfo->fd, &last_head32) != 0) return -1; c_len = c_len32; u_len = u_len32; sinfo->s[stream].last_head = last_head32; header_length = 13; } else { if (read_i64(sinfo->fd, &c_len) != 0) return -1; if (read_i64(sinfo->fd, &u_len) != 0) return -1; if (read_i64(sinfo->fd, &sinfo->s[stream].last_head) != 0) return -1; header_length = 25; } sinfo->total_read += header_length; if (sinfo->s[stream].buf) free(sinfo->s[stream].buf); sinfo->s[stream].buf = malloc(u_len); if (!sinfo->s[stream].buf) return -1; if (read_buf(sinfo->fd, sinfo->s[stream].buf, c_len) != 0) return -1; sinfo->total_read += c_len; sinfo->s[stream].buflen = u_len; sinfo->s[stream].bufp = 0; if (c_type != CTYPE_NONE) { if (c_type == CTYPE_LZMA) { if (lzma_decompress_buf(&sinfo->s[stream], (size_t)c_len)) return -1; } else if (c_type == CTYPE_LZO) { if (lzo_decompress_buf(&sinfo->s[stream], c_len)) return -1; } else if (c_type == CTYPE_BZIP2) { if (bzip2_decompress_buf(&sinfo->s[stream], c_len)) return -1; } else if (c_type == CTYPE_GZIP) { if (gzip_decompress_buf(&sinfo->s[stream], c_len)) return -1; } else if (c_type == CTYPE_ZPAQ) { if (zpaq_decompress_buf(&sinfo->s[stream])) return -1; } else fatal("Dunno wtf decompression type to use!\n"); } return 0; }