/*

  sshadt_structs.h

  Author: Antti Huima <huima@ssh.fi>

  Copyright (c) 1999 SSH Communications Security, Finland
  All rights reserved.

  Created Tue Oct 19 19:16:12 1999.

  */

#ifndef SSHADT_STRUCTS_H_INCLUDED
#define SSHADT_STRUCTS_H_INCLUDED

#ifndef SSHADT_INSIDE_SSHADT_H
#error  sshadt_structs.h improperly included
#endif

#include "sshfastalloc.h"

struct ssh_adt_container_pars;

typedef struct {
  /* $$METHODSDECL */
  /* DO NOT EDIT THIS, edit METHODS.h instead. */
  void (* container_init)
    (SshADTContainer, struct ssh_adt_container_pars *);
  void (* clear)
    (SshADTContainer);
  void (* destroy)
    (SshADTContainer);
  SshADTHandle (* insert_at)
    (SshADTContainer, SshADTRelativeLocation, SshADTHandle, void *);
  SshADTHandle (* insert_to)
    (SshADTContainer, SshADTAbsoluteLocation, void *);
  SshADTHandle (* alloc_n_at)
    (SshADTContainer, SshADTRelativeLocation, SshADTHandle, size_t);
  SshADTHandle (* alloc_n_to)
    (SshADTContainer, SshADTAbsoluteLocation, size_t);
  SshADTHandle (* put_n_at)
    (SshADTContainer, SshADTRelativeLocation, SshADTHandle, size_t, void *);
  SshADTHandle (* put_n_to)
    (SshADTContainer, SshADTAbsoluteLocation, size_t, void *);
  void * (* get)
    (SshADTContainer, SshADTHandle);
  size_t (* num_objects)
    (SshADTContainer);
  SshADTHandle (* get_handle_to)
    (SshADTContainer, void *);
  SshADTHandle (* get_handle_to_location)
    (SshADTContainer, SshADTAbsoluteLocation);
  SshADTHandle (* next)
    (SshADTContainer, SshADTHandle);
  SshADTHandle (* previous)
    (SshADTContainer, SshADTHandle);
  SshADTHandle (* enumerate_start)
    (SshADTContainer);
  SshADTHandle (* enumerate_next)
    (SshADTContainer, SshADTHandle);
  SshADTHandle (* get_handle_to_equal)
    (SshADTContainer, void *);
  void * (* reallocate)
    (SshADTContainer, void *, size_t);
  void * (* detach)
    (SshADTContainer, SshADTHandle);
  void (* delete)
    (SshADTContainer, SshADTHandle);
  /* $$ENDMETHODSDECL */
} SshADTMethods;

typedef struct {
  SshADTMethods methods;
  size_t internal_header_size;
  SshUInt32 flags;
} SshADTStaticData;

struct ssh_adt_hooks;

typedef struct {
  /* The application supplied methods. */
  SshADTCompareFunc compare;
  SshADTCopyFunc copy;
  SshADTDuplicateFunc duplicate;
  SshADTDestroyFunc destroy;
  SshADTInitFunc init;
  SshADTHashFunc hash;

  /* Context common to all methods. */
  void *context;  
} SshADTAppMethods;

typedef struct {
  SshADTAppMethods app_methods;

  /* `default_object_size' is used only when SSH_ADT_FLAG_ALLOCATE is
     set. In that case it is the default size of objects to allocate. */
  size_t default_object_size;

  /* `header_offset' is the difference between header and object pointers.
     It is set by the application if an inlined header is used, 
     and by the library if library allocated objects without inlined
     headers are used. Must be signed (SshInt32) because the offset
     can be negative. */
  SshInt32 header_offset;
} SshADTStandardFields;

typedef struct {
  /* Number of contained objects. */
  size_t num_objects;

  /* This is used only if SSH_ADT_FLAG_FASTALLOC is defined. */
  SshFastMemoryAllocator fast_alloc;  
} SshADTAux;

struct SshADTContainerRec {
  /* Static data that is container type specific. */
  SshADTStaticData *static_data; 
  
  /* Pointer to extra data that the container wants to use. 
     Allocated and released by the container. */
  void *container_specific;

  struct ssh_adt_hooks *hooks;  /* The active hooks, or NULL if no
                                   hooks are active. */

  SshUInt32 flags;

  union {
    struct {      
      /* Used by non-proxy containers. */
      SshADTStandardFields f;
      SshADTAux aux;
    } nonproxy;
  } u;
};

#define SSH_ADT_DEFAULT_SIZE(c) ((c)->u.nonproxy.f.default_object_size)

#endif /* SSHADT_STRUCTS_H_INCLUDED */
