summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
2fc7969)
Change slice format so that in addition to <start>+<length>, it is possible
to specify just <length>. This isn't needed (0+<length>) could be used
instead, but looks more pleasing if lengths are specified more frequently
on objects. Also update the various tools to correctly parse the new
syntax.
This is part of the new v0.6 format.
my $ref_str = shift;
# Check for special objects before attempting general parsing.
my $ref_str = shift;
# Check for special objects before attempting general parsing.
- if ($ref_str =~ m/^zero\[(\d+)\+(\d+)\]$/) {
- return "\0" x ($2 + 0);
+ if ($ref_str =~ m/^zero\[((\d+)\+)?(\d+)\]$/) {
+ return "\0" x ($3 + 0);
}
# Try to parse the object reference string into constituent pieces. The
}
# Try to parse the object reference string into constituent pieces. The
# If a range was specified, then only a subset of the bytes of the object
# are desired. Extract just the desired bytes.
if ($range) {
# If a range was specified, then only a subset of the bytes of the object
# are desired. Extract just the desired bytes.
if ($range) {
- if ($range !~ m/^\[(\d+)\+(\d+)\]$/) {
+ if ($range !~ m/^\[((\d+)\+)?(\d+)\]$/) {
die "Malformed object range: $range";
}
my $object_size = length $contents;
die "Malformed object range: $range";
}
my $object_size = length $contents;
- my ($start, $length) = ($1 + 0, $2 + 0);
+ my ($start, $length);
+ if ($1 ne "") {
+ ($start, $length) = ($2 + 0, $3 + 0);
+ } else {
+ ($start, $length) = (0, $3 + 0);
+ }
if ($start >= $object_size || $start + $length > $object_size) {
die "Object range $range falls outside object bounds "
. "(actual size $object_size)";
if ($start >= $object_size || $start + $length > $object_size) {
die "Object range $range falls outside object bounds "
. "(actual size $object_size)";
not fall within the original object. The slice specification should be
appended to an object name, for example:
a704eeae-97f2-4f30-91a4-d4473956366b/000001ad[264+1000]
not fall within the original object. The slice specification should be
appended to an object name, for example:
a704eeae-97f2-4f30-91a4-d4473956366b/000001ad[264+1000]
-selects only bytes 264..1263 from the original object.
+selects only bytes 264..1263 from the original object. As an
+abbreviation, the slice syntax
+ [<length>]
+is shorthand for
+ [0+<length>]
Both a checksum and a slice can be used. In this case, the checksum is
given first, followed by the slice. The checksum is computed over the
Both a checksum and a slice can be used. In this case, the checksum is
given first, followed by the slice. The checksum is computed over the
This represents an object consisting entirely of zeroes. The zero
object must have a slice specification appended to indicate the size of
the object. For example
This represents an object consisting entirely of zeroes. The zero
object must have a slice specification appended to indicate the size of
the object. For example
represents a block consisting of 1024 null bytes. A checksum should not
represents a block consisting of 1024 null bytes. A checksum should not
+be given. The slice syntax should use the abbreviated length-only form.
@staticmethod
def parse_ref(refstr):
@staticmethod
def parse_ref(refstr):
- m = re.match(r"^zero\[(\d+)\+(\d+)\]$", refstr)
+ m = re.match(r"^zero\[(\d+)\]$", refstr)
- return ("zero", None, None, (int(m.group(1)), int(m.group(2))))
+ return ("zero", None, None, (0, int(m.group(1))))
- m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[(\d+)\+(\d+)\])?$", refstr)
+ m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[((\d+)\+)?(\d+)\])?$", refstr)
if not m: return
segment = m.group(1)
if not m: return
segment = m.group(1)
checksum = checksum.lstrip("(").rstrip(")")
if slice is not None:
checksum = checksum.lstrip("(").rstrip(")")
if slice is not None:
- slice = (int(m.group(5)), int(m.group(6)))
+ if m.group(5) is None:
+ # Abbreviated slice
+ slice = (0, int(m.group(7)))
+ else:
+ slice = (int(m.group(6)), int(m.group(7)))
return (segment, object, checksum, slice)
return (segment, object, checksum, slice)
if (range_valid) {
char buf[64];
if (range_valid) {
char buf[64];
- sprintf(buf, "[%zu+%zu]", range_start, range_length);
+ if (range_start == 0) {
+ sprintf(buf, "[%zu]", range_length);
+ } else {
+ sprintf(buf, "[%zu+%zu]", range_start, range_length);
+ }
s = t;
while (*t >= '0' && *t <= '9')
t++;
s = t;
while (*t >= '0' && *t <= '9')
t++;
- if (*t != '+')
- return ObjectReference();
- string val(s, t - s);
- range1 = atoll(val.c_str());
+ // Abbreviated-length only range?
+ if (*t == ']') {
+ string val(s, t - s);
+ range2 = atoll(val.c_str());
+ } else {
+ if (*t != '+')
+ return ObjectReference();
- t++;
- s = t;
- while (*t >= '0' && *t <= '9')
- t++;
- if (*t != ']')
- return ObjectReference();
+ string val(s, t - s);
+ range1 = atoll(val.c_str());
- val = string(s, t - s);
- range2 = atoll(val.c_str());
+ t++;
+ s = t;
+ while (*t >= '0' && *t <= '9')
+ t++;
+ if (*t != ']')
+ return ObjectReference();
+
+ val = string(s, t - s);
+ range2 = atoll(val.c_str());
+ }
* range specifier is given, then by default the entire object is used.
* <range> ::= <start> "+" <length>
* Both <start> and <length> are decimal values. If included, the range is
* range specifier is given, then by default the entire object is used.
* <range> ::= <start> "+" <length>
* Both <start> and <length> are decimal values. If included, the range is
- * enclosed in brackets.
+ * enclosed in brackets. As an abbreviation, if <start> is 0 then the range
+ * can be given as just <length> (no "+" needed).
*
* When both a checksum and a range are included, note that the checksum is
* taken over the entire original object, before the range is taken into
*
* When both a checksum and a range are included, note that the checksum is
* taken over the entire original object, before the range is taken into