# Using debhelper 8.
[tabix.git] / bgzf.c
1 /* The MIT License
2
3    Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology
4
5    Permission is hereby granted, free of charge, to any person obtaining a copy
6    of this software and associated documentation files (the "Software"), to deal
7    in the Software without restriction, including without limitation the rights
8    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9    copies of the Software, and to permit persons to whom the Software is
10    furnished to do so, subject to the following conditions:
11
12    The above copyright notice and this permission notice shall be included in
13    all copies or substantial portions of the Software.
14
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21    THE SOFTWARE.
22 */
23
24 /*
25   2009-06-29 by lh3: cache recent uncompressed blocks.
26   2009-06-25 by lh3: optionally use my knetfile library to access file on a FTP.
27   2009-06-12 by lh3: support a mode string like "wu" where 'u' for uncompressed output */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include "bgzf.h"
37
38 #include "khash.h"
39 typedef struct {
40         int size;
41         uint8_t *block;
42         int64_t end_offset;
43 } cache_t;
44 KHASH_MAP_INIT_INT64(cache, cache_t)
45
46 #if defined(_WIN32) || defined(_MSC_VER)
47 #define ftello(fp) ftell(fp)
48 #define fseeko(fp, offset, whence) fseek(fp, offset, whence)
49 #else
50 extern off_t ftello(FILE *stream);
51 extern int fseeko(FILE *stream, off_t offset, int whence);
52 #endif
53
54 typedef int8_t bgzf_byte_t;
55
56 static const int DEFAULT_BLOCK_SIZE = 64 * 1024;
57 static const int MAX_BLOCK_SIZE = 64 * 1024;
58
59 static const int BLOCK_HEADER_LENGTH = 18;
60 static const int BLOCK_FOOTER_LENGTH = 8;
61
62 static const int GZIP_ID1 = 31;
63 static const int GZIP_ID2 = 139;
64 static const int CM_DEFLATE = 8;
65 static const int FLG_FEXTRA = 4;
66 static const int OS_UNKNOWN = 255;
67 static const int BGZF_ID1 = 66; // 'B'
68 static const int BGZF_ID2 = 67; // 'C'
69 static const int BGZF_LEN = 2;
70 static const int BGZF_XLEN = 6; // BGZF_LEN+4
71
72 static const int GZIP_WINDOW_BITS = -15; // no zlib header
73 static const int Z_DEFAULT_MEM_LEVEL = 8;
74
75
76 inline
77 void
78 packInt16(uint8_t* buffer, uint16_t value)
79 {
80     buffer[0] = value;
81     buffer[1] = value >> 8;
82 }
83
84 inline
85 int
86 unpackInt16(const uint8_t* buffer)
87 {
88     return (buffer[0] | (buffer[1] << 8));
89 }
90
91 inline
92 void
93 packInt32(uint8_t* buffer, uint32_t value)
94 {
95     buffer[0] = value;
96     buffer[1] = value >> 8;
97     buffer[2] = value >> 16;
98     buffer[3] = value >> 24;
99 }
100
101 static inline
102 int
103 bgzf_min(int x, int y)
104 {
105     return (x < y) ? x : y;
106 }
107
108 static
109 void
110 report_error(BGZF* fp, const char* message) {
111     fp->error = message;
112 }
113
114 int is_bgzipped(const char *fn)
115 {
116     BGZF *fp;
117     uint8_t buf[10],magic[10]="\037\213\010\4\0\0\0\0\0\377";
118     int n;
119
120     if ((fp = bgzf_open(fn, "r")) == 0) 
121     {
122         fprintf(stderr, "[is_bgzipped] failed to open the file: %s\n",fn);
123         return -1;
124     }
125
126 #ifdef _USE_KNETFILE
127     n = knet_read(fp->x.fpr, buf, 10);
128 #else
129     n = fread(buf, 1, 10, fp->file);
130 #endif
131     bgzf_close(fp);
132
133     if ( n!=10 ) 
134         return -1;
135
136     if ( !memcmp(magic, buf, 10) ) return 1;
137     return 0;
138 }
139
140 static BGZF *bgzf_read_init()
141 {
142         BGZF *fp;
143         fp = calloc(1, sizeof(BGZF));
144     fp->uncompressed_block_size = MAX_BLOCK_SIZE;
145     fp->uncompressed_block = malloc(MAX_BLOCK_SIZE);
146     fp->compressed_block_size = MAX_BLOCK_SIZE;
147     fp->compressed_block = malloc(MAX_BLOCK_SIZE);
148         fp->cache_size = 0;
149         fp->cache = kh_init(cache);
150         return fp;
151 }
152
153 static
154 BGZF*
155 open_read(int fd)
156 {
157 #ifdef _USE_KNETFILE
158     knetFile *file = knet_dopen(fd, "r");
159 #else
160     FILE* file = fdopen(fd, "r");
161 #endif
162     BGZF* fp;
163         if (file == 0) return 0;
164         fp = bgzf_read_init();
165     fp->file_descriptor = fd;
166     fp->open_mode = 'r';
167 #ifdef _USE_KNETFILE
168     fp->x.fpr = file;
169 #else
170     fp->file = file;
171 #endif
172     return fp;
173 }
174
175 static
176 BGZF*
177 open_write(int fd, bool is_uncompressed)
178 {
179     FILE* file = fdopen(fd, "w");
180     BGZF* fp;
181         if (file == 0) return 0;
182         fp = malloc(sizeof(BGZF));
183     fp->file_descriptor = fd;
184     fp->open_mode = 'w';
185     fp->owned_file = 0; fp->is_uncompressed = is_uncompressed;
186 #ifdef _USE_KNETFILE
187     fp->x.fpw = file;
188 #else
189     fp->file = file;
190 #endif
191     fp->uncompressed_block_size = DEFAULT_BLOCK_SIZE;
192     fp->uncompressed_block = NULL;
193     fp->compressed_block_size = MAX_BLOCK_SIZE;
194     fp->compressed_block = malloc(MAX_BLOCK_SIZE);
195     fp->block_address = 0;
196     fp->block_offset = 0;
197     fp->block_length = 0;
198     fp->error = NULL;
199     return fp;
200 }
201
202 BGZF*
203 bgzf_open(const char* __restrict path, const char* __restrict mode)
204 {
205     BGZF* fp = NULL;
206     if (mode[0] == 'r' || mode[0] == 'R') { /* The reading mode is preferred. */
207 #ifdef _USE_KNETFILE
208                 knetFile *file = knet_open(path, mode);
209                 if (file == 0) return 0;
210                 fp = bgzf_read_init();
211                 fp->file_descriptor = -1;
212                 fp->open_mode = 'r';
213                 fp->x.fpr = file;
214 #else
215                 int fd, oflag = O_RDONLY;
216 #ifdef _WIN32
217                 oflag |= O_BINARY;
218 #endif
219                 fd = open(path, oflag);
220                 if (fd == -1) return 0;
221         fp = open_read(fd);
222 #endif
223     } else if (mode[0] == 'w' || mode[0] == 'W') {
224                 int fd, oflag = O_WRONLY | O_CREAT | O_TRUNC;
225 #ifdef _WIN32
226                 oflag |= O_BINARY;
227 #endif
228                 fd = open(path, oflag, 0666);
229                 if (fd == -1) return 0;
230         fp = open_write(fd, strstr(mode, "u")? 1 : 0);
231     }
232     if (fp != NULL) {
233         fp->owned_file = 1;
234     }
235     return fp;
236 }
237
238 BGZF*
239 bgzf_fdopen(int fd, const char * __restrict mode)
240 {
241         if (fd == -1) return 0;
242     if (mode[0] == 'r' || mode[0] == 'R') {
243         return open_read(fd);
244     } else if (mode[0] == 'w' || mode[0] == 'W') {
245         return open_write(fd, strstr(mode, "u")? 1 : 0);
246     } else {
247         return NULL;
248     }
249 }
250
251 static
252 int
253 deflate_block(BGZF* fp, int block_length)
254 {
255     // Deflate the block in fp->uncompressed_block into fp->compressed_block.
256     // Also adds an extra field that stores the compressed block length.
257
258     bgzf_byte_t* buffer = fp->compressed_block;
259     int buffer_size = fp->compressed_block_size;
260
261     // Init gzip header
262     buffer[0] = GZIP_ID1;
263     buffer[1] = GZIP_ID2;
264     buffer[2] = CM_DEFLATE;
265     buffer[3] = FLG_FEXTRA;
266     buffer[4] = 0; // mtime
267     buffer[5] = 0;
268     buffer[6] = 0;
269     buffer[7] = 0;
270     buffer[8] = 0;
271     buffer[9] = OS_UNKNOWN;
272     buffer[10] = BGZF_XLEN;
273     buffer[11] = 0;
274     buffer[12] = BGZF_ID1;
275     buffer[13] = BGZF_ID2;
276     buffer[14] = BGZF_LEN;
277     buffer[15] = 0;
278     buffer[16] = 0; // placeholder for block length
279     buffer[17] = 0;
280
281     // loop to retry for blocks that do not compress enough
282     int input_length = block_length;
283     int compressed_length = 0;
284     while (1) {
285                 int compress_level = fp->is_uncompressed? 0 : Z_DEFAULT_COMPRESSION;
286         z_stream zs;
287         zs.zalloc = NULL;
288         zs.zfree = NULL;
289         zs.next_in = fp->uncompressed_block;
290         zs.avail_in = input_length;
291         zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH];
292         zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH;
293
294         int status = deflateInit2(&zs, compress_level, Z_DEFLATED,
295                                   GZIP_WINDOW_BITS, Z_DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY);
296         if (status != Z_OK) {
297             report_error(fp, "deflate init failed");
298             return -1;
299         }
300         status = deflate(&zs, Z_FINISH);
301         if (status != Z_STREAM_END) {
302             deflateEnd(&zs);
303             if (status == Z_OK) {
304                 // Not enough space in buffer.
305                 // Can happen in the rare case the input doesn't compress enough.
306                 // Reduce the amount of input until it fits.
307                 input_length -= 1024;
308                 if (input_length <= 0) {
309                     // should never happen
310                     report_error(fp, "input reduction failed");
311                     return -1;
312                 }
313                 continue;
314             }
315             report_error(fp, "deflate failed");
316             return -1;
317         }
318         status = deflateEnd(&zs);
319         if (status != Z_OK) {
320             report_error(fp, "deflate end failed");
321             return -1;
322         }
323         compressed_length = zs.total_out;
324         compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH;
325         if (compressed_length > MAX_BLOCK_SIZE) {
326             // should never happen
327             report_error(fp, "deflate overflow");
328             return -1;
329         }
330         break;
331     }
332
333     packInt16((uint8_t*)&buffer[16], compressed_length-1);
334     uint32_t crc = crc32(0L, NULL, 0L);
335     crc = crc32(crc, fp->uncompressed_block, input_length);
336     packInt32((uint8_t*)&buffer[compressed_length-8], crc);
337     packInt32((uint8_t*)&buffer[compressed_length-4], input_length);
338
339     int remaining = block_length - input_length;
340     if (remaining > 0) {
341         if (remaining > input_length) {
342             // should never happen (check so we can use memcpy)
343             report_error(fp, "remainder too large");
344             return -1;
345         }
346         memcpy(fp->uncompressed_block,
347                fp->uncompressed_block + input_length,
348                remaining);
349     }
350     fp->block_offset = remaining;
351     return compressed_length;
352 }
353
354 static
355 int
356 inflate_block(BGZF* fp, int block_length)
357 {
358     // Inflate the block in fp->compressed_block into fp->uncompressed_block
359
360     z_stream zs;
361     zs.zalloc = NULL;
362     zs.zfree = NULL;
363     zs.next_in = fp->compressed_block + 18;
364     zs.avail_in = block_length - 16;
365     zs.next_out = fp->uncompressed_block;
366     zs.avail_out = fp->uncompressed_block_size;
367
368     int status = inflateInit2(&zs, GZIP_WINDOW_BITS);
369     if (status != Z_OK) {
370         report_error(fp, "inflate init failed");
371         return -1;
372     }
373     status = inflate(&zs, Z_FINISH);
374     if (status != Z_STREAM_END) {
375         inflateEnd(&zs);
376         report_error(fp, "inflate failed");
377         return -1;
378     }
379     status = inflateEnd(&zs);
380     if (status != Z_OK) {
381         report_error(fp, "inflate failed");
382         return -1;
383     }
384     return zs.total_out;
385 }
386
387 static
388 int
389 check_header(const bgzf_byte_t* header)
390 {
391     return (header[0] == GZIP_ID1 &&
392             header[1] == (bgzf_byte_t) GZIP_ID2 &&
393             header[2] == Z_DEFLATED &&
394             (header[3] & FLG_FEXTRA) != 0 &&
395             unpackInt16((uint8_t*)&header[10]) == BGZF_XLEN &&
396             header[12] == BGZF_ID1 &&
397             header[13] == BGZF_ID2 &&
398             unpackInt16((uint8_t*)&header[14]) == BGZF_LEN);
399 }
400
401 static void free_cache(BGZF *fp)
402 {
403         khint_t k;
404         khash_t(cache) *h = (khash_t(cache)*)fp->cache;
405         if (fp->open_mode != 'r') return;
406         for (k = kh_begin(h); k < kh_end(h); ++k)
407                 if (kh_exist(h, k)) free(kh_val(h, k).block);
408         kh_destroy(cache, h);
409 }
410
411 static int load_block_from_cache(BGZF *fp, int64_t block_address)
412 {
413         khint_t k;
414         cache_t *p;
415         khash_t(cache) *h = (khash_t(cache)*)fp->cache;
416         k = kh_get(cache, h, block_address);
417         if (k == kh_end(h)) return 0;
418         p = &kh_val(h, k);
419         if (fp->block_length != 0) fp->block_offset = 0;
420         fp->block_address = block_address;
421         fp->block_length = p->size;
422         memcpy(fp->uncompressed_block, p->block, MAX_BLOCK_SIZE);
423 #ifdef _USE_KNETFILE
424         knet_seek(fp->x.fpr, p->end_offset, SEEK_SET);
425 #else
426         fseeko(fp->file, p->end_offset, SEEK_SET);
427 #endif
428         return p->size;
429 }
430
431 static void cache_block(BGZF *fp, int size)
432 {
433         int ret;
434         khint_t k;
435         cache_t *p;
436         khash_t(cache) *h = (khash_t(cache)*)fp->cache;
437         if (MAX_BLOCK_SIZE >= fp->cache_size) return;
438         if ((kh_size(h) + 1) * MAX_BLOCK_SIZE > fp->cache_size) {
439                 /* A better way would be to remove the oldest block in the
440                  * cache, but here we remove a random one for simplicity. This
441                  * should not have a big impact on performance. */
442                 for (k = kh_begin(h); k < kh_end(h); ++k)
443                         if (kh_exist(h, k)) break;
444                 if (k < kh_end(h)) {
445                         free(kh_val(h, k).block);
446                         kh_del(cache, h, k);
447                 }
448         }
449         k = kh_put(cache, h, fp->block_address, &ret);
450         if (ret == 0) return; // if this happens, a bug!
451         p = &kh_val(h, k);
452         p->size = fp->block_length;
453         p->end_offset = fp->block_address + size;
454         p->block = malloc(MAX_BLOCK_SIZE);
455         memcpy(kh_val(h, k).block, fp->uncompressed_block, MAX_BLOCK_SIZE);
456 }
457
458 int
459 bgzf_read_block(BGZF* fp)
460 {
461     bgzf_byte_t header[BLOCK_HEADER_LENGTH];
462         int size = 0;
463 #ifdef _USE_KNETFILE
464     int64_t block_address = knet_tell(fp->x.fpr);
465         if (load_block_from_cache(fp, block_address)) return 0;
466     int count = knet_read(fp->x.fpr, header, sizeof(header));
467 #else
468     int64_t block_address = ftello(fp->file);
469         if (load_block_from_cache(fp, block_address)) return 0;
470     int count = fread(header, 1, sizeof(header), fp->file);
471 #endif
472     if (count == 0) {
473         fp->block_length = 0;
474         return 0;
475     }
476         size = count;
477     if (count != sizeof(header)) {
478         report_error(fp, "read failed");
479         return -1;
480     }
481     if (!check_header(header)) {
482         report_error(fp, "invalid block header");
483         return -1;
484     }
485     int block_length = unpackInt16((uint8_t*)&header[16]) + 1;
486     bgzf_byte_t* compressed_block = (bgzf_byte_t*) fp->compressed_block;
487     memcpy(compressed_block, header, BLOCK_HEADER_LENGTH);
488     int remaining = block_length - BLOCK_HEADER_LENGTH;
489 #ifdef _USE_KNETFILE
490     count = knet_read(fp->x.fpr, &compressed_block[BLOCK_HEADER_LENGTH], remaining);
491 #else
492     count = fread(&compressed_block[BLOCK_HEADER_LENGTH], 1, remaining, fp->file);
493 #endif
494     if (count != remaining) {
495         report_error(fp, "read failed");
496         return -1;
497     }
498         size += count;
499     count = inflate_block(fp, block_length);
500     if (count < 0) {
501         return -1;
502     }
503     if (fp->block_length != 0) {
504         // Do not reset offset if this read follows a seek.
505         fp->block_offset = 0;
506     }
507     fp->block_address = block_address;
508     fp->block_length = count;
509         cache_block(fp, size);
510     return 0;
511 }
512
513 int
514 bgzf_read(BGZF* fp, void* data, int length)
515 {
516     if (length <= 0) {
517         return 0;
518     }
519     if (fp->open_mode != 'r') {
520         report_error(fp, "file not open for reading");
521         return -1;
522     }
523
524     int bytes_read = 0;
525     bgzf_byte_t* output = data;
526     while (bytes_read < length) {
527         int available = fp->block_length - fp->block_offset;
528         if (available <= 0) {
529             if (bgzf_read_block(fp) != 0) {
530                 return -1;
531             }
532             available = fp->block_length - fp->block_offset;
533             if (available <= 0) {
534                 break;
535             }
536         }
537         int copy_length = bgzf_min(length-bytes_read, available);
538         bgzf_byte_t* buffer = fp->uncompressed_block;
539         memcpy(output, buffer + fp->block_offset, copy_length);
540         fp->block_offset += copy_length;
541         output += copy_length;
542         bytes_read += copy_length;
543     }
544     if (fp->block_offset == fp->block_length) {
545 #ifdef _USE_KNETFILE
546         fp->block_address = knet_tell(fp->x.fpr);
547 #else
548         fp->block_address = ftello(fp->file);
549 #endif
550         fp->block_offset = 0;
551         fp->block_length = 0;
552     }
553     return bytes_read;
554 }
555
556 static
557 int
558 flush_block(BGZF* fp)
559 {
560     while (fp->block_offset > 0) {
561         int block_length = deflate_block(fp, fp->block_offset);
562         if (block_length < 0) {
563             return -1;
564         }
565 #ifdef _USE_KNETFILE
566         int count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw);
567 #else
568         int count = fwrite(fp->compressed_block, 1, block_length, fp->file);
569 #endif
570         if (count != block_length) {
571             report_error(fp, "write failed");
572             return -1;
573         }
574         fp->block_address += block_length;
575     }
576     return 0;
577 }
578
579 int
580 bgzf_write(BGZF* fp, const void* data, int length)
581 {
582     if (fp->open_mode != 'w') {
583         report_error(fp, "file not open for writing");
584         return -1;
585     }
586
587     if (fp->uncompressed_block == NULL) {
588         fp->uncompressed_block = malloc(fp->uncompressed_block_size);
589     }
590
591     const bgzf_byte_t* input = data;
592     int block_length = fp->uncompressed_block_size;
593     int bytes_written = 0;
594     while (bytes_written < length) {
595         int copy_length = bgzf_min(block_length - fp->block_offset, length - bytes_written);
596         bgzf_byte_t* buffer = fp->uncompressed_block;
597         memcpy(buffer + fp->block_offset, input, copy_length);
598         fp->block_offset += copy_length;
599         input += copy_length;
600         bytes_written += copy_length;
601         if (fp->block_offset == block_length) {
602             if (flush_block(fp) != 0) {
603                 break;
604             }
605         }
606     }
607     return bytes_written;
608 }
609
610 int
611 bgzf_close(BGZF* fp)
612 {
613     if (fp->open_mode == 'w') {
614         if (flush_block(fp) != 0) {
615             return -1;
616         }
617                 { // add an empty block
618                         int count, block_length = deflate_block(fp, 0);
619 #ifdef _USE_KNETFILE
620                         count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw);
621 #else
622                         count = fwrite(fp->compressed_block, 1, block_length, fp->file);
623 #endif
624                 }
625 #ifdef _USE_KNETFILE
626         if (fflush(fp->x.fpw) != 0) {
627 #else
628         if (fflush(fp->file) != 0) {
629 #endif
630             report_error(fp, "flush failed");
631             return -1;
632         }
633     }
634     if (fp->owned_file) {
635 #ifdef _USE_KNETFILE
636                 int ret;
637                 if (fp->open_mode == 'w') ret = fclose(fp->x.fpw);
638                 else ret = knet_close(fp->x.fpr);
639         if (ret != 0) return -1;
640 #else
641         if (fclose(fp->file) != 0) {
642             return -1;
643         }
644 #endif
645     }
646     free(fp->uncompressed_block);
647     free(fp->compressed_block);
648         free_cache(fp);
649     free(fp);
650     return 0;
651 }
652
653 void bgzf_set_cache_size(BGZF *fp, int cache_size)
654 {
655         if (fp) fp->cache_size = cache_size;
656 }
657
658 int bgzf_check_EOF(BGZF *fp)
659 {
660         static uint8_t magic[28] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\033\0\3\0\0\0\0\0\0\0\0\0";
661         uint8_t buf[28];
662         off_t offset;
663 #ifdef _USE_KNETFILE
664         offset = knet_tell(fp->x.fpr);
665         if (knet_seek(fp->x.fpr, -28, SEEK_END) != 0) return -1;
666         knet_read(fp->x.fpr, buf, 28);
667         knet_seek(fp->x.fpr, offset, SEEK_SET);
668 #else
669         offset = ftello(fp->file);
670         if (fseeko(fp->file, -28, SEEK_END) != 0) return -1;
671         fread(buf, 1, 28, fp->file);
672         fseeko(fp->file, offset, SEEK_SET);
673 #endif
674         return (memcmp(magic, buf, 28) == 0)? 1 : 0;
675 }
676
677 int64_t
678 bgzf_seek(BGZF* fp, int64_t pos, int where)
679 {
680     if (fp->open_mode != 'r') {
681         report_error(fp, "file not open for read");
682         return -1;
683     }
684     if (where != SEEK_SET) {
685         report_error(fp, "unimplemented seek option");
686         return -1;
687     }
688     int block_offset = pos & 0xFFFF;
689     int64_t block_address = (pos >> 16) & 0xFFFFFFFFFFFFLL;
690 #ifdef _USE_KNETFILE
691     if (knet_seek(fp->x.fpr, block_address, SEEK_SET) != 0) {
692 #else
693     if (fseeko(fp->file, block_address, SEEK_SET) != 0) {
694 #endif
695         report_error(fp, "seek failed");
696         return -1;
697     }
698     fp->block_length = 0;  // indicates current block is not loaded
699     fp->block_address = block_address;
700     fp->block_offset = block_offset;
701     return 0;
702 }