int DRead(struct dcache *adc, int page, struct DirBuffer *entry) { /* Read a page from the disk. */ struct buffer *tb, *tb2; struct osi_file *tfile; int code; AFS_STATCNT(DRead); memset(entry, 0, sizeof(struct DirBuffer)); ObtainWriteLock(&afs_bufferLock, 256); #define bufmatch(tb) (tb->page == page && tb->fid == adc->index) #define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);} /* this apparently-complicated-looking code is simply an example of * a little bit of loop unrolling, and is a standard linked-list * traversal trick. It saves a few assignments at the the expense * of larger code size. This could be simplified by better use of * macros. */ if ((tb = phTable[pHash(adc->index, page)])) { if (bufmatch(tb)) { ObtainWriteLock(&tb->lock, 257); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; } else { struct buffer **bufhead; bufhead = &(phTable[pHash(adc->index, page)]); while ((tb2 = tb->hashNext)) { if (bufmatch(tb2)) { buf_Front(bufhead, tb, tb2); ObtainWriteLock(&tb2->lock, 258); tb2->lockers++; ReleaseWriteLock(&afs_bufferLock); tb2->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb2->lock); entry->buffer = tb2; entry->data = tb2->data; return 0; } if ((tb = tb2->hashNext)) { if (bufmatch(tb)) { buf_Front(bufhead, tb2, tb); ObtainWriteLock(&tb->lock, 259); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; } } else break; } } } else tb2 = NULL; AFS_STATS(afs_stats_cmperf.bufMisses++); /* can't find it */ /* The last thing we looked at was either tb or tb2 (or nothing). That * is at least the oldest buffer on one particular hash chain, so it's * a pretty good place to start looking for the truly oldest buffer. */ tb = afs_newslot(adc, page, (tb ? tb : tb2)); if (!tb) { ReleaseWriteLock(&afs_bufferLock); return EIO; } ObtainWriteLock(&tb->lock, 260); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) { tb->fid = NULLIDX; afs_reset_inode(&tb->inode); tb->lockers--; ReleaseWriteLock(&tb->lock); return EIO; } tfile = afs_CFileOpen(&adc->f.inode); code = afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data, AFS_BUFFER_PAGESIZE); afs_CFileClose(tfile); if (code < AFS_BUFFER_PAGESIZE) { tb->fid = NULLIDX; afs_reset_inode(&tb->inode); tb->lockers--; ReleaseWriteLock(&tb->lock); return EIO; } /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; }
/** * read a page out of a directory object. * * @param[in] fid directory object fid * @param[in] page page in hash table to be read * * @return pointer to requested page in directory cache * @retval NULL read failed */ void * DRead(afs_int32 *fid, int page) { /* Read a page from the disk. */ struct buffer *tb, *tb2, **bufhead; ObtainWriteLock(&afs_bufferLock); calls++; #define bufmatch(tb) (tb->page == page && FidEq(tb->fid, fid)) #define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);} /* this apparently-complicated-looking code is simply an example of * a little bit of loop unrolling, and is a standard linked-list * traversal trick. It saves a few assignments at the the expense * of larger code size. This could be simplified by better use of * macros. With the use of these LRU queues, the old one-cache is * probably obsolete. */ if ((tb = phTable[pHash(fid)])) { /* ASSMT HERE */ if (bufmatch(tb)) { ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } else { bufhead = &(phTable[pHash(fid)]); while ((tb2 = tb->hashNext)) { if (bufmatch(tb2)) { buf_Front(bufhead, tb, tb2); ObtainWriteLock(&tb2->lock); tb2->lockers++; ReleaseWriteLock(&afs_bufferLock); tb2->accesstime = ++timecounter; ReleaseWriteLock(&tb2->lock); return tb2->data; } if ((tb = tb2->hashNext)) { /* ASSIGNMENT HERE! */ if (bufmatch(tb)) { buf_Front(bufhead, tb2, tb); ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } } else break; } } } else tb2 = NULL; /* can't find it */ /* The last thing we looked at was either tb or tb2 (or nothing). That * is at least the oldest buffer on one particular hash chain, so it's * a pretty good place to start looking for the truly oldest buffer. */ tb = newslot(fid, page, (tb ? tb : tb2)); ios++; ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); if (ReallyRead(tb->fid, tb->page, tb->data)) { tb->lockers--; FidZap(tb->fid); /* disaster */ ReleaseWriteLock(&tb->lock); return 0; } /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ ReleaseWriteLock(&tb->lock); return tb->data; }
static short ppm_image_init_rev( LPBJF_IMAGEINFO lpbjfimage ) { FILE *readfp; FILE *tmpfp; unsigned char buffer[50]; unsigned char *buf = NULL; unsigned char **rawbuf = NULL; short tmpflg; short tmpformat; short retbyte = 0; short bpp = 3; long width = 0; long length = 0; long maxvalue = 0; long rstep = 0; long RasterLength = 0; long i; short result = -1; char ch; long fp_offset; /*--- We must init global parameters again, without isfirstcall and ppm imageformat is inited in ppmraw_image_open ---*/ tmpflg = lpbjfimage->isfirstcall; tmpformat = lpbjfimage->imageformat; tmpfp = lpbjfimage->bmp; memset( (LPBJF_IMAGEINFO)lpbjfimage, 0, sizeof(BJF_IMAGEINFO) ); lpbjfimage->isfirstcall = tmpflg; lpbjfimage->imageformat = tmpformat; lpbjfimage->bmp = tmpfp; readfp = lpbjfimage->bmp; /*--- when second page, ---*/ if ( lpbjfimage->isfirstcall ){ lpbjfimage->isfirstcall = 0; } else{ retbyte = fread( buffer, 2, 1, readfp ); if ( !retbyte ){ /* end document */ result = 0; goto onErr; } if ( bufmatch( (char *)PPMRAWSTART, (char*)buffer, 2 ) < 0 ) goto onErr; } /* skip "0x0A" after "P6" */ if ( (ch = fgetc( readfp )) == EOF ) goto onErr; readPPMParam( readfp, &width, &length, &maxvalue ); if ( (!width) || (!length) ) goto onErr; RasterLength = width * bpp; /* parameter check */ if ( maxvalue != 255 ) goto onErr; /*--- Get image raw data ( by MAXBUFSIZE unit ) ---*/ rstep = MAXBUF / RasterLength; if ( rstep > length ){ rstep = length; } if ( (buf = (unsigned char *)malloc( MAXBUF )) == NULL ) goto onErr; rawbuf = (unsigned char **)calloc( sizeof(unsigned char *), rstep ); if ( rawbuf == NULL ) goto onErr; for( i=0; i<rstep; i++ ){ rawbuf[i] = buf + RasterLength * i; } fp_offset = RasterLength * ( length - rstep ); if ( fseek( readfp, fp_offset, SEEK_CUR ) != 0 ){ goto onErr; } if ( !fread( buf, RasterLength, rstep, readfp ) ){ goto onErr; } lpbjfimage->readraster += rstep; /* go back to read start point */ if ( fseek( readfp, -( RasterLength * rstep ) , SEEK_CUR ) != 0 ){ goto onErr; } /*--- Set cif Parameter ---*/ lpbjfimage->width = width; lpbjfimage->length = length; lpbjfimage->bpp = bpp; lpbjfimage->rasterlength = width * bpp; lpbjfimage->outputtype = BJFOUTPUT_COLOR; lpbjfimage->xresolution = 0; lpbjfimage->yresolution = 0; lpbjfimage->bmpraw = rawbuf; lpbjfimage->rstep = rstep; lpbjfimage->top = 0; result = 1; onErr: return result; }
/*---------------------------------------------------------------*/ int ppm_write_tmpfile( LPBJF_IMAGEINFO lpbjfimage, char *filename , char *outfile) { FILE *readfp = NULL; unsigned char buffer[5]; long width = 0; long length = 0; long maxvalue = 0; short bpp = 3; long RasterLength = 0; /* width of a raster */ long read_len = 0; long imagesize = 0; short retbyte; char ch; unsigned char *buf = NULL; long parm_len = 0; int fd = -1; int w_size; long block_num = 0; long lastblock_size = 0; short i; if ( filename != NULL ){ if ( (readfp = fopen( filename, "rb" )) == NULL ) goto onErr; fread( buffer, 2, 1, readfp ); } else { readfp = stdin; } /* check header */ retbyte = fread( buffer, 2, 1, readfp ); if ( !retbyte ){ /* end document */ return CIF_FILE_END; /* end document --> return */ } if ( bufmatch( (char *)PPMRAWSTART, (char*)buffer, 2 ) < 0 ) goto onErr; /* make tempfile to output */ fd = mkstemp(outfile); if( fd < 0 ){ goto onErr; } /* write "P6" */ w_size = write( fd , PPMRAWSTART , 2 ); /* skip "0x0A" after "P6" */ if ( (ch = fgetc( readfp )) == EOF ) goto onErr; w_size = write( fd , &ch , 1 ); /* read and write PPM parameter */ parm_len = readwritePPMParam( readfp, &width, &length, &maxvalue , fd ); if ( (!width) || (!length) ) goto onErr; /* parameter check */ if ( maxvalue != 255 ) goto onErr; RasterLength = width * bpp; imagesize = RasterLength * length; /* allocate read buffer */ if ( (buf = (unsigned char *)malloc( MAXBUF )) == NULL ) goto onErr; block_num = imagesize / MAXBUF; lastblock_size = imagesize % MAXBUF; /* read and write image raw data ( by MAXBUFSIZE unit ) */ for( i=0 ; i<block_num ; i++ ){ if ( !(read_len = fread( buf, 1, MAXBUF, readfp ) )){ goto onErr; } w_size = write( fd , buf , MAXBUF ); } if( lastblock_size > 0 ){ if ( !(read_len = fread( buf, 1, lastblock_size, readfp ) )){ goto onErr; } w_size = write( fd , buf , lastblock_size ); } if( buf ) free(buf); close( fd ); return fd; onErr: if( fd >= 0 ){ close( fd ); unlink(outfile); } if( buf ) free(buf); return -1; }
/*-------------------------------------------------------------*/ short bjf_image_open( LPBJF_IMAGEINFO lpbjfimage, char *filename ) /*-------------------------------------------------------------*/ { FILE *tf = NULL; unsigned char tbuf[10]; short result = -1; /*--- initialize image work parameter ---*/ memset( (LPBJF_IMAGEINFO)lpbjfimage, 0, sizeof(BJF_IMAGEINFO) ); /*-------------------------------*/ /* Select Image Format */ /*-------------------------------*/ /*---- in case input is stdin ---*/ if ( filename == NULL ){ if ( !fread( tbuf, 2, 1, stdin ) ) goto onErr; /*-- support ppm stdin --*/ if ( bufmatch( (char *)PPMRAWSTART, (char *)tbuf, 2 ) > 0 ){ lpbjfimage->imageformat = BJFIMAGE_PPM; } else { fprintf( stderr, "Error : not support this image format\n"); goto onErr; } } /*--- in case input is file ---*/ else{ if ( (tf=fopen( filename, "rb" )) == NULL ) goto onErr; /* top 4 byte of file */ if ( !fread( tbuf, 8, 1, tf ) ) goto onErr; if ( tf != NULL ){ fclose( tf ); tf = NULL; } if ( bufmatch( (char*)PPMRAWSTART, (char *)tbuf, 2 ) > 0 ) lpbjfimage->imageformat = BJFIMAGE_PPM; else{ fprintf( stderr, "Error : not support this image format\n"); goto onErr; } } /*--------------------------*/ /* Open Read Image */ /*--------------------------*/ switch( lpbjfimage->imageformat ){ case BJFIMAGE_PPM: if ( ppm_image_open( lpbjfimage, filename ) < 0 ) goto onErr; break; default: fprintf( stderr, "Error : not support this image format\n"); goto onErr; } result = 0; return result; onErr: if ( tf != NULL ) fclose( tf ); return result; }