blob: b95b3fa97b5b80a790dcdc3ea8ce676f79b0341f [file] [log] [blame]
Alexander Afanasyev5ba90362013-07-15 19:58:38 -07001## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
2#
3# Copyright (c) 2011-2013, Regents of the University of California
4# Alexander Afanasyev
5#
6# GNU 3.0 license, See the LICENSE file for more information
7#
8# Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9#
10
11#
12# Based on PyCCN code, copyrighted and licensed as follows
13#
14# Copyright (c) 2011-2013, Regents of the University of California
15# BSD license, See the COPYING file for more information
16# Written by: Derek Kulinski <takeda@takeda.tk>
17# Jeff Burke <jburke@ucla.edu>
18#
19
20__TT_BITS__ = 3
21__TT_MASK__ = (1 << __TT_BITS__) - 1
22__TT_HBIT__ = (1 << 7)
23__TT_LBIT__ = __TT_HBIT__ - 1
24
25DTAG_NAME = 14
26DTAG_COLLECTION = 17
27DTAG_LINK = 31
28
29def blob(value):
30 return _encode(len(value), 5) + value
31
32def dtag(tag, value):
33 return _encode(tag, 2) + value + '\x00'
34
35def _encode(value, tt):
36 global __TT_BITS__, __TT_HBIT__, __TT_LBIT__
37
38 header = (value << __TT_BITS__) | tt
39
40 blocks = []
41 blocks.append((header & __TT_LBIT__) | __TT_HBIT__)
42 header >>= 7
43
44 while header != 0:
45 blocks.append(header & __TT_LBIT__)
46 header >>= 7
47
48 blocks.reverse()
49
50 return bytearray(blocks)
51
52class CCNBDecoder(object):
53 def __init__(self, ccnb_data):
54 self.ccnb_data = ccnb_data
55 self.reset()
56
57 def reset(self):
58 self.position = 0
59 self.decoded = 0
60 self.stack = []
61
62 def _process_next_byte(self):
63 global __TT_HBIT__, __TT_LBIT__
64
65 assert self.position < len(self.ccnb_data)
66
67 char = ord(self.ccnb_data[self.position])
68 self.position += 1
69
70 if self.decoded == 0 and char == 0:
71 return None, True
72
73 decoded = (self.decoded << 7) | (char & __TT_LBIT__)
74 complete = (char & __TT_HBIT__) == __TT_HBIT__
75
76 self.decoded = decoded if not complete else 0
77
78 return decoded, complete
79
80 def print_element(self, tt, value, data = None):
81 if tt == 2:
82 print "DTAG",
83
84 if value == 14:
85 print "Name"
86 elif value == 15:
87 print "Component"
88 elif value == 17:
89 print "Collection"
90 elif value == 31:
91 print "Link"
92 else:
93 print value
94
95 elif tt == 5:
96 print "BLOB",
97 print value,
98 print repr(data)
99 else:
100 print tt,
101 print value,
102 print repr(data)
103
104 def get_tags(self):
105 global __TT_MASK__, __TT_BITS__
106
107 while self.position < len(self.ccnb_data):
108 while True:
109 decoded, complete = self._process_next_byte()
110 if complete:
111 break
112
113 if decoded is None:
114 tt, value = self.stack.pop()
115 print "Close",
116 else:
117 tt = decoded & __TT_MASK__
118 value = decoded >> __TT_BITS__
119
120 data = None
121 if decoded is not None:
122 if tt == 2:
123 self.stack.append((tt, value))
124 elif tt == 5:
125 data = self.ccnb_data[self.position:self.position + value]
126 self.position += value
127
128 self.print_element(tt, value, data)
129