Add igor.packed.walk for traversing a packed experiment filesystem.
authorW. Trevor King <wking@tremily.us>
Sat, 21 Jul 2012 15:17:08 +0000 (11:17 -0400)
committerW. Trevor King <wking@tremily.us>
Sat, 21 Jul 2012 15:23:06 +0000 (11:23 -0400)
igor/packed.py
igor/util.py
test/test.py

index da773bba543634689442b197d9b71295064f8192..8b5537a8f83f095f6b0b8eb9325b690dbee7da03 100644 (file)
@@ -22,6 +22,7 @@ from .struct import Structure as _Structure
 from .struct import Field as _Field
 from .util import byte_order as _byte_order
 from .util import need_to_reorder_bytes as _need_to_reorder_bytes
 from .struct import Field as _Field
 from .util import byte_order as _byte_order
 from .util import need_to_reorder_bytes as _need_to_reorder_bytes
+from .util import _bytes
 from .record import RECORD_TYPE as _RECORD_TYPE
 from .record.base import UnknownRecord as _UnknownRecord
 from .record.base import UnusedRecord as _UnusedRecord
 from .record import RECORD_TYPE as _RECORD_TYPE
 from .record.base import UnknownRecord as _UnknownRecord
 from .record.base import UnusedRecord as _UnusedRecord
@@ -181,3 +182,13 @@ def _check_filename(dir_stack, filename):
     if filename in cwd:
         raise ValueError('collision on name {} in {}'.format(
                 filename, ':'.join(d for d,cwd in dir_stack)))
     if filename in cwd:
         raise ValueError('collision on name {} in {}'.format(
                 filename, ':'.join(d for d,cwd in dir_stack)))
+
+def walk(filesystem, callback, dirpath=None):
+    """Walk a packed experiment filesystem, operating on each key,value pair.
+    """
+    if dirpath is None:
+        dirpath = []
+    for key,value in sorted((_bytes(k),v) for k,v in filesystem.items()):
+        callback(dirpath, key, value)
+        if isinstance(value, dict):
+            walk(filesystem=value, callback=callback, dirpath=dirpath+[key])
index b91bf2bf00f211f08903eeba215fd0da9c1d46bb..ecc783a684ced3be0fbcf583db9e6755cf08ea3a 100644 (file)
@@ -110,3 +110,19 @@ def checksum(buffer, byte_order, oldcksum, numbytes):
         if oldcksum > 2**31:
             oldcksum -= 2**31
     return oldcksum & 0xffff
         if oldcksum > 2**31:
             oldcksum -= 2**31
     return oldcksum & 0xffff
+
+def _bytes(obj, encoding='utf-8'):
+    """Convert bytes or strings into bytes
+
+    >>> _bytes(b'123')
+    '123'
+    >>> _bytes('123')
+    '123'
+    """
+    if _sys.version_info >= (3,):
+        if isinstance(obj, bytes):
+            return obj
+        else:
+            return bytes(obj, encoding)
+    else:
+        return bytes(obj)
index 4a76476e15e37df4013aa2d45de6f9d8d5090cde..1934493cd63c25776f7681b3b78b9016e90fa701 100644 (file)
@@ -1415,6 +1415,21 @@ filesystem:
           'angleQ1': <WaveRecord ...>,
           'radiusData': <WaveRecord ...>,
           'radiusQ1': <WaveRecord ...>}}
           'angleQ1': <WaveRecord ...>,
           'radiusData': <WaveRecord ...>,
           'radiusQ1': <WaveRecord ...>}}
+<BLANKLINE>
+walking filesystem:
+walk callback on ([], root, {'K0': 0.0,...})
+walk callback on (['root'], K0, 0.0)
+walk callback on (['root'], K1, 0.0)
+walk callback on (['root'], K10, 0.0)
+...
+walk callback on (['root'], K9, 0.0)
+walk callback on (['root'], Packages, {'PolarGraphs': ...})
+walk callback on (['root', 'Packages'], PolarGraphs, {...})
+walk callback on (['root', 'Packages', 'PolarGraphs'], V_bottom, 232.0)
+...
+walk callback on (['root', 'Packages'], WMDataBase, {...})
+...
+walk callback on (['root'], radiusQ1, <WaveRecord ...>)
 """
 
 import os.path
 """
 
 import os.path
@@ -1423,6 +1438,7 @@ from pprint import pformat
 from igor import LOG
 from igor.binarywave import load as loadibw
 from igor.packed import load as loadpxp
 from igor import LOG
 from igor.binarywave import load as loadibw
 from igor.packed import load as loadpxp
+from igor.packed import walk as _walk
 from igor.record.base import TextRecord
 from igor.record.folder import FolderStartRecord, FolderEndRecord
 from igor.record.variables import VariablesRecord
 from igor.record.base import TextRecord
 from igor.record.folder import FolderStartRecord, FolderEndRecord
 from igor.record.variables import VariablesRecord
@@ -1438,7 +1454,11 @@ def dumpibw(filename):
     data = loadibw(path)
     pprint(data)
 
     data = loadibw(path)
     pprint(data)
 
-def dumppxp(filename):
+def walk_callback(dirpath, key, value):
+    print('walk callback on ({}, {}, {})'.format(
+            dirpath, key, pformat(value)))
+
+def dumppxp(filename, walk=True):
     LOG.info('Testing {}\n'.format(filename))
     path = os.path.join(_data_dir, filename)
     records,filesystem = loadpxp(path)
     LOG.info('Testing {}\n'.format(filename))
     path = os.path.join(_data_dir, filename)
     records,filesystem = loadpxp(path)
@@ -1456,6 +1476,9 @@ def dumppxp(filename):
             pprint(record)
     print('\nfilesystem:')
     pprint(filesystem)
             pprint(record)
     print('\nfilesystem:')
     pprint(filesystem)
+    if walk:
+        print('\nwalking filesystem:')
+        _walk(filesystem, walk_callback)
 
 def pprint(data):
     lines = pformat(data).splitlines()
 
 def pprint(data):
     lines = pformat(data).splitlines()