### BEGIN LICENSE ###
### Use of the triage tools and related source code is subject to the terms
### of the license below.
###
### ------------------------------------------------------------------------
### Copyright (C) 2011 Carnegie Mellon University. All Rights Reserved.
### ------------------------------------------------------------------------
### Redistribution and use in source and binary forms, with or without
### modification, are permitted provided that the following conditions are
### met:
###
### 1. Redistributions of source code must retain the above copyright
###    notice, this list of conditions and the following acknowledgments
###    and disclaimers.
###
### 2. Redistributions in binary form must reproduce the above copyright
###    notice, this list of conditions and the following disclaimer in the
###    documentation and/or other materials provided with the distribution.
###
### 3. All advertising materials for third-party software mentioning
###    features or use of this software must display the following
###    disclaimer:
###
###    "Neither Carnegie Mellon University nor its Software Engineering
###     Institute have reviewed or endorsed this software"
###
### 4. The names "Department of Homeland Security," "Carnegie Mellon
###    University," "CERT" and/or "Software Engineering Institute" shall
###    not be used to endorse or promote products derived from this software
###    without prior written permission. For written permission, please
###    contact permission@sei.cmu.edu.
###
### 5. Products derived from this software may not be called "CERT" nor
###    may "CERT" appear in their names without prior written permission of
###    permission@sei.cmu.edu.
###
### 6. Redistributions of any form whatsoever must retain the following
###    acknowledgment:
###
###    "This product includes software developed by CERT with funding
###     and support from the Department of Homeland Security under
###     Contract No. FA 8721-05-C-0003."
###
### THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
### CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
### EXPRESS OR IMPLIED, AS TO ANY MATTER, AND ALL SUCH WARRANTIES, INCLUDING
### WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
### EXPRESSLY DISCLAIMED. WITHOUT LIMITING THE GENERALITY OF THE FOREGOING,
### CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND
### RELATING TO EXCLUSIVITY, INFORMATIONAL CONTENT, ERROR-FREE OPERATION,
### RESULTS TO BE OBTAINED FROM USE, FREEDOM FROM PATENT, TRADEMARK AND
### COPYRIGHT INFRINGEMENT AND/OR FREEDOM FROM THEFT OF TRADE SECRETS.
### END LICENSE ###
'''
A collection of basic Python objects used throughout this project.
'''
class AttrDict(object):
    """
    A dictionary that can be accessed both using indexing and attributes,
    i.e.,
        x = AttrDict()
        x.foo = 5
        print x["foo"]

    Adapted from Construct v2's AttrDict
        (ref: http://pypi.python.org/pypi/construct) 8/23/2011
    """
    __slots__ = ["__dict__"]
    def __init__(self, **kw):
        self.__dict__ = kw
    def __contains__(self, key):
        return key in self.__dict__
    def __nonzero__(self):
        return bool(self.__dict__)
    def __repr__(self):
        return repr(self.__dict__)
    def __str__(self):
        return self.__pretty_str__()
    def __pretty_str__(self, nesting = 1, indentation = "    "):
        if not self:
            return "{}"
        text = ["{\n"]
        ind = nesting * indentation
        for k in sorted(self.__dict__.keys()):
            v = self.__dict__[k]
            text.append(ind)
            text.append(repr(k))
            text.append(" : ")
            if hasattr(v, "__pretty_str__"):
                try:
                    text.append(v.__pretty_str__(nesting+1, indentation))
                except Exception:
                    text.append(repr(v))
            else:
                text.append(str(v))
            text.append("\n")
        text.append((nesting-1) * indentation)
        text.append("}")
        return "".join(text)
    def __delitem__(self, key):
        del self.__dict__[key]
    def __getitem__(self, key):
        return self.__dict__[key]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __copy__(self):
        new = self.__class__()
        new.__dict__ = self.__dict__.copy()
        return new
    def __update__(self, other):
        if isinstance(other, dict):
            self.__dict__.update(other)
        else:
            self.__dict__.update(other.__dict__)
    def __getstate__(self):
        return self.__dict__

