from mutagen._util import DictMixin, cdata, insert_bytes, delete_bytes
from mutagen._util import decode_terminated, split_escape, dict_match, enum
from mutagen._util import BitReader, BitReaderError, set_win32_unicode_argv
from mutagen._compat import text_type, itervalues, iterkeys, iteritems, PY2, \
    cBytesIO, xrange
from tests import TestCase
import random
import sys
import os
import mmap
try:
    import fcntl
except ImportError:
    fcntl = None
class FDict(DictMixin):
    def __init__(self):
        self.__d = {}
        self.keys = self.__d.keys
    def __getitem__(self, *args):
        return self.__d.__getitem__(*args)
    def __setitem__(self, *args):
        return self.__d.__setitem__(*args)
    def __delitem__(self, *args):
        return self.__d.__delitem__(*args)
class TDictMixin(TestCase):
    def setUp(self):
        self.fdict = FDict()
        self.rdict = {}
        self.fdict["foo"] = self.rdict["foo"] = "bar"
    def test_getsetitem(self):
        self.failUnlessEqual(self.fdict["foo"], "bar")
        self.failUnlessRaises(KeyError, self.fdict.__getitem__, "bar")
    def test_has_key_contains(self):
        self.failUnless("foo" in self.fdict)
        self.failIf("bar" in self.fdict)
        if PY2:
            self.failUnless(self.fdict.has_key("foo"))
            self.failIf(self.fdict.has_key("bar"))
    def test_iter(self):
        self.failUnlessEqual(list(iter(self.fdict)), ["foo"])
    def test_clear(self):
        self.fdict.clear()
        self.rdict.clear()
        self.failIf(self.fdict)
    def test_keys(self):
        self.failUnlessEqual(list(self.fdict.keys()), list(self.rdict.keys()))
        self.failUnlessEqual(
            list(iterkeys(self.fdict)), list(iterkeys(self.rdict)))
    def test_values(self):
        self.failUnlessEqual(
            list(self.fdict.values()), list(self.rdict.values()))
        self.failUnlessEqual(
            list(itervalues(self.fdict)), list(itervalues(self.rdict)))
    def test_items(self):
        self.failUnlessEqual(
            list(self.fdict.items()), list(self.rdict.items()))
        self.failUnlessEqual(
            list(iteritems(self.fdict)), list(iteritems(self.rdict)))
    def test_pop(self):
        self.failUnlessEqual(self.fdict.pop("foo"), self.rdict.pop("foo"))
        self.failUnlessRaises(KeyError, self.fdict.pop, "woo")
    def test_pop_bad(self):
        self.failUnlessRaises(TypeError, self.fdict.pop, "foo", 1, 2)
    def test_popitem(self):
        self.failUnlessEqual(self.fdict.popitem(), self.rdict.popitem())
        self.failUnlessRaises(KeyError, self.fdict.popitem)
    def test_update_other(self):
        other = {"a": 1, "b": 2}
        self.fdict.update(other)
        self.rdict.update(other)
    def test_update_other_is_list(self):
        other = [("a", 1), ("b", 2)]
        self.fdict.update(other)
        self.rdict.update(dict(other))
    def test_update_kwargs(self):
        self.fdict.update(a=1, b=2)
        # Ironically, the *real* dict doesn't support this on Python 2.3
        other = {"a": 1, "b": 2}
        self.rdict.update(other)
    def test_setdefault(self):
        self.fdict.setdefault("foo", "baz")
        self.rdict.setdefault("foo", "baz")
        self.fdict.setdefault("bar", "baz")
        self.rdict.setdefault("bar", "baz")
    def test_get(self):
        self.failUnlessEqual(self.rdict.get("a"), self.fdict.get("a"))
        self.failUnlessEqual(
            self.rdict.get("a", "b"), self.fdict.get("a", "b"))
        self.failUnlessEqual(self.rdict.get("foo"), self.fdict.get("foo"))
    def test_repr(self):
        self.failUnlessEqual(repr(self.rdict), repr(self.fdict))
    def test_len(self):
        self.failUnlessEqual(len(self.rdict), len(self.fdict))
    def tearDown(self):
        self.failUnlessEqual(self.fdict, self.rdict)
        self.failUnlessEqual(self.rdict, self.fdict)
