1 /*
2  *  linux/fs/hfsplus/brec.c
3  *
4  * Copyright (C) 2001
5  * Brad Boyer (flar@allandria.com)
6  * (C) 2003 Ardis Technologies <roman@ardistech.com>
7  *
8  * Handle individual btree records
9  */
10 
11 #include "hfsplus_fs.h"
12 #include "hfsplus_raw.h"
13 
14 /* Get the length and offset of the given record in the given node */
hfsplus_brec_lenoff(hfsplus_bnode * node,u16 rec,u16 * off)15 u16 hfsplus_brec_lenoff(hfsplus_bnode *node, u16 rec, u16 *off)
16 {
17 	u16 retval[2];
18 	u16 dataoff;
19 
20 	dataoff = node->tree->node_size - (rec + 2) * 2;
21 	hfsplus_bnode_readbytes(node, retval, dataoff, 4);
22 	*off = be16_to_cpu(retval[1]);
23 	return be16_to_cpu(retval[0]) - *off;
24 }
25 
26 /* Get the length of the key from a keyed record */
hfsplus_brec_keylen(hfsplus_bnode * node,u16 rec)27 u16 hfsplus_brec_keylen(hfsplus_bnode *node, u16 rec)
28 {
29 	u16 klsz, retval, recoff;
30 	unsigned char buf[2];
31 
32 	if ((node->kind != HFSPLUS_NODE_NDX)&&(node->kind != HFSPLUS_NODE_LEAF))
33 		return 0;
34 
35 	klsz = (node->tree->attributes & HFSPLUS_TREE_BIGKEYS) ? 2 : 1;
36 	if ((node->kind == HFSPLUS_NODE_NDX) &&
37 	   !(node->tree->attributes & HFSPLUS_TREE_VAR_NDXKEY_SIZE)) {
38 		retval = node->tree->max_key_len;
39 	} else {
40 		recoff = hfsplus_bnode_read_u16(node, node->tree->node_size - (rec + 1) * 2);
41 		if (!recoff)
42 			return 0;
43 		hfsplus_bnode_readbytes(node, buf, recoff, klsz);
44 		if (klsz == 1)
45 			retval = buf[0];
46 		else
47 			retval = be16_to_cpu(*(u16 *)buf);
48 	}
49 	return (retval + klsz + 1) & 0xFFFE;
50 }
51