/*
    block.h -- block functions
    Copyright (C) 2001, 2002 Yury Umanets <torque@ukrpost.net>, see COPYING for 
    licensing and copyright details.
*/

#ifndef BLOCK_H
#define BLOCK_H

#include <dal/dal.h>

#define MAX_CHILD_SIZE(blocksize) 		((blocksize) - BLKH_SIZE)
#define MAX_FREE_SPACE(blocksize) 		MAX_CHILD_SIZE(blocksize)

#define GET_BLOCK_HEAD(bh)  			((reiserfs_block_head_t *)((bh)->data))

struct reiserfs_block_head {       
    uint16_t blk_level;
    uint16_t blk_nr_item;
    uint16_t blk_free_space;
    uint16_t blk_reserved[9];
};

typedef struct reiserfs_block_head reiserfs_block_head_t;

#define BLKH_SIZE 						(sizeof(reiserfs_block_head_t))

#define get_blkh_level(blkh) 			get_le16 (blkh, blk_level)
#define set_blkh_level(blkh, val) 		set_le16 (blkh, blk_level, val)

#define get_blkh_nr_items(blkh)			get_le16 (blkh, blk_nr_item)
#define set_blkh_nr_items(blkh, val) 	set_le16 (blkh, blk_nr_item, val)

#define get_blkh_free_space(blkh) 		get_le16 (blkh, blk_free_space)
#define set_blkh_free_space(blkh, val) 	set_le16 (blkh, blk_free_space, val)

#define is_leaf_block(blkh) \
    (get_blkh_level ((reiserfs_block_head_t *)(blkh)) == LEAF_LEVEL)
    
#define is_internal_block(blkh) \
    ((get_blkh_level (((reiserfs_block_head_t *)(blkh))) > LEAF_LEVEL) && \
    (get_blkh_level (((reiserfs_block_head_t *)(blkh))) <= MAX_HEIGHT))

#define reiserfs_block_reading_failed(blk, action) \
	do { \
    	libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL, \
			_("Reading block %lu failed."), blk); \
		action; \
	} while (0)

#define reiserfs_block_writing_failed(blk, action) \
	do { \
    	libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL, \
			_("Writing block %lu failed."), blk); \
		action; \
	} while (0)

struct reiserfs_block {
	dal_t *dal;
	
	char *data;
	uint64_t address;
};

typedef struct reiserfs_block reiserfs_block_t;

extern reiserfs_block_t *reiserfs_block_alloc(dal_t *dal, blk_t blk, char c);
extern reiserfs_block_t *reiserfs_block_realloc(reiserfs_block_t *block, blk_t blk);

extern reiserfs_block_t *reiserfs_block_alloc_with_copy(dal_t *dal, blk_t blk,
    void *data);

extern dal_t *reiserfs_block_dal(reiserfs_block_t *block);
extern void reiserfs_block_set_dal(reiserfs_block_t *block, dal_t *dal);

extern blk_t reiserfs_block_location(reiserfs_block_t *block);
extern void reiserfs_block_set_location(reiserfs_block_t *block, blk_t blk);

extern reiserfs_block_t *reiserfs_block_read(dal_t *dal, blk_t blk);
extern int reiserfs_block_write(dal_t *dal, reiserfs_block_t *block);

extern void reiserfs_block_free(reiserfs_block_t *block);

#endif

