|
|
1.1 root 1: /*
2: * libhfs - library for reading and writing Macintosh HFS volumes
3: *
4: * The iterator shown here iterates over the blocks of a fork.
5: *
6: * Copyright (C) 2000 Klaus Halfmann <[email protected]>
7: * Original work by 1996-1998 Robert Leslie <[email protected]>
8: * other work 2000 from Brad Boyer ([email protected])
9: *
10: * This program is free software; you can redistribute it and/or modify
11: * it under the terms of the GNU General Public License as published by
12: * the Free Software Foundation; either version 2 of the License, or
13: * (at your option) any later version.
14: *
15: * This program is distributed in the hope that it will be useful,
16: * but WITHOUT ANY WARRANTY; without even the implied warranty of
17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: * GNU General Public License for more details.
19: *
20: * You should have received a copy of the GNU General Public License
21: * along with this program; if not, write to the Free Software
22: * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23: * MA 02110-1301, USA.
24: *
25: * $Id: blockiter.c,v 1.2 2000/10/17 05:58:46 hasi Exp $
26: */
27:
28: #include "config.h"
29: #include "libhfsp.h"
30: #include "blockiter.h"
31: #include "volume.h"
32: #include "record.h"
33: #include "btree.h"
34: #include "os.h"
35: #include "swab.h"
36: #include "hfstime.h"
37:
38: /* Initialize iterator for a given fork */
39: void
40: blockiter_init(blockiter* b, volume* vol, hfsp_fork_raw* f,
41: UInt8 forktype, UInt32 fileId)
42: {
43: b->vol = vol;
44: b->curr_block = 0;
45: b->block = 0;
46: b->max_block = f->total_blocks;
47: b->fileId = fileId;
48: b->index = 0;
49: b->file = f->extents;
50: b->e = f->extents;
51: b->forktype = forktype;
52: b->in_extent = 0;
53: }
54:
55: /* get next extent record when needed */
56: static int
57: blockiter_next_extent(blockiter *b)
58: {
59: btree* extents_tree = volume_get_extents_tree(b->vol);
60: int err;
61:
62: b->index = 0;
63: if (b->in_extent) // already using extents record ?
64: {
65: err = record_next_extent(&b->er);
66: // Hope there is no need to check this ...
67: // if (b->er.key.start_block != b->curr_block)
68: // HFSP_ERROR(ENOENT,
69: // "Extents record inconistent");
70: }
71: else
72: {
73: err = record_init_file(&b->er, extents_tree, b->forktype,
74: b->fileId, b->curr_block);
75: b->in_extent = -1; // true
76: }
77: b->e = b->er.extent;
78: return err;
79: }
80:
81: /* find next block of the fork iterating over */
82: int
83: blockiter_next(blockiter *b)
84: {
85: b->curr_block ++;
86: b->block ++;
87: if (b->curr_block >= b->max_block)
88: return -1; // end of Blocks, but no error
89: // in current part of extent ?
90: if (b->block >= b->e->block_count)
91: {
92: b->index++;
93: b->block = 0; // reset relative position
94: b->e++;
95: if (b -> index >= 8) // need to fetch another extent
96: {
97: if (blockiter_next_extent(b))
98: HFSP_ERROR(ENOENT, "Extends record not found.");
99: }
100: }
101: return 0;
102:
103: fail:
104: return -1;
105: }
106:
107: /* skip the indicated number of blocks */
108: int
109: blockiter_skip(blockiter *b, UInt32 skip)
110: {
111: while (skip > 0)
112: {
113: // Skip to skip or end of current extent
114: UInt32 diff = b->e->block_count - b->block;
115: if (skip < diff)
116: {
117: diff = skip;
118: skip = 0;
119: }
120: else
121: skip -= diff;
122: b->curr_block += diff;
123: b->block += diff;
124: if (b->curr_block >= b->max_block)
125: return -1; // end of Blocks, but no error
126: if (b->block >= b->e->block_count)
127: {
128: b->index++;
129: b->block = 0; // reset relative position
130: b->e++;
131: if (b -> index >= 8) // need to fetch another extent
132: {
133: if (blockiter_next_extent(b))
134: HFSP_ERROR(ENOENT, "Extends record not found.");
135: }
136: }
137: } // we are here when skip was null, thats ok
138: return 0;
139: fail:
140: return -1;
141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.