2007-01-17 04:29:59 +00:00
|
|
|
|
2007-06-12 01:25:18 +00:00
|
|
|
import re
|
|
|
|
from allmydata.util import idlib, hashutil
|
2007-01-17 04:29:59 +00:00
|
|
|
|
|
|
|
# the URI shall be an ascii representation of the file. It shall contain
|
|
|
|
# enough information to retrieve and validate the contents. It shall be
|
|
|
|
# expressed in a limited character set (namely [TODO]).
|
|
|
|
|
2007-06-08 22:59:16 +00:00
|
|
|
def pack_uri(storage_index, key, uri_extension_hash,
|
2007-06-02 01:48:01 +00:00
|
|
|
needed_shares, total_shares, size):
|
2007-05-23 18:18:49 +00:00
|
|
|
# applications should pass keyword parameters into this
|
2007-06-02 01:48:01 +00:00
|
|
|
assert isinstance(storage_index, str)
|
2007-06-08 04:47:21 +00:00
|
|
|
assert len(storage_index) == 32 # sha256 hash
|
2007-06-02 01:48:01 +00:00
|
|
|
|
2007-06-08 22:59:16 +00:00
|
|
|
assert isinstance(uri_extension_hash, str)
|
|
|
|
assert len(uri_extension_hash) == 32 # sha56 hash
|
2007-06-02 01:48:01 +00:00
|
|
|
|
2007-04-26 00:53:10 +00:00
|
|
|
assert isinstance(key, str)
|
|
|
|
assert len(key) == 16 # AES-128
|
2007-06-02 01:48:01 +00:00
|
|
|
assert isinstance(needed_shares, int)
|
|
|
|
assert isinstance(total_shares, int)
|
|
|
|
assert isinstance(size, (int,long))
|
|
|
|
|
|
|
|
return "URI:%s:%s:%s:%d:%d:%d" % (idlib.b2a(storage_index), idlib.b2a(key),
|
2007-06-08 22:59:16 +00:00
|
|
|
idlib.b2a(uri_extension_hash),
|
2007-06-02 01:48:01 +00:00
|
|
|
needed_shares, total_shares, size)
|
2007-01-17 04:29:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
def unpack_uri(uri):
|
|
|
|
assert uri.startswith("URI:")
|
2007-05-23 18:18:49 +00:00
|
|
|
d = {}
|
2007-06-02 01:48:01 +00:00
|
|
|
(header,
|
2007-06-08 22:59:16 +00:00
|
|
|
storage_index_s, key_s, uri_extension_hash_s,
|
2007-06-02 01:48:01 +00:00
|
|
|
needed_shares_s, total_shares_s, size_s) = uri.split(":")
|
2007-05-23 18:18:49 +00:00
|
|
|
assert header == "URI"
|
2007-06-02 01:48:01 +00:00
|
|
|
d['storage_index'] = idlib.a2b(storage_index_s)
|
2007-05-23 18:18:49 +00:00
|
|
|
d['key'] = idlib.a2b(key_s)
|
2007-06-08 22:59:16 +00:00
|
|
|
d['uri_extension_hash'] = idlib.a2b(uri_extension_hash_s)
|
2007-05-23 18:18:49 +00:00
|
|
|
d['needed_shares'] = int(needed_shares_s)
|
|
|
|
d['total_shares'] = int(total_shares_s)
|
|
|
|
d['size'] = int(size_s)
|
|
|
|
return d
|
2007-01-17 04:29:59 +00:00
|
|
|
|
|
|
|
|
2007-06-12 01:25:18 +00:00
|
|
|
def pack_extension(data):
|
|
|
|
pieces = []
|
|
|
|
for k in sorted(data.keys()):
|
|
|
|
value = data[k]
|
|
|
|
if isinstance(value, (int, long)):
|
|
|
|
value = "%d" % value
|
|
|
|
assert isinstance(value, str), k
|
|
|
|
assert re.match(r'^[a-zA-Z_\-]+$', k)
|
|
|
|
pieces.append(k + ":" + hashutil.netstring(value))
|
|
|
|
uri_extension = "".join(pieces)
|
|
|
|
return uri_extension
|
|
|
|
|
|
|
|
def unpack_extension(data):
|
|
|
|
d = {}
|
|
|
|
while data:
|
|
|
|
colon = data.index(":")
|
|
|
|
key = data[:colon]
|
|
|
|
data = data[colon+1:]
|
|
|
|
|
|
|
|
colon = data.index(":")
|
|
|
|
number = data[:colon]
|
|
|
|
length = int(number)
|
|
|
|
data = data[colon+1:]
|
|
|
|
|
|
|
|
value = data[:length]
|
|
|
|
assert data[length] == ","
|
|
|
|
data = data[length+1:]
|
|
|
|
|
|
|
|
d[key] = value
|
|
|
|
|
|
|
|
# convert certain things to numbers
|
|
|
|
for intkey in ("size", "segment_size", "num_segments",
|
|
|
|
"needed_shares", "total_shares"):
|
|
|
|
if intkey in d:
|
|
|
|
d[intkey] = int(d[intkey])
|
|
|
|
return d
|
|
|
|
|
2007-06-12 01:38:21 +00:00
|
|
|
|
|
|
|
def unpack_extension_readable(data):
|
|
|
|
unpacked = unpack_extension(data)
|
|
|
|
for k in sorted(unpacked.keys()):
|
|
|
|
if "hash" in k:
|
|
|
|
unpacked[k] = idlib.b2a(unpacked[k])
|
|
|
|
return unpacked
|