class Tcdata(TestCase):
    ZERO = staticmethod(lambda s: b"\x00" * s)
    LEONE = staticmethod(lambda s: b"\x01" + b"\x00" * (s - 1))
    BEONE = staticmethod(lambda s: b"\x00" * (s - 1) + b"\x01")
    NEGONE = staticmethod(lambda s: b"\xff" * s)
    def test_char(self):
        self.failUnlessEqual(cdata.char(self.ZERO(1)), 0)
        self.failUnlessEqual(cdata.char(self.LEONE(1)), 1)
        self.failUnlessEqual(cdata.char(self.BEONE(1)), 1)
        self.failUnlessEqual(cdata.char(self.NEGONE(1)), -1)
        self.assertTrue(cdata.char is cdata.int8)
        self.assertTrue(cdata.to_char is cdata.to_int8)
        self.assertTrue(cdata.char_from is cdata.int8_from)
    def test_char_from_to(self):
        self.assertEqual(cdata.to_char(-2), b"\xfe")
        self.assertEqual(cdata.char_from(b"\xfe"), (-2, 1))
        self.assertEqual(cdata.char_from(b"\x00\xfe", 1), (-2, 2))
        self.assertRaises(cdata.error, cdata.char_from, b"\x00\xfe", 3)
    def test_uchar(self):
        self.failUnlessEqual(cdata.uchar(self.ZERO(1)), 0)
        self.failUnlessEqual(cdata.uchar(self.LEONE(1)), 1)
        self.failUnlessEqual(cdata.uchar(self.BEONE(1)), 1)
        self.failUnlessEqual(cdata.uchar(self.NEGONE(1)), 255)
        self.assertTrue(cdata.uchar is cdata.uint8)
        self.assertTrue(cdata.to_uchar is cdata.to_uint8)
        self.assertTrue(cdata.uchar_from is cdata.uint8_from)
    def test_short(self):
        self.failUnlessEqual(cdata.short_le(self.ZERO(2)), 0)
        self.failUnlessEqual(cdata.short_le(self.LEONE(2)), 1)
        self.failUnlessEqual(cdata.short_le(self.BEONE(2)), 256)
        self.failUnlessEqual(cdata.short_le(self.NEGONE(2)), -1)
        self.assertTrue(cdata.short_le is cdata.int16_le)
        self.failUnlessEqual(cdata.short_be(self.ZERO(2)), 0)
        self.failUnlessEqual(cdata.short_be(self.LEONE(2)), 256)
        self.failUnlessEqual(cdata.short_be(self.BEONE(2)), 1)
        self.failUnlessEqual(cdata.short_be(self.NEGONE(2)), -1)
        self.assertTrue(cdata.short_be is cdata.int16_be)
    def test_ushort(self):
        self.failUnlessEqual(cdata.ushort_le(self.ZERO(2)), 0)
        self.failUnlessEqual(cdata.ushort_le(self.LEONE(2)), 1)
        self.failUnlessEqual(cdata.ushort_le(self.BEONE(2)), 2 ** 16 >> 8)
        self.failUnlessEqual(cdata.ushort_le(self.NEGONE(2)), 65535)
        self.assertTrue(cdata.ushort_le is cdata.uint16_le)
        self.failUnlessEqual(cdata.ushort_be(self.ZERO(2)), 0)
        self.failUnlessEqual(cdata.ushort_be(self.LEONE(2)), 2 ** 16 >> 8)
        self.failUnlessEqual(cdata.ushort_be(self.BEONE(2)), 1)
        self.failUnlessEqual(cdata.ushort_be(self.NEGONE(2)), 65535)
        self.assertTrue(cdata.ushort_be is cdata.uint16_be)
    def test_int(self):
        self.failUnlessEqual(cdata.int_le(self.ZERO(4)), 0)
        self.failUnlessEqual(cdata.int_le(self.LEONE(4)), 1)
        self.failUnlessEqual(cdata.int_le(self.BEONE(4)), 2 ** 32 >> 8)
        self.failUnlessEqual(cdata.int_le(self.NEGONE(4)), -1)
        self.assertTrue(cdata.int_le is cdata.int32_le)
        self.failUnlessEqual(cdata.int_be(self.ZERO(4)), 0)
        self.failUnlessEqual(cdata.int_be(self.LEONE(4)), 2 ** 32 >> 8)
        self.failUnlessEqual(cdata.int_be(self.BEONE(4)), 1)
        self.failUnlessEqual(cdata.int_be(self.NEGONE(4)), -1)
        self.assertTrue(cdata.int_be is cdata.int32_be)
    def test_uint(self):
        self.failUnlessEqual(cdata.uint_le(self.ZERO(4)), 0)
        self.failUnlessEqual(cdata.uint_le(self.LEONE(4)), 1)
        self.failUnlessEqual(cdata.uint_le(self.BEONE(4)), 2 ** 32 >> 8)
        self.failUnlessEqual(cdata.uint_le(self.NEGONE(4)), 2 ** 32 - 1)
        self.assertTrue(cdata.uint_le is cdata.uint32_le)
        self.failUnlessEqual(cdata.uint_be(self.ZERO(4)), 0)
        self.failUnlessEqual(cdata.uint_be(self.LEONE(4)), 2 ** 32 >> 8)
        self.failUnlessEqual(cdata.uint_be(self.BEONE(4)), 1)
        self.failUnlessEqual(cdata.uint_be(self.NEGONE(4)), 2 ** 32 - 1)
        self.assertTrue(cdata.uint_be is cdata.uint32_be)
    def test_longlong(self):
        self.failUnlessEqual(cdata.longlong_le(self.ZERO(8)), 0)
        self.failUnlessEqual(cdata.longlong_le(self.LEONE(8)), 1)
        self.failUnlessEqual(cdata.longlong_le(self.BEONE(8)), 2 ** 64 >> 8)
        self.failUnlessEqual(cdata.longlong_le(self.NEGONE(8)), -1)
        self.assertTrue(cdata.longlong_le is cdata.int64_le)
        self.failUnlessEqual(cdata.longlong_be(self.ZERO(8)), 0)
        self.failUnlessEqual(cdata.longlong_be(self.LEONE(8)), 2 ** 64 >> 8)
        self.failUnlessEqual(cdata.longlong_be(self.BEONE(8)), 1)
        self.failUnlessEqual(cdata.longlong_be(self.NEGONE(8)), -1)
        self.assertTrue(cdata.longlong_be is cdata.int64_be)
    def test_ulonglong(self):
        self.failUnlessEqual(cdata.ulonglong_le(self.ZERO(8)), 0)
        self.failUnlessEqual(cdata.ulonglong_le(self.LEONE(8)), 1)
        self.failUnlessEqual(cdata.longlong_le(self.BEONE(8)), 2 ** 64 >> 8)
        self.failUnlessEqual(cdata.ulonglong_le(self.NEGONE(8)), 2 ** 64 - 1)
        self.assertTrue(cdata.ulonglong_le is cdata.uint64_le)
        self.failUnlessEqual(cdata.ulonglong_be(self.ZERO(8)), 0)
        self.failUnlessEqual(cdata.ulonglong_be(self.LEONE(8)), 2 ** 64 >> 8)
        self.failUnlessEqual(cdata.longlong_be(self.BEONE(8)), 1)
        self.failUnlessEqual(cdata.ulonglong_be(self.NEGONE(8)), 2 ** 64 - 1)
        self.assertTrue(cdata.ulonglong_be is cdata.uint64_be)
    def test_invalid_lengths(self):
        self.failUnlessRaises(cdata.error, cdata.char, b"")
        self.failUnlessRaises(cdata.error, cdata.uchar, b"")
        self.failUnlessRaises(cdata.error, cdata.int_le, b"")
        self.failUnlessRaises(cdata.error, cdata.longlong_le, b"")
        self.failUnlessRaises(cdata.error, cdata.uint_le, b"")
        self.failUnlessRaises(cdata.error, cdata.ulonglong_le, b"")
        self.failUnlessRaises(cdata.error, cdata.int_be, b"")
        self.failUnlessRaises(cdata.error, cdata.longlong_be, b"")
        self.failUnlessRaises(cdata.error, cdata.uint_be, b"")
        self.failUnlessRaises(cdata.error, cdata.ulonglong_be, b"")
    def test_test(self):
        self.failUnless(cdata.test_bit((1), 0))
        self.failIf(cdata.test_bit(1, 1))
        self.failUnless(cdata.test_bit(2, 1))
        self.failIf(cdata.test_bit(2, 0))
        v = (1 << 12) + (1 << 5) + 1
        self.failUnless(cdata.test_bit(v, 0))
        self.failUnless(cdata.test_bit(v, 5))
        self.failUnless(cdata.test_bit(v, 12))
        self.failIf(cdata.test_bit(v, 3))
        self.failIf(cdata.test_bit(v, 8))
        self.failIf(cdata.test_bit(v, 13))
