Exemple #1
0
static launch_data_t
python2launch(PyObject* object)
{
	launch_data_t result;

	if (PyDict_Check(object)) {
		/* PyMapping_Check doesn't work because a lot of sequence types
		 * are mappings as wel to support extended slices a[i:j:k]
		 */
		return pythondict2launch(object);
	} else if (PySequence_Check(object)) {
		return pythonarray2launch(object);
	} else if (PyInt_Check(object)) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}
	} else if (PyLong_Check(object)) {
		long long value = PyLong_AsLongLong(object);

		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (PyString_Check(object)) {
		char* value = PyString_AsString(object);

		result = launch_data_alloc(LAUNCH_DATA_STRING);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_string(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == file_descriptor_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_FD);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_fd(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == errno_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_ERRNO);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_errno(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (object->ob_type->tp_as_buffer != NULL) {
		PyBufferProcs* bp = object->ob_type->tp_as_buffer;
		void* ptr;
		size_t size;

		size = bp->bf_getreadbuffer(object, 0, &ptr);
		if (size == (size_t)-1) {
			return NULL;
		}

		result = launch_data_alloc(LAUNCH_DATA_OPAQUE);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_opaque(result, ptr, size)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else {
		PyErr_Format(PyExc_TypeError,
			"Don't know how to convert object of type %s to launch",
			object->ob_type->tp_name);
		return NULL;
	}
}
launch_data_t GTMLaunchDataCreateFromCFType(CFTypeRef cf_type_ref,
                                            CFErrorRef *error) {
  launch_data_t result = NULL;
  CFErrorRef local_error = NULL;
  if (cf_type_ref == NULL) {
    local_error = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                    CFSTR("NULL CFType"));
    goto exit;
  }

  CFTypeID cf_type = CFGetTypeID(cf_type_ref);
  if (cf_type == CFStringGetTypeID()) {
    CFIndex length = CFStringGetLength(cf_type_ref);
    CFIndex max_length
      = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
    char *buffer = calloc(max_length, sizeof(char));
    size_t buffer_size = max_length * sizeof(char);
    if (buffer) {
      if (CFStringGetCString(cf_type_ref,
                             buffer,
                             buffer_size,
                             kCFStringEncodingUTF8)) {
        result = launch_data_alloc(LAUNCH_DATA_STRING);
        launch_data_set_string(result, buffer);
      } else {
        local_error
          = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                              CFSTR("CFStringGetCString failed %@"),
                                              cf_type_ref);
      }
      free(buffer);
    } else {
      local_error = GTMCFLaunchCreateUnlocalizedError(ENOMEM,
                                                      CFSTR("calloc of %zu failed"),
                                                      buffer_size);
    }
  } else if (cf_type == CFBooleanGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_BOOL);
    launch_data_set_bool(result, CFBooleanGetValue(cf_type_ref));
  } else if (cf_type == CFArrayGetTypeID()) {
    CFIndex count = CFArrayGetCount(cf_type_ref);
    result = launch_data_alloc(LAUNCH_DATA_ARRAY);
    for (CFIndex i = 0; i < count; i++) {
      CFTypeRef array_value = CFArrayGetValueAtIndex(cf_type_ref, i);
      if (array_value) {
        launch_data_t launch_value
          = GTMLaunchDataCreateFromCFType(array_value, &local_error);
        if (local_error) break;
        launch_data_array_set_index(result, launch_value, i);
      }
    }
  } else if (cf_type == CFDictionaryGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
    GTMCFToLDictContext context = { result, &local_error };
    CFDictionaryApplyFunction(cf_type_ref,
                              GTMConvertCFDictEntryToLaunchDataDictEntry,
                              &context);
  } else if (cf_type == CFDataGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_OPAQUE);
    launch_data_set_opaque(result,
                           CFDataGetBytePtr(cf_type_ref),
                           CFDataGetLength(cf_type_ref));
  } else if (cf_type == CFNumberGetTypeID()) {
    CFNumberType cf_number_type = CFNumberGetType(cf_type_ref);
    switch (cf_number_type) {
      case kCFNumberSInt8Type:
      case kCFNumberSInt16Type:
      case kCFNumberSInt32Type:
      case kCFNumberSInt64Type:
      case kCFNumberCharType:
      case kCFNumberShortType:
      case kCFNumberIntType:
      case kCFNumberLongType:
      case kCFNumberLongLongType:
      case kCFNumberCFIndexType:
      case kCFNumberNSIntegerType:{
        long long value;
        if (CFNumberGetValue(cf_type_ref, kCFNumberLongLongType, &value)) {
          result = launch_data_alloc(LAUNCH_DATA_INTEGER);
          launch_data_set_integer(result, value);
        } else {
          local_error
            = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                CFSTR("Unknown to convert: %@"),
                                                cf_type_ref);
        }
        break;
      }

      case kCFNumberFloat32Type:
      case kCFNumberFloat64Type:
      case kCFNumberFloatType:
      case kCFNumberDoubleType:
      case kCFNumberCGFloatType: {
        double value;
        if (CFNumberGetValue(cf_type_ref, kCFNumberDoubleType, &value)) {
          result = launch_data_alloc(LAUNCH_DATA_REAL);
          launch_data_set_real(result, value);
        } else {
          local_error
            = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                CFSTR("Unknown to convert: %@"),
                                                cf_type_ref);
        }
        break;
      }

      default:
        local_error
          = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                              CFSTR("Unknown CFNumberType %lld"),
                                              (long long)cf_number_type);
        break;
    }
  } else {
    local_error
      = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                          CFSTR("Unknown CFTypeID %lu"),
                                          cf_type);
  }

exit:
  if (error) {
    *error = local_error;
  } else if (local_error) {
#ifdef DEBUG
    CFShow(local_error);
#endif //  DEBUG
    CFRelease(local_error);
  }
  return result;
}