//===-- CFCMutableDictionary.cpp --------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CFCMutableDictionary.h"
#include "CFCString.h"
//----------------------------------------------------------------------
// CFCString constructor
//----------------------------------------------------------------------
CFCMutableDictionary::CFCMutableDictionary(CFMutableDictionaryRef s)
    : CFCReleaser<CFMutableDictionaryRef>(s) {}

//----------------------------------------------------------------------
// CFCMutableDictionary copy constructor
//----------------------------------------------------------------------
CFCMutableDictionary::CFCMutableDictionary(const CFCMutableDictionary &rhs)
    : CFCReleaser<CFMutableDictionaryRef>(rhs) {}

//----------------------------------------------------------------------
// CFCMutableDictionary copy constructor
//----------------------------------------------------------------------
const CFCMutableDictionary &CFCMutableDictionary::
operator=(const CFCMutableDictionary &rhs) {
  if (this != &rhs)
    *this = rhs;
  return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
CFCMutableDictionary::~CFCMutableDictionary() {}

CFIndex CFCMutableDictionary::GetCount() const {
  CFMutableDictionaryRef dict = get();
  if (dict)
    return ::CFDictionaryGetCount(dict);
  return 0;
}

CFIndex CFCMutableDictionary::GetCountOfKey(const void *key) const

{
  CFMutableDictionaryRef dict = get();
  if (dict)
    return ::CFDictionaryGetCountOfKey(dict, key);
  return 0;
}

CFIndex CFCMutableDictionary::GetCountOfValue(const void *value) const

{
  CFMutableDictionaryRef dict = get();
  if (dict)
    return ::CFDictionaryGetCountOfValue(dict, value);
  return 0;
}

void CFCMutableDictionary::GetKeysAndValues(const void **keys,
                                            const void **values) const {
  CFMutableDictionaryRef dict = get();
  if (dict)
    ::CFDictionaryGetKeysAndValues(dict, keys, values);
}

const void *CFCMutableDictionary::GetValue(const void *key) const

{
  CFMutableDictionaryRef dict = get();
  if (dict)
    return ::CFDictionaryGetValue(dict, key);
  return NULL;
}

Boolean
CFCMutableDictionary::GetValueIfPresent(const void *key,
                                        const void **value_handle) const {
  CFMutableDictionaryRef dict = get();
  if (dict)
    return ::CFDictionaryGetValueIfPresent(dict, key, value_handle);
  return false;
}

CFMutableDictionaryRef CFCMutableDictionary::Dictionary(bool can_create) {
  CFMutableDictionaryRef dict = get();
  if (can_create && dict == NULL) {
    dict = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks);
    reset(dict);
  }
  return dict;
}

bool CFCMutableDictionary::AddValue(CFStringRef key, const void *value,
                                    bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Let the dictionary own the CFNumber
    ::CFDictionaryAddValue(dict, key, value);
    return true;
  }
  return false;
}

bool CFCMutableDictionary::SetValue(CFStringRef key, const void *value,
                                    bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Let the dictionary own the CFNumber
    ::CFDictionarySetValue(dict, key, value);
    return true;
  }
  return false;
}

bool CFCMutableDictionary::AddValueSInt8(CFStringRef key, int8_t value,
                                         bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueSInt8(CFStringRef key, int8_t value,
                                         bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueSInt16(CFStringRef key, int16_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueSInt16(CFStringRef key, int16_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueSInt32(CFStringRef key, int32_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueSInt32(CFStringRef key, int32_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueSInt64(CFStringRef key, int64_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueSInt64(CFStringRef key, int64_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueUInt8(CFStringRef key, uint8_t value,
                                         bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int16_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueUInt8(CFStringRef key, uint8_t value,
                                         bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int16_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueUInt16(CFStringRef key, uint16_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int32_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueUInt16(CFStringRef key, uint16_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int32_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueUInt32(CFStringRef key, uint32_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int64_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueUInt32(CFStringRef key, uint32_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // Have to promote to the next size type so things don't appear negative of
    // the MSBit is set...
    int64_t sval = value;
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // The number may appear negative if the MSBit is set in "value". Due to a
    // limitation of CFNumber, there isn't a way to have it show up otherwise
    // as of this writing.
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // The number may appear negative if the MSBit is set in "value". Due to a
    // limitation of CFNumber, there isn't a way to have it show up otherwise
    // as of this writing.
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // The number may appear negative if the MSBit is set in "value". Due to a
    // limitation of CFNumber, there isn't a way to have it show up otherwise
    // as of this writing.
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value,
                                          bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    // The number may appear negative if the MSBit is set in "value". Due to a
    // limitation of CFNumber, there isn't a way to have it show up otherwise
    // as of this writing.
    CFCReleaser<CFNumberRef> cf_number(
        ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
    if (cf_number.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_number.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr,
                                           bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCString cf_str(cstr, kCFStringEncodingUTF8);
    if (cf_str.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionaryAddValue(dict, key, cf_str.get());
      return true;
    }
  }
  return false;
}

bool CFCMutableDictionary::SetValueCString(CFStringRef key, const char *cstr,
                                           bool can_create) {
  CFMutableDictionaryRef dict = Dictionary(can_create);
  if (dict != NULL) {
    CFCString cf_str(cstr, kCFStringEncodingUTF8);
    if (cf_str.get()) {
      // Let the dictionary own the CFNumber
      ::CFDictionarySetValue(dict, key, cf_str.get());
      return true;
    }
  }
  return false;
}

void CFCMutableDictionary::RemoveAllValues() {
  CFMutableDictionaryRef dict = get();
  if (dict)
    ::CFDictionaryRemoveAllValues(dict);
}

void CFCMutableDictionary::RemoveValue(const void *value) {
  CFMutableDictionaryRef dict = get();
  if (dict)
    ::CFDictionaryRemoveValue(dict, value);
}
void CFCMutableDictionary::ReplaceValue(const void *key, const void *value) {
  CFMutableDictionaryRef dict = get();
  if (dict)
    ::CFDictionaryReplaceValue(dict, key, value);
}
