/**
    Core Foundation Emulation Library
    ---------------------------------

    A source-compatible emulation of the CoreFoundation framework based
    upon the GNUstep Base Library.

    Copyright (C) 2007 Christopher Armstrong 

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef e_CFBASE_H //hys
#define e_CFBASE_H

#ifndef __TYPES_H
#include <CoreFoundation/Types.h>
#endif

/* Basic types */
typedef UInt32   CFIndex;
typedef UInt32  CFOptionFlags;
typedef UInt32  CFTypeID;

struct CFRange
{
  CFIndex location;
  CFIndex length;
};
typedef struct CFRange CFRange;

enum CFComparisonResult 
{
  kCFCompareLessThan = -1,
  kCFCompareEqualTo = 0,
  kCFCompareGreaterThan = 1
};
typedef enum CFComparisonResult CFComparisonResult;

enum 
{
  kCFNotFound = -1
};

struct __CFType;
struct __CFAllocator;

typedef const struct __CFType *CFTypeRef;
typedef const struct __CFAllocator *CFAllocatorRef;

typedef const struct __CFString *CFStringRef;
typedef struct __CFString *CFMutableStringRef;

typedef const void *(*CFAllocatorRetainCallBack)(const void *info);
typedef void (*CFAllocatorReleaseCallBack)(const void *info);
typedef void *(*CFAllocatorAllocateCallBack)(CFIndex allocSize,
  CFOptionFlags hint, void *info);
typedef CFStringRef (*CFAllocatorCopyDescriptionCallBack)
  (const void *info);
typedef void (*CFAllocatorDeallocateCallBack)
  (void *ptr, void *info);
typedef CFIndex (*CFAllocatorPreferredSizeCallBack)
  (CFIndex size, CFOptionFlags hint, void *info);
typedef void *(*CFAllocatorReallocateCallBack)
  (void *ptr, CFIndex newsize, CFOptionFlags flags, void *info);

struct CFAllocatorContext 
{
  CFIndex version;
  void *info;
  CFAllocatorRetainCallBack retain;
  CFAllocatorReleaseCallBack release;
  CFAllocatorCopyDescriptionCallBack copyDescription;
  CFAllocatorAllocateCallBack allocate;
  CFAllocatorReallocateCallBack reallocate;
  CFAllocatorDeallocateCallBack deallocate;
  CFAllocatorPreferredSizeCallBack preferredSize;
};
typedef struct CFAllocatorContext CFAllocatorContext;

/* CFAllocator Functions */

void *CFAllocatorAllocate(
  CFAllocatorRef allocator, 
  CFIndex size, 
  CFOptionFlags hint
  );

CFAllocatorRef CFAllocatorCreate(
  CFAllocatorRef allocator,
  CFAllocatorContext *context
  );

void CFAllocatorDeallocate(
  CFAllocatorRef allocator,
  void *ptr
  );

void CFAllocatorGetContext(
  CFAllocatorRef allocator,
  CFAllocatorContext *context
  );

CFAllocatorRef CFAllocatorGetDefault();

CFIndex CFAllocatorGetPreferredSizeForSize(
  CFAllocatorRef allocator,
  CFIndex size,
  CFOptionFlags hint
  );

CFTypeID CFAllocatorGetTypeID();

void *CFAllocatorReallocate(
  CFAllocatorRef allocator,
  void *ptr,
  CFIndex newsize,
  CFOptionFlags hint
  );

void CFAllocatorSetDefault(
  CFAllocatorRef allocator
  );

const CFAllocatorRef kCFAllocatorDefault;
const CFAllocatorRef kCFAllocatorSystemDefault;
const CFAllocatorRef kCFAllocatorMalloc;
const CFAllocatorRef kCFAllocatorMallocZone;
const CFAllocatorRef kCFAllocatorNull;
const CFAllocatorRef kCFAllocatorUseContext;

/* CFType Functions */

CFTypeRef CFRetain(
  CFTypeRef cf
  );

void CFRelease(
  CFTypeRef cf
  );

CFAllocatorRef CFGetAllocator(
  CFTypeRef ref
  );

CFIndex CFGetRetainCount(
  CFTypeRef cf
  );

CFTypeID CFGetTypeID(
  CFTypeRef cf
  );

/* CFRange Functions */
static inline CFRange CFRangeMake(CFIndex location, CFIndex length)
{
  CFRange range;
  range.location = location;
  range.length = length;
  return range;
}

#endif
