Exemple #1
0
PyObject *py_ped_unit_get_size(PyObject *s, PyObject *args) {
    long long ret = -1;
    PedDevice *dev = NULL;
    int unit;

    if (!PyArg_ParseTuple(args, "i", &unit))
        return NULL;

    if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) {
        PyErr_SetString(PyExc_ValueError, "Invalid unit provided.");
        return NULL;
    }

    dev = _ped_Device2PedDevice(s);
    if (dev == NULL) {
        return NULL;
    }

    ret = ped_unit_get_size(dev, unit);
    if (ret == 0) {
        if (partedExnRaised) {
            partedExnRaised = 0;

            if (!PyErr_Occurred()) {
                PyErr_SetString(PyExc_ValueError, partedExnMessage);
            }
        } else {
            PyErr_SetString(PyExc_ValueError, "Could not get size");
        }

        return NULL;
    }

    return PyLong_FromLong(ret);
}
Exemple #2
0
/**
 * If \p str contains a valid description of a location on \p dev, then
 * \p *sector is modified to describe the location and a geometry is created
 * in \p *range describing a 2 units large area centered on \p *sector.  If the
 * \p range as described here would be partially outside the device \p dev, the
 * geometry returned is the intersection between the former and the whole
 * device geometry.  If no units are specified, then the default unit is
 * assumed.
 *
 * \throws PED_EXCEPTION_ERROR if \p str contains invalid description of a
 * location
 * \throws PED_EXCEPTION_ERROR if location described by \p str
 * is outside of the device \p dev->path
 *
 * \return \c 1 if \p str is a valid location description, \c 0 otherwise.
 */
int
ped_unit_parse_custom (const char* str, const PedDevice* dev, PedUnit unit,
		       PedSector* sector, PedGeometry** range)
{
	char*     copy;
	char*     suffix;
	double    num;
	long long unit_size;
	PedSector radius;

	if (is_chs (str))
		return parse_chs (str, dev, sector, range);

	copy = ped_strdup (str);
	if (!copy)
		goto error;
	strip_string (copy);

	suffix = find_suffix (copy);
	unit = parse_unit_suffix (suffix, unit);
	suffix[0] = 0;

	if (sscanf (copy, "%lf", &num) != 1) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Invalid number."));
		goto error_free_copy;
	}
        if (num > 0 && num < 1) {
            ped_exception_throw (
                    PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
                    _("Use a smaller unit instead of a value < 1"));
            goto error_free_copy;
        }

	unit_size = ped_unit_get_size (dev, unit);
	radius = (ped_div_round_up (unit_size, dev->sector_size) / 2) - 1;
	if (radius < 0)
		radius = 0;
	/* If the user specifies units in a power of 2, e.g., 4MiB, as in
	       parted -s -- $dev mklabel gpt mkpart P-NAME 4MiB -34s
	   do not use 4MiB as the range.  Rather, presume that they
	   are specifying precisely the starting or ending number,
	   and treat "4MiB" just as we would treat "4194304B".  */
	if (is_power_of_2 (unit_size))
		radius = 0;

	*sector = num * unit_size / dev->sector_size;
	/* negative numbers count from the end */
	if (copy[0] == '-')
		*sector += dev->length;
	if (range) {
		*range = geometry_from_centre_radius (dev, *sector, radius);
		if (!*range) {
			ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The location %s is outside of the "
				  "device %s."),
				str, dev->path);
			goto error_free_copy;
		}
	}
	*sector = clip (dev, *sector);

	free (copy);
	return 1;

error_free_copy:
	free (copy);
error:
	*sector = 0;
	if (range)
		*range = NULL;
	return 0;
}
Exemple #3
0
/**
 * \brief Get a string that describes the location of the \p byte on
 * device \p dev.
 *
 * The string is described with the desired \p unit.
 * The returned string must be freed with free().
 */
char*
ped_unit_format_custom_byte (const PedDevice* dev, PedSector byte, PedUnit unit)
{
	char buf[100];
	PedSector sector = byte / dev->sector_size;
	double d, w;
	int p;

	PED_ASSERT (dev != NULL);

	/* CHS has a special comma-separated format. */
	if (unit == PED_UNIT_CHS) {
		const PedCHSGeometry *chs = &dev->bios_geom;
		snprintf (buf, 100, "%lld,%lld,%lld",
			  sector / chs->sectors / chs->heads,
			  (sector / chs->sectors) % chs->heads,
			  sector % chs->sectors);
		return ped_strdup (buf);
	}

	/* Cylinders, sectors and bytes should be rounded down... */
	if (unit == PED_UNIT_CYLINDER
	    || unit == PED_UNIT_SECTOR
	    || unit == PED_UNIT_BYTE) {
		snprintf (buf, 100, "%lld%s",
			  byte / ped_unit_get_size (dev, unit),
			  ped_unit_get_name (unit));
		return ped_strdup (buf);
	}

        if (unit == PED_UNIT_COMPACT) {
                if (byte >= 10LL * PED_TERABYTE_SIZE)
                        unit = PED_UNIT_TERABYTE;
                else if (byte >= 10LL * PED_GIGABYTE_SIZE)
                        unit = PED_UNIT_GIGABYTE;
                else if (byte >= 10LL * PED_MEGABYTE_SIZE)
                        unit = PED_UNIT_MEGABYTE;
                else if (byte >= 10LL * PED_KILOBYTE_SIZE)
                        unit = PED_UNIT_KILOBYTE;
                else
                        unit = PED_UNIT_BYTE;
	}

	/* IEEE754 says that 100.5 has to be rounded to 100 (by printf) */
	/* but 101.5 has to be rounded to 102... so we multiply by 1+E. */
	/* This just divide by 2 the natural IEEE754 extended precision */
	/* and won't cause any trouble before 1000 TB */
	d = ((double)byte / ped_unit_get_size (dev, unit))
	    * (1. + DBL_EPSILON);
	w = d + ( (d < 10. ) ? 0.005 :
		  (d < 100.) ? 0.05  :
			       0.5  );
	p = (w < 10. ) ? 2 :
	    (w < 100.) ? 1 :
			 0 ;

#ifdef __BEOS__
	snprintf (buf, 100, "%.*f%s", p, d, ped_unit_get_name(unit));
#else
	snprintf (buf, 100, "%1$.*2$f%3$s", d, p, ped_unit_get_name (unit));
#endif

	return ped_strdup (buf);
}