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); }
/** * 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; }
/** * \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); }