/*
 * Copyright (c) 2003-2012
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 *
 * $Id: frame.h 2594 2012-10-19 17:28:49Z brachman $
 */

/*****************************************************************************
 * COPYRIGHT AND PERMISSION NOTICE
 * 
 * Copyright (c) 2001-2003 The Queen in Right of Canada
 * 
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, and/or sell
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, provided that the above copyright notice(s) and this
 * permission notice appear in all copies of the Software and that both the
 * above copyright notice(s) and this permission notice appear in supporting
 * documentation.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE 
 * BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
 * SOFTWARE.
 * 
 * Except as contained in this notice, the name of a copyright holder shall not
 * be used in advertising or otherwise to promote the sale, use or other
 * dealings in this Software without prior written authorization of the
 * copyright holder.
 ***************************************************************************/

#ifndef _FRAME_H_
#define _FRAME_H_

#define HAVE_FRAME	1

typedef unsigned char Fm_ui8;
typedef unsigned int Fm_ui32;

/* Bit flags */
enum {
  FM_FRAME_UNIT_FREE = 1,		/* Can free individual allocations */
  FM_FRAME_MEM_ZAP   = 2,		/* Zero memory when freeing it */
  FM_FRAME_FLAG_MASK = 0x03
};

/* Memory allocation sources that look like malloc/free */
typedef struct Fm_mem_funcs_standard {
  void *(*malloc)(size_t size);
  void (*free)(void *ptr);
} Fm_mem_funcs_standard;

/*
 * Memory allocation sources that look like malloc/free but which
 * also take a private data pointer.
 */
typedef struct Fm_mem_funcs_dataptr {
  void *(*malloc)(void *dataptr, size_t size);
  void (*free)(void *dataptr, void *ptr);
  void *dataptr;
} Fm_mem_funcs_dataptr;

/*
 * This describes the source of memory allocations for a frame.
 * There are three types:
 *   MEM_SRC_DEFAULT:  this allows the package to select its own source
 *   MEM_SRC_STANDARD: the caller provides Fm_mem_funcs_standard
 *   MEM_SRC_DATAPTR:  the caller provides Fm_mem_funcs_dataptr
 * The unit_free flag indicates whether individual allocations can be
 * free (non-zero) or if all frame allocations must be freed at once (zero).
 */
typedef struct Fm_mem_src {
  enum {
	MEM_SRC_DEFAULT  = 0,
	MEM_SRC_STANDARD = 1,
	MEM_SRC_DATAPTR =  2
  } type;
  unsigned int flags;
  union {
	Fm_mem_funcs_standard *mem_funcs_standard;
	Fm_mem_funcs_dataptr *mem_funcs_dataptr;
  } u;
} Fm_mem_src;

typedef struct Frame_stats {
  int malloc_count;
  int realloc_count;
  int calloc_count;
  int free_count;
  int allocated;
} Frame_stats;

extern int disable_frame_memory;

#ifdef __cplusplus
extern "C" {
#endif

extern void *fm_new_frame(char *name, Fm_mem_src *src, unsigned int flags);
extern int fm_push_new_frame(char *name, Fm_mem_src *src, unsigned int flags);
extern int fm_set_frame_name(void *frame, char *new_name);
extern char *fm_get_frame_name(void *frame);
extern unsigned int fm_set_default_frame_flags(unsigned int flags);
extern unsigned int fm_get_default_frame_flags(void);
extern unsigned int fm_get_frame_flags(void *frame);
extern unsigned int fm_set_frame_flags(void *frame, unsigned int flags);
extern int fm_push_frame(void *frame);
extern void *fm_pop_frame(void);
extern int fm_exchange_frames(void);
extern int fm_unite_frames(void *frame1, void *frame2);
extern int fm_free(void *ptr);
extern int fm_close_frame(void *frame);
extern int fm_close_frames(void);
extern int fm_close_all_frames(void);
extern int fm_free_frame(void *frame);
extern int fm_free_frames(void);
extern int fm_free_all_frames(void);
extern void *fm_malloc(size_t req_size);
extern void *fm_malloc_src(Fm_mem_src *src, size_t req_size);
extern void *fm_frame_malloc(void *frame, size_t req_size);
extern void *fm_frame_malloc_src(void *frame, Fm_mem_src *src,
								 size_t req_size);
extern void *fm_calloc(size_t nmemb, size_t req_memb_size);
extern void *fm_calloc_src(Fm_mem_src *src, size_t nmemb,
						   size_t req_memb_size);
extern void *fm_frame_calloc(void *frame, size_t nmemb, size_t req_memb_size);
extern void *fm_frame_calloc_src(void *frame, Fm_mem_src *src, size_t nmemb,
                    size_t req_memb_size);
extern void *fm_realloc(void *ptr, size_t req_size);
extern void *fm_realloc_src(Fm_mem_src *src, void *ptr, size_t req_size);
extern void *fm_frame_realloc(void *frame, void *ptr, size_t req_size);
extern void *fm_frame_realloc_src(void *frame, Fm_mem_src *src, void *ptr,
					size_t req_size);
extern char *fm_strdup(const char *str);
extern Frame_stats *fm_get_stats(void);

#ifdef __cplusplus
}
#endif

#endif
