📄 record.c
字号:
while (start < end) { mid = (start + end) >> 1; p = btree_key_by_index(tree, buf, mid); if (!p) HFSP_ERROR(-1, "record_init_key: unexpected error"); p = readkey (p, curr_key); if (!p) HFSP_ERROR(-1, "record_init_cat_key: unexpected error"); comp = key_compare(curr_key, key); if (comp > 0) start = mid + 1; else if (comp < 0) end = mid; else break; } if (!p) // Empty tree, fascinating ... HFSP_ERROR(ENOENT, "record_init_key: unexpected empty node"); *keyind = mid; *node_index = buf->index; if (!comp) // found something ... return p; } HFSP_ERROR(ENOENT, NULL); fail: return NULL;}/* intialize the record by searching for the given key in the btree. * * r is umodified on error. */static intrecord_init_key(record* r, btree* tree, hfsp_cat_key* key){ int keyind; UInt16 node_index; void *p = record_find_key(tree, key, &keyind, &node_index); if (p) { r -> tree = tree; r -> node_index= node_index; r -> keyind = keyind; r -> key = *key; // Better use a record_key_copy ... p = record_readentry(p, &r->record); if (!p) HFSP_ERROR(-1, "record_init_key: unexpected error"); return 0; } fail: return -1;}/* intialize the extent_record to the extent identified by the * (first) blockindex. * * forktype: either HFSP_EXTEND_DATA or HFSP_EXTEND_RSRC */int record_init_file(extent_record* r, btree* tree, UInt8 forktype, UInt32 fileId, UInt32 blockindex){ int keyind; UInt16 node_index; hfsp_extent_key key = { 10, forktype, 0, fileId, blockindex }; void *p = record_find_key(tree, &key, &keyind, &node_index); if (p) { r -> tree = tree; r -> node_index= node_index; r -> keyind = keyind; r -> key = key; // Better use a record_key_copy ... p = volume_readextent(p, r->extent); if (!p) HFSP_ERROR(-1, "record_init_file: unexpected error"); return 0; } fail: return -1;}/* intialize the record to the folder identified by cnid */int record_init_cnid(record* r, btree* tree, UInt32 cnid){ hfsp_cat_key thread_key; // the thread is the first record thread_key.key_length = 6; // null name (like '.' in unix ) thread_key.parent_cnid = cnid; thread_key.name.strlen = 0; return record_init_key(r, tree, &thread_key);}/* intialize the record to the first record of the parent. */int record_init_parent(record* r, record* parent){ if (parent->record.type == HFSP_FOLDER) return record_init_cnid(r, parent->tree, parent->record.u.folder.id); else if(parent->record.type == HFSP_FOLDER_THREAD) { if (r != parent) *r = *parent; // The folder thread is in fact the first entry, like '.' return 0; } HFSP_ERROR(EINVAL, "record_init_parent: parent is neither folder nor folder thread."); fail: return EINVAL;}/* find correct node record for given node and *pindex. * * index of record in this (or next) node * */static node_buf* prepare_next(btree* tree, UInt16 node_index, UInt16* pindex){ node_buf* buf = btree_node_by_index(tree, node_index); btree_node_desc* desc = &buf->desc; UInt32 numrec = desc->num_rec; if (*pindex >= numrec) // move on to next node { UInt16 next = desc->next; *pindex = 0; if (!next /* is there a next node ? */ || !( buf = btree_node_by_index(tree, next))) return NULL; } return buf;}/* move record foreward to next entry. * * In case of an error the value of *r is undefined ! */int record_next(record* r){ btree* tree = r->tree; UInt16 index = r->keyind +1; UInt32 parent; node_buf* buf = prepare_next(tree, r->node_index, &index); if (!buf) return ENOENT; // No (more) such file or directory parent = r->key.parent_cnid; if (record_init(r, tree, buf, index)) return -1; if (r->key.parent_cnid != parent || // end of current directory index != r->keyind) // internal error ? return ENOENT; // No (more) such file or directory return 0;}/* move record foreward to next extent record. * * In case of an error the value of *r is undefined ! */int record_next_extent(extent_record* r){ btree* tree = r->tree; UInt16 index = r->keyind +1; UInt32 file_id; UInt8 fork_type; node_buf* buf = prepare_next(tree, r->node_index, &index); if (!buf) return ENOENT; // No (more) such file or directory file_id = r->key.file_id; fork_type = r->key.fork_type; if (record_init_extent(r, tree, buf, index)) return -1; if (r->key.file_id != file_id || // end of current file r->key.fork_type != fork_type || // end of current fork index != r->keyind) // internal error ? return ENOENT; // No (more) such file or directory return 0;}/* intialize the record by searching for the given string in the given folder. * * parent and r may be the same. */int record_init_string_parent(record* r, record* parent, char* name){ hfsp_cat_key key; if (parent->record.type == HFSP_FOLDER) key.parent_cnid = parent->record.u.folder.id; else if(parent->record.type == HFSP_FOLDER_THREAD) key.parent_cnid = parent->key.parent_cnid; else HFSP_ERROR(-1, "record_init_string_parent: parent is not a folder."); key.key_length = 6 + unicode_asc2uni(&key.name,name); // 6 for minumum size return record_init_key(r, parent->tree, &key); fail: return -1;}/* move record up in folder hierarchy (if possible) */int record_up(record* r){ if (r->record.type == HFSP_FOLDER) { // locate folder thread if (record_init_cnid(r, r->tree, r->record.u.folder.id)) return -1; } else if(r->record.type == HFSP_FOLDER_THREAD) { // do nothing were are already where we want to be } else HFSP_ERROR(-1, "record_up: record is neither folder nor folder thread."); if(r->record.type != HFSP_FOLDER_THREAD) HFSP_ERROR(-1, "record_up: unable to locate parent"); return record_init_cnid(r, r->tree, r->record.u.thread.parentID); fail: return -1;}#ifdef DEBUG/* print Quickdraw Point */static void record_print_Point(Point* p){ printf("[ v=%d, h=%d ]", p->v, p->h);}/* print Quickdraw Rect */static void record_print_Rect(Rect* r){ printf("[ top=%d, left=%d, bottom=%d, right=%d ]", r->top, r->left, r->bottom, r->right);}/* print the key of a record */static void record_print_key(hfsp_cat_key* key){ char buf[255]; // mh this _might_ overflow unicode_uni2asc(buf, &key->name, 255); printf("parent cnid : %ld\n", key->parent_cnid); printf("name : %s\n", buf);}/* print permissions */static void record_print_perm(hfsp_perm* perm){ printf("owner :\t%ld\n", perm->owner); printf("group :\t%ld\n", perm->group); printf("perm :\t0x%lX\n",perm->mode); printf("dev :\t%ld\n", perm->dev);}/* print Directory info */static void record_print_DInfo(DInfo* dinfo){ printf( "frRect :\t"); record_print_Rect(&dinfo->frRect); printf("\nfrFlags :\t0X%X\n", dinfo->frFlags); printf( "frLocation :\t"); record_print_Point(&dinfo->frLocation); printf("\nfrView :\t0X%X\n", dinfo->frView);}/* print extended Directory info */static void record_print_DXInfo(DXInfo* xinfo){ printf( "frScroll :\t"); record_print_Point(&xinfo->frScroll); printf("\nfrOpenChain :\t%ld\n", xinfo->frOpenChain); printf( "frUnused :\t%d\n", xinfo->frUnused); printf( "frComment :\t%d\n", xinfo->frComment); printf( "frPutAway :\t%ld\n", xinfo->frPutAway);}static void record_print_folder(hfsp_cat_folder* folder){ printf("flags :\t0x%X\n", folder->flags); printf("valence :\t0x%lX\n", folder->valence); printf("id :\t%ld\n", folder->id); record_print_perm (&folder->permissions); record_print_DInfo (&folder->user_info); record_print_DXInfo (&folder->finder_info); printf("text_encoding :\t0x%lX\n", folder->text_encoding); printf("reserved :\t0x%lX\n", folder->reserved);}/* print File info */static void record_print_FInfo(FInfo* finfo){ printf( "fdType :\t%4.4s\n", (char*) &finfo->fdType); printf( "fdCreator :\t%4.4s\n", (char*) &finfo->fdCreator); printf( "fdFlags :\t0X%X\n", finfo->fdFlags); printf( "fdLocation :\t"); record_print_Point(&finfo->fdLocation); printf("\nfdFldr :\t%d\n", finfo->fdFldr);} /* print extended File info */static void record_print_FXInfo(FXInfo* xinfo){ printf( "fdIconID :\t%d\n", xinfo->fdIconID); // xinfo -> fdUnused; printf( "fdComment :\t%d\n", xinfo->fdComment); printf( "fdPutAway :\t%ld\n", xinfo->fdPutAway);} /* print folder entry *//* print file entry */static void record_print_file(hfsp_cat_file* file){ printf("flags :\t0x%X\n", file->flags); printf("reserved1 :\t0x%lX\n", file->reserved1); printf("id :\t%ld\n", file->id); record_print_perm (&file->permissions); record_print_FInfo (&file->user_info); record_print_FXInfo (&file->finder_info); printf("text_encoding :\t0x%lX\n", file->text_encoding); printf("reserved :\t0x%lX\n", file->reserved2); printf("Datafork:\n"); volume_print_fork (&file->data_fork); printf("Rsrcfork:\n"); volume_print_fork (&file->res_fork);}/* print info for a file or folder thread */static void record_print_thread(hfsp_cat_thread* entry){ char buf[255]; // mh this _might_ overflow unicode_uni2asc(buf, &entry->nodeName, 255); printf("parent cnid :\t%ld\n", entry->parentID); printf("name :\t%s\n" , buf);}/* print the information for a record */static void record_print_entry(hfsp_cat_entry* entry){ switch (entry->type) { case HFSP_FOLDER: printf("=== Folder ===\n"); return record_print_folder(&entry->u.folder); case HFSP_FILE: printf("=== File ===\n"); return record_print_file (&entry->u.file); case HFSP_FOLDER_THREAD: printf("=== Folder Thread ===\n"); return record_print_thread(&entry->u.thread); case HFSP_FILE_THREAD: printf("=== File Thread ==\n"); return record_print_thread(&entry->u.thread); default: printf("=== Unknown Record Type ===\n"); } ;} /* Dump all the record information to stdout */void record_print(record* r){ printf ("keyind : %u\n", r->keyind); record_print_key (&r->key); record_print_entry(&r->record);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -