PyNDN: Initial import of PyNDN code

Refs #1010 (http://redmine.named-data.net/issues/1010)
diff --git a/PyNDN/Interest.py b/PyNDN/Interest.py
new file mode 100644
index 0000000..7ebee01
--- /dev/null
+++ b/PyNDN/Interest.py
@@ -0,0 +1,182 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+# 
+# Copyright (c) 2011-2013, Regents of the University of California
+#                          Alexander Afanasyev
+# 
+# GNU 3.0 license, See the LICENSE file for more information
+# 
+# Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+# 
+
+#
+# Based on PyCCN code, copyrighted and licensed as follows
+#
+# Copyright (c) 2011-2013, Regents of the University of California
+# BSD license, See the COPYING file for more information
+# Written by: Derek Kulinski <takeda@takeda.tk>
+#             Jeff Burke <jburke@ucla.edu>
+#
+
+import ndn.Name
+
+class AOKType(utils.Flag):
+    _prefix = "ndn"
+
+AOK_NONE = AOKType.new_flag('AOK_NONE', 0x0)
+AOK_CS = AOKType.new_flag('AOK_CS', 0x1)  # Answer from content store
+AOK_NEW = AOKType.new_flag('AOK_NEW', 0x2)  # OK to produce new content
+AOK_STALE = AOKType.new_flag('AOK_STALE', 0x4)  # OK to answer with stale data
+AOK_EXPIRE = AOKType.new_flag('AOK_EXPIRE', 0x10) # Mark as stale (requires scope 0)
+
+AOK_DEFAULT = AOK_CS | AOK_NEW
+
+CHILD_SELECTOR_LEFT = 0
+CHILD_SELECTOR_RIGHT = 1
+
+class Interest(object):
+    def __init__(self, name = None, minSuffixComponents = None,
+             maxSuffixComponents = None, publisherPublicKeyDigest = None,
+             exclude = None, childSelector = None, answerOriginKind = None,
+             scope = None, interestLifetime = None, nonce = None):
+        
+        self.name = name
+
+        #
+        # Not supported at the moment
+        #
+        # self.minSuffixComponents = minSuffixComponents  # default 0
+        # self.maxSuffixComponents = maxSuffixComponents  # default infinity
+        # self.publisherPublicKeyDigest = publisherPublicKeyDigest  # SHA256 hash
+        # self.exclude = exclude
+        # self.childSelector = childSelector
+        # self.answerOriginKind = answerOriginKind
+
+        self.scope = scope
+        self.interestLifetime = interestLifetime
+        self.nonce = nonce
+
+        # wire
+        self.wire_dirty = True
+        self.wire = None  # backing charbuf
+
+    def __setattr__(self, name, value):
+        if name != "wire_dirty":
+            self.wire_dirty = True
+        object.__setattr__(self, name, value)
+
+    def __getattribute__(self, name):
+        if name == "wire":
+            # force refresh if components changed
+            if object.__getattribute__(self, 'name') and self.name.wire_dirty:
+                self.wire_dirty = True
+            elif object.__getattribute__(self, 'exclude') and self.exclude.wire_dirty:
+                self.wire_dirty = True
+
+            if object.__getattribute__(self, 'wire_dirty'):
+                self.wire = _ndn.Interest_obj_to_ccn(self)
+                self.wire_dirty = False
+        return object.__getattribute__(self, name)
+
+    def __str__(self):
+        res = []
+        res.append("name: %s" % self.name)
+        res.append("minSuffixComponents: %s" % self.minSuffixComponents)
+        res.append("maxSuffixComponents: %s" % self.maxSuffixComponents)
+        res.append("publisherPublicKeyDigest: %r" % self.publisherPublicKeyDigest)
+        res.append("exclude:\n%s" % self.exclude)
+        res.append("childSelector: %s" % self.childSelector)
+        res.append("answerOriginKind: %s" % self.answerOriginKind)
+        res.append("scope: %s" % self.scope)
+        res.append("interestLifetime: %s" % self.interestLifetime)
+        res.append("nonce: %r" % self.nonce)
+        return "\n".join(res)
+
+    def __repr__(self):
+        args = []
+
+        if self.name is not None:
+            args += ["name=%r" % self.name]
+        if self.minSuffixComponents is not None:
+            args += ["minSuffixComponents=%r" % self.minSuffixComponents]
+        if self.maxSuffixComponents is not None:
+            args += ["maxSuffixComponents=%r" % self.maxSuffixComponents]
+        if self.publisherPublicKeyDigest is not None:
+            args += ["publisherPublicKeyDigest=%r" % self.publisherPublicKeyDigest]
+        if self.exclude is not None:
+            args += ["exclude=%r" % self.exclude]
+        if self.childSelector is not None:
+            args += ["childSelector=%r" % self.childSelector]
+        if self.answerOriginKind is not None:
+            args += ["answerOriginKind=%r" % self.answerOriginKind]
+        if self.scope is not None:
+            args += ["scope=%r" % self.scope]
+        if self.interestLifetime is not None:
+            args += ["interestLifetime=%r" % self.interestLifetime]
+        if self.nonce is not None:
+            args += ["nonce=%r" % self.nonce]
+
+        return "ndn.Interest(%s)" % ", ".join(args)
+
+    def get_aok_value(self):
+        global AOK_DEFAULT
+
+        return AOK_DEFAULT if not self.answerOriginKind else self.answerOriginKind
+
+    def matches_name(self, name):
+        i_name = self.name.components
+        o_name = name.components
+
+        # requested name is longer than ours
+        if len(i_name) > len(o_name):
+            return False
+
+        # at least one of given components don't match
+        if not all(i == j for i, j in zip(i_name, o_name)):
+            return False
+
+        return True
+
+# # Bloom filters will be deprecated, so we do not support them.
+# class ExclusionFilter(object):
+#     def __init__(self):
+#         self.components = []
+
+#         # py-ndn
+#         self.wire_dirty = False
+#         self.wire = None  # backing charbuf
+
+#     def reset(self):
+#         self.components = []
+
+#     def add_names(self, names):
+#         self.wire_dirty = True
+#         self.components.extend(sorted(names))
+
+#     def add_name(self, name):
+#         if not type(name) is Name.Name:
+#             raise TypeError("Name type required")
+
+#         self.wire_dirty = True
+#         self.components.append(name)
+
+#     def add_any(self):
+#         self.components.append(Name.Name(name_type = Name.NAME_ANY))
+
+#     def __setattr__(self, name, value):
+#         if name != "wire_dirty":
+#             self.wire_dirty = True
+#         object.__setattr__(self, name, value)
+
+#     def __getattribute__(self, name):
+#         if name == "wire":
+#             if object.__getattribute__(self, 'wire_dirty'):
+#                 self.wire = _ndn.ExclusionFilter_names_to_ccn(
+#                     self.components)
+#                 self.wire_dirty = False
+#         return object.__getattribute__(self, name)
+
+#     def __str__(self):
+#         comps = []
+#         for n in self.components:
+#             comps.append(str(n))
+#         return str(comps)