class FileHandling(TestCase):
    def file(self, contents):
        import tempfile
        temp = tempfile.TemporaryFile()
        temp.write(contents)
        temp.flush()
        temp.seek(0)
        return temp
    def read(self, fobj):
        fobj.seek(0, 0)
        return fobj.read()
    def test_insert_into_empty(self):
        o = self.file(b'')
        insert_bytes(o, 8, 0)
        self.assertEquals(b'\x00' * 8, self.read(o))
    def test_insert_before_one(self):
        o = self.file(b'a')
        insert_bytes(o, 8, 0)
        self.assertEquals(b'a' + b'\x00' * 7 + b'a', self.read(o))
    def test_insert_after_one(self):
        o = self.file(b'a')
        insert_bytes(o, 8, 1)
        self.assertEquals(b'a' + b'\x00' * 8, self.read(o))
    def test_smaller_than_file_middle(self):
        o = self.file(b'abcdefghij')
        insert_bytes(o, 4, 4)
        self.assertEquals(b'abcdefghefghij', self.read(o))
    def test_smaller_than_file_to_end(self):
        o = self.file(b'abcdefghij')
        insert_bytes(o, 4, 6)
        self.assertEquals(b'abcdefghijghij', self.read(o))
    def test_smaller_than_file_across_end(self):
        o = self.file(b'abcdefghij')
        insert_bytes(o, 4, 8)
        self.assertEquals(b'abcdefghij\x00\x00ij', self.read(o))
    def test_smaller_than_file_at_end(self):


Answer:         o = self.file(b'abcdefghij')