def File(filename, options=None, easy=False):

if options is None:<EOL><INDENT>from mutagen.asf import ASF<EOL>from mutagen.apev2 import APEv2File<EOL>from mutagen.flac import FLAC<EOL>if easy:<EOL><INDENT>from mutagen.easyid3 import EasyID3FileType as ID3FileType<EOL><DEDENT>else:<EOL><INDENT>from mutagen.id3 import ID3FileType<EOL><DEDENT>if easy:<EOL><INDENT>from mutagen.mp3 import EasyMP3 as MP3<EOL><DEDENT>else:<EOL><INDENT>from mutagen.mp3 import MP3<EOL><DEDENT>from mutagen.oggflac import OggFLAC<EOL>from mutagen.oggspeex import OggSpeex<EOL>from mutagen.oggtheora import OggTheora<EOL>from mutagen.oggvorbis import OggVorbis<EOL>from mutagen.oggopus import OggOpus<EOL>if easy:<EOL><INDENT>from mutagen.trueaudio import EasyTrueAudio as TrueAudio<EOL><DEDENT>else:<EOL><INDENT>from mutagen.trueaudio import TrueAudio<EOL><DEDENT>from mutagen.wavpack import WavPack<EOL>if easy:<EOL><INDENT>from mutagen.easymp4 import EasyMP4 as MP4<EOL><DEDENT>else:<EOL><INDENT>from mutagen.mp4 import MP4<EOL><DEDENT>from mutagen.musepack import Musepack<EOL>from mutagen.monkeysaudio import MonkeysAudio<EOL>from mutagen.optimfrog import OptimFROG<EOL>from mutagen.aiff import AIFF<EOL>options = [MP3, TrueAudio, OggTheora, OggSpeex, OggVorbis, OggFLAC,<EOL>FLAC, AIFF, APEv2File, MP4, ID3FileType, WavPack,<EOL>Musepack, MonkeysAudio, OptimFROG, ASF, OggOpus]<EOL><DEDENT>if not options:<EOL><INDENT>return None<EOL><DEDENT>fileobj = open(filename, "<STR_LIT:rb>")<EOL>try:<EOL><INDENT>header = fileobj.read(<NUM_LIT>)<EOL>results = [(Kind.score(filename, fileobj, header), Kind.__name__)<EOL>for Kind in options]<EOL><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>results = list(zip(results, options))<EOL>results.sort()<EOL>(score, name), Kind = results[-<NUM_LIT:1>]<EOL>if score > <NUM_LIT:0>:<EOL><INDENT>return Kind(filename)<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Guess the type of the file and try to open it.

    The file type is decided by several things, such as the first 128
    bytes (which usually contains a file type identifier), the
    filename extension, and the presence of existing tags.

    If no appropriate type could be found, None is returned.

    :param options: Sequence of :class:`FileType` implementations, defaults to
                    all included ones.

    :param easy: If the easy wrappers should be returnd if available.
                 For example :class:`EasyMP3 <mp3.EasyMP3>` instead
                 of :class:`MP3 <mp3.MP3>`.


raise NotImplementedError<EOL>


if self.tags is None:<EOL><INDENT>raise KeyError(key)<EOL><DEDENT>else:<EOL><INDENT>return self.tags[key]<EOL><DEDENT>

Look up a metadata tag key.

        If the file has no tags at all, a KeyError is raised.


if self.tags is None:<EOL><INDENT>self.add_tags()<EOL><DEDENT>self.tags[key] = value<EOL>

Set a metadata tag.

        If the file has no tags, an appropriate format is added (but
        not written until save is called).


if self.tags is None:<EOL><INDENT>raise KeyError(key)<EOL><DEDENT>else:<EOL><INDENT>del(self.tags[key])<EOL><DEDENT>

Delete a metadata tag key.

        If the file has no tags at all, a KeyError is raised.


if self.tags is not None:<EOL><INDENT>if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>else:<EOL><INDENT>warnings.warn(<EOL>"<STR_LIT>",<EOL>DeprecationWarning)<EOL><DEDENT>return self.tags.delete(filename)<EOL><DEDENT>


def save(self, filename=None, **kwargs):

if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>else:<EOL><INDENT>warnings.warn(<EOL>"<STR_LIT>",<EOL>DeprecationWarning)<EOL><DEDENT>if self.tags is not None:<EOL><INDENT>return self.tags.save(filename, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>


stream = "<STR_LIT>" % (self.info.pprint(), self.mime[<NUM_LIT:0>])<EOL>try:<EOL><INDENT>tags = self.tags.pprint()<EOL><DEDENT>except AttributeError:<EOL><INDENT>return stream<EOL><DEDENT>else:<EOL><INDENT>return stream + ((tags and "<STR_LIT:\n>" + tags) or "<STR_LIT>")<EOL><DEDENT>

Print stream information and comment key=value pairs.


raise NotImplementedError<EOL>

Adds new tags to the file.

        Raises if tags already exist.


mimes = []<EOL>for Kind in type(self).__mro__:<EOL><INDENT>for mime in getattr(Kind, '<STR_LIT>', []):<EOL><INDENT>if mime not in mimes:<EOL><INDENT>mimes.append(mime)<EOL><DEDENT><DEDENT><DEDENT>return mimes<EOL>


def delete(filename, delete_v1=True, delete_v2=True):

f = open(filename, '<STR_LIT>')<EOL>if delete_v1:<EOL><INDENT>try:<EOL><INDENT>f.seek(-<NUM_LIT>, <NUM_LIT:2>)<EOL><DEDENT>except IOError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>if f.read(<NUM_LIT:3>) == b'<STR_LIT>':<EOL><INDENT>f.seek(-<NUM_LIT>, <NUM_LIT:2>)<EOL>f.truncate()<EOL><DEDENT><DEDENT><DEDENT>if delete_v2:<EOL><INDENT>f.seek(<NUM_LIT:0>, <NUM_LIT:0>)<EOL>idata = f.read(<NUM_LIT:10>)<EOL>try:<EOL><INDENT>id3, vmaj, vrev, flags, insize = unpack('<STR_LIT>', idata)<EOL><DEDENT>except struct.error:<EOL><INDENT>id3, insize = b'<STR_LIT>', -<NUM_LIT:1><EOL><DEDENT>insize = BitPaddedInt(insize)<EOL>if id3 == b'<STR_LIT>' and insize >= <NUM_LIT:0>:<EOL><INDENT>delete_bytes(f, insize + <NUM_LIT:10>, <NUM_LIT:0>)<EOL><DEDENT><DEDENT>

Remove tags from a file.

    Keyword arguments:

    * delete_v1 -- delete any ID3v1 tag
    * delete_v2 -- delete any ID3v2 tag


try:<EOL><INDENT>data = data[data.index(b'<STR_LIT>'):]<EOL><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT>if <NUM_LIT> < len(data) or len(data) < <NUM_LIT>:<EOL><INDENT>return None<EOL><DEDENT>unpack_fmt = "<STR_LIT>" % (len(data) - <NUM_LIT>)<EOL>try:<EOL><INDENT>tag, title, artist, album, year, comment, track, genre = unpack(<EOL>unpack_fmt, data)<EOL><DEDENT>except StructError:<EOL><INDENT>return None<EOL><DEDENT>if tag != b"<STR_LIT>":<EOL><INDENT>return None<EOL><DEDENT>def fix(data):<EOL><INDENT>return data.split(b'<STR_LIT:\x00>')[<NUM_LIT:0>].strip().decode('<STR_LIT>')<EOL><DEDENT>title, artist, album, year, comment = map(<EOL>fix, [title, artist, album, year, comment])<EOL>frames = {}<EOL>if title:<EOL><INDENT>frames['<STR_LIT>'] = TIT2(encoding=<NUM_LIT:0>, text=title)<EOL><DEDENT>if artist:<EOL><INDENT>frames['<STR_LIT>'] = TPE1(encoding=<NUM_LIT:0>, text=[artist])<EOL><DEDENT>if album:<EOL><INDENT>frames['<STR_LIT>'] = TALB(encoding=<NUM_LIT:0>, text=album)<EOL><DEDENT>if year:<EOL><INDENT>frames['<STR_LIT>'] = TDRC(encoding=<NUM_LIT:0>, text=year)<EOL><DEDENT>if comment:<EOL><INDENT>frames['<STR_LIT>'] = COMM(encoding=<NUM_LIT:0>, lang='<STR_LIT>', desc="<STR_LIT>",<EOL>text=comment)<EOL><DEDENT>if track and ((track != <NUM_LIT:32>) or (data[-<NUM_LIT:3>] == b'<STR_LIT:\x00>'[<NUM_LIT:0>])):<EOL><INDENT>frames['<STR_LIT>'] = TRCK(encoding=<NUM_LIT:0>, text=str(track))<EOL><DEDENT>if genre != <NUM_LIT:255>:<EOL><INDENT>frames['<STR_LIT>'] = TCON(encoding=<NUM_LIT:0>, text=str(genre))<EOL><DEDENT>return frames<EOL>

Parse an ID3v1 tag, returning a list of ID3v2.4 frames.


v1 = {}<EOL>for v2id, name in {"<STR_LIT>": "<STR_LIT:title>", "<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>"}.items():<EOL><INDENT>if v2id in id3:<EOL><INDENT>text = id3[v2id].text[<NUM_LIT:0>].encode('<STR_LIT>', '<STR_LIT:replace>')[:<NUM_LIT:30>]<EOL><DEDENT>else:<EOL><INDENT>text = b'<STR_LIT>'<EOL><DEDENT>v1[name] = text + (b'<STR_LIT:\x00>' * (<NUM_LIT:30> - len(text)))<EOL><DEDENT>if "<STR_LIT>" in id3:<EOL><INDENT>cmnt = id3["<STR_LIT>"].text[<NUM_LIT:0>].encode('<STR_LIT>', '<STR_LIT:replace>')[:<NUM_LIT>]<EOL><DEDENT>else:<EOL><INDENT>cmnt = b'<STR_LIT>'<EOL><DEDENT>v1['<STR_LIT>'] = cmnt + (b'<STR_LIT:\x00>' * (<NUM_LIT> - len(cmnt)))<EOL>if "<STR_LIT>" in id3:<EOL><INDENT>try:<EOL><INDENT>v1["<STR_LIT>"] = chr_(+id3["<STR_LIT>"])<EOL><DEDENT>except ValueError:<EOL><INDENT>v1["<STR_LIT>"] = b'<STR_LIT:\x00>'<EOL><DEDENT><DEDENT>else:<EOL><INDENT>v1["<STR_LIT>"] = b'<STR_LIT:\x00>'<EOL><DEDENT>if "<STR_LIT>" in id3:<EOL><INDENT>try:<EOL><INDENT>genre = id3["<STR_LIT>"].genres[<NUM_LIT:0>]<EOL><DEDENT>except IndexError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>if genre in TCON.GENRES:<EOL><INDENT>v1["<STR_LIT>"] = chr_(TCON.GENRES.index(genre))<EOL><DEDENT><DEDENT><DEDENT>if "<STR_LIT>" not in v1:<EOL><INDENT>v1["<STR_LIT>"] = b"<STR_LIT>"<EOL><DEDENT>if "<STR_LIT>" in id3:<EOL><INDENT>year = text_type(id3["<STR_LIT>"]).encode('<STR_LIT>', '<STR_LIT:replace>')<EOL><DEDENT>elif "<STR_LIT>" in id3:<EOL><INDENT>year = text_type(id3["<STR_LIT>"]).encode('<STR_LIT>', '<STR_LIT:replace>')<EOL><DEDENT>else:<EOL><INDENT>year = b'<STR_LIT>'<EOL><DEDENT>v1['<STR_LIT>'] = (year + b'<STR_LIT>')[:<NUM_LIT:4>]<EOL>return (b'<STR_LIT>' +<EOL>v1['<STR_LIT:title>'] +<EOL>v1['<STR_LIT>'] +<EOL>v1['<STR_LIT>'] +<EOL>v1['<STR_LIT>'] +<EOL>v1['<STR_LIT>'] +<EOL>v1['<STR_LIT>'] +<EOL>v1['<STR_LIT>'])<EOL>

Return an ID3v1.1 tag string from a dict of ID3v2.4 frames.


try:<EOL><INDENT>if size < <NUM_LIT:0>:<EOL><INDENT>raise ValueError('<STR_LIT>' % size)<EOL><DEDENT>if size > self.__filesize:<EOL><INDENT>raise EOFError('<STR_LIT>' % (<EOL>int(size), int(self.__filesize), self.filename))<EOL><DEDENT><DEDENT>except AttributeError:<EOL><INDENT>pass<EOL><DEDENT>data = self._fileobj.read(size)<EOL>if len(data) != size:<EOL><INDENT>raise EOFError<EOL><DEDENT>self.__readbytes += size<EOL>return data<EOL>

Read a certain number of bytes from the source file.


def load(self, filename, known_frames=None, translate=True, v2_version=<NUM_LIT:4>):

if not v2_version in (<NUM_LIT:3>, <NUM_LIT:4>):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>from os.path import getsize<EOL>self.filename = filename<EOL>self.__known_frames = known_frames<EOL>self._fileobj = open(filename, '<STR_LIT:rb>')<EOL>self.__filesize = getsize(filename)<EOL>try:<EOL><INDENT>try:<EOL><INDENT>self._load_header()<EOL><DEDENT>except EOFError:<EOL><INDENT>self.size = <NUM_LIT:0><EOL>raise ID3NoHeaderError("<STR_LIT>" % (<EOL>filename, self.__filesize))<EOL><DEDENT>except (ID3NoHeaderError, ID3UnsupportedVersionError) as err:<EOL><INDENT>self.size = <NUM_LIT:0><EOL>import sys<EOL>stack = sys.exc_info()[<NUM_LIT:2>]<EOL>try:<EOL><INDENT>self._fileobj.seek(-<NUM_LIT>, <NUM_LIT:2>)<EOL><DEDENT>except EnvironmentError:<EOL><INDENT>reraise(err, None, stack)<EOL><DEDENT>else:<EOL><INDENT>frames = ParseID3v1(self._fileobj.read(<NUM_LIT>))<EOL>if frames is not None:<EOL><INDENT>self.version = self._V11<EOL>for v in frames.values():<EOL><INDENT>self.add(v)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>reraise(err, None, stack)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>frames = self.__known_frames<EOL>if frames is None:<EOL><INDENT>if self._V23 <= self.version:<EOL><INDENT>frames = Frames<EOL><DEDENT>elif self._V22 <= self.version:<EOL><INDENT>frames = Frames_2_2<EOL><DEDENT><DEDENT>data = self.__fullread(self.size - <NUM_LIT:10>)<EOL>for frame in self.__read_frames(data, frames=frames):<EOL><INDENT>if isinstance(frame, Frame):<EOL><INDENT>self.add(frame)<EOL><DEDENT>else:<EOL><INDENT>self.unknown_frames.append(frame)<EOL><DEDENT><DEDENT>self.__unknown_version = self.version<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self._fileobj.close()<EOL>del self._fileobj<EOL>del self.__filesize<EOL>if translate:<EOL><INDENT>if v2_version == <NUM_LIT:3>:<EOL><INDENT>self.update_to_v23()<EOL><DEDENT>else:<EOL><INDENT>self.update_to_v24()<EOL><DEDENT><DEDENT><DEDENT>

Load tags from a filename.

        Keyword arguments:

        * filename -- filename to load tag data from
        * known_frames -- dict mapping frame IDs to Frame objects
        * translate -- Update all tags to ID3v2.3/4 internally. If you
                       intend to save, this must be true or you have to
                       call update_to_v23() / update_to_v24() manually.
        * v2_version -- if update_to_v23 or update_to_v24 get called (3 or 4)

        Example of loading a custom frame::

            my_frames = dict(mutagen.id3.Frames)
            class XMYF(Frame): ...
            my_frames["XMYF"] = XMYF
            mutagen.id3.ID3(filename, known_frames=my_frames)


if key in self:<EOL><INDENT>return [self[key]]<EOL><DEDENT>else:<EOL><INDENT>key = key + '<STR_LIT::>'<EOL>return [v for s, v in self.items() if s.startswith(key)]<EOL><DEDENT>

Return all frames with a given name (the list may be empty).

        This is best explained by examples::

            id3.getall('TIT2') == [id3['TIT2']]
            id3.getall('TTTT') == []
            id3.getall('TXXX') == [TXXX(desc='woo', text='bar'),
                                   TXXX(desc='baz', text='quuuux'), ...]

        Since this is based on the frame's HashKey, which is
        colon-separated, you can use it to do things like
        ``getall('COMM:MusicMatch')`` or ``getall('TXXX:QuodLibet:')``.


if key in self:<EOL><INDENT>del(self[key])<EOL><DEDENT>else:<EOL><INDENT>key = key + "<STR_LIT::>"<EOL>for k in self.keys():<EOL><INDENT>if k.startswith(key):<EOL><INDENT>del(self[k])<EOL><DEDENT><DEDENT><DEDENT>

Delete all tags of a given kind; see getall.


self.delall(key)<EOL>for tag in values:<EOL><INDENT>self[tag.HashKey] = tag<EOL><DEDENT>

Delete frames of the given type and add frames in 'values'.


frames = sorted(Frame.pprint(s) for s in self.values())<EOL>return '<STR_LIT:\n>'.join(frames)<EOL>

Return tags in a human-readable format.

        "Human-readable" is used loosely here. The format is intended
        to mirror that used for Vorbis or APEv2 output, e.g.

            ``TIT2=My Title``

        However, ID3 frames can have multiple keys:

            ``POPM=user@example.org=3 128/255``


<EOL>if len(type(tag).__name__) == <NUM_LIT:3>:<EOL><INDENT>tag = type(tag).__base__(tag)<EOL><DEDENT>self[tag.HashKey] = tag<EOL>


return self.loaded_frame(frame)<EOL>


def save(self, filename=None, v1=<NUM_LIT:1>, v2_version=<NUM_LIT:4>, v23_sep='<STR_LIT:/>'):

framedata = self._prepare_framedata(v2_version, v23_sep)<EOL>framesize = len(framedata)<EOL>if not framedata:<EOL><INDENT>try:<EOL><INDENT>self.delete(filename)<EOL><DEDENT>except EnvironmentError as err:<EOL><INDENT>from errno import ENOENT<EOL>if err.errno != ENOENT:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>return<EOL><DEDENT>if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>try:<EOL><INDENT>f = open(filename, '<STR_LIT>')<EOL><DEDENT>except IOError as err:<EOL><INDENT>from errno import ENOENT<EOL>if err.errno != ENOENT:<EOL><INDENT>raise<EOL><DEDENT>f = open(filename, '<STR_LIT>')  <EOL>f = open(filename, '<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>idata = f.read(<NUM_LIT:10>)<EOL>header = self._prepare_id3_header(idata, framesize, v2_version)<EOL>header, outsize, insize = header<EOL>data = header + framedata + (b'<STR_LIT:\x00>' * (outsize - framesize))<EOL>if (insize < outsize):<EOL><INDENT>insert_bytes(f, outsize-insize, insize+<NUM_LIT:10>)<EOL><DEDENT>f.seek(<NUM_LIT:0>)<EOL>f.write(data)<EOL>try:<EOL><INDENT>f.seek(-<NUM_LIT>, <NUM_LIT:2>)<EOL><DEDENT>except IOError as err:<EOL><INDENT>from errno import EINVAL<EOL>if err.errno != EINVAL:<EOL><INDENT>raise<EOL><DEDENT>f.seek(<NUM_LIT:0>, <NUM_LIT:2>)<EOL><DEDENT>data = f.read(<NUM_LIT>)<EOL>try:<EOL><INDENT>idx = data.index(b"<STR_LIT>")<EOL><DEDENT>except ValueError:<EOL><INDENT>offset = <NUM_LIT:0><EOL>has_v1 = False<EOL><DEDENT>else:<EOL><INDENT>offset = idx - len(data)<EOL>has_v1 = True<EOL><DEDENT>f.seek(offset, <NUM_LIT:2>)<EOL>if v1 == <NUM_LIT:1> and has_v1 or v1 == <NUM_LIT:2>:<EOL><INDENT>f.write(MakeID3v1(self))<EOL><DEDENT>else:<EOL><INDENT>f.truncate()<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>f.close()<EOL><DEDENT>

Save changes to a file.

        If no filename is given, the one most recently loaded is used.

        Keyword arguments:
        v1 -- if 0, ID3v1 tags will be removed
              if 1, ID3v1 tags will be updated but not added
              if 2, ID3v1 tags will be created and/or updated
        v2 -- version of ID3v2 tags (3 or 4).

        By default Mutagen saves ID3v2.4 tags. If you want to save ID3v2.3
        tags, you must call method update_to_v23 before saving the file.

        v23_sep -- the separator used to join multiple text values
                   if v2_version == 3. Defaults to '/' but if it's None
                   will be the ID3v2v2.4 null separator.

        The lack of a way to update only an ID3v1 tag is intentional.


def delete(self, filename=None, delete_v1=True, delete_v2=True):

if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>delete(filename, delete_v1, delete_v2)<EOL>self.clear()<EOL>

Remove tags from a file.

        If no filename is given, the one most recently loaded is used.

        Keyword arguments:

        * delete_v1 -- delete any ID3v1 tag
        * delete_v2 -- delete any ID3v2 tag


if "<STR_LIT>" in self:<EOL><INDENT>self["<STR_LIT>"].genres = self["<STR_LIT>"].genres<EOL><DEDENT>if self.version < self._V23:<EOL><INDENT>pics = self.getall("<STR_LIT>")<EOL>mimes = {"<STR_LIT>": "<STR_LIT>", "<STR_LIT>": "<STR_LIT>"}<EOL>self.delall("<STR_LIT>")<EOL>for pic in pics:<EOL><INDENT>newpic = APIC(<EOL>encoding=pic.encoding, mime=mimes.get(pic.mime, pic.mime),<EOL>type=pic.type, desc=pic.desc, data=pic.data)<EOL>self.add(newpic)<EOL><DEDENT>self.delall("<STR_LIT>")<EOL><DEDENT>


self.__update_common()<EOL>if self.__unknown_version == self._V23:<EOL><INDENT>converted = []<EOL>for frame in self.unknown_frames:<EOL><INDENT>try:<EOL><INDENT>name, size, flags = unpack('<STR_LIT>', frame[:<NUM_LIT:10>])<EOL>frame = BinaryFrame.fromData(self, flags, frame[<NUM_LIT:10>:])<EOL><DEDENT>except (struct.error, error):<EOL><INDENT>continue<EOL><DEDENT>name = name.decode('<STR_LIT:ascii>')<EOL>converted.append(self.__save_frame(frame, name=name))<EOL><DEDENT>self.unknown_frames[:] = converted<EOL>self.__unknown_version = self._V24<EOL><DEDENT>try:<EOL><INDENT>date = text_type(self.get("<STR_LIT>", "<STR_LIT>"))<EOL>if date.strip(u"<STR_LIT:\x00>"):<EOL><INDENT>self.pop("<STR_LIT>")<EOL>dat = text_type(self.get("<STR_LIT>", "<STR_LIT>"))<EOL>if dat.strip("<STR_LIT:\x00>"):<EOL><INDENT>self.pop("<STR_LIT>")<EOL>date = "<STR_LIT>" % (date, dat[<NUM_LIT:2>:], dat[:<NUM_LIT:2>])<EOL>time = text_type(self.get("<STR_LIT>", "<STR_LIT>"))<EOL>if time.strip("<STR_LIT:\x00>"):<EOL><INDENT>self.pop("<STR_LIT>")<EOL>date += "<STR_LIT>" % (time[:<NUM_LIT:2>], time[<NUM_LIT:2>:])<EOL><DEDENT><DEDENT>if "<STR_LIT>" not in self:<EOL><INDENT>self.add(TDRC(encoding=<NUM_LIT:0>, text=date))<EOL><DEDENT><DEDENT><DEDENT>except UnicodeDecodeError:<EOL><INDENT>pass<EOL><DEDENT>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>if "<STR_LIT>" not in self:<EOL><INDENT>try:<EOL><INDENT>self.add(TDOR(encoding=<NUM_LIT:0>, text=str(f)))<EOL><DEDENT>except UnicodeDecodeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>if "<STR_LIT>" not in self:<EOL><INDENT>self.add(TIPL(encoding=f.encoding, people=f.people))<EOL><DEDENT><DEDENT>for key in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>if key in self:<EOL><INDENT>del(self[key])<EOL><DEDENT><DEDENT>

Convert older tags into an ID3v2.4 tag.

        This updates old ID3v2 frames to ID3v2.4 ones (e.g. TYER to
        TDRC). If you intend to save tags, you must call this function
        at some point; it is called by default when loading the tag.


self.__update_common()<EOL>if "<STR_LIT>" in self or "<STR_LIT>" in self:<EOL><INDENT>people = []<EOL>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>people.extend(f.people)<EOL><DEDENT>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>people.extend(f.people)<EOL><DEDENT>if "<STR_LIT>" not in self:<EOL><INDENT>self.add(IPLS(encoding=f.encoding, people=people))<EOL><DEDENT><DEDENT>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>if f.text:<EOL><INDENT>d = f.text[<NUM_LIT:0>]<EOL>if d.year and "<STR_LIT>" not in self:<EOL><INDENT>self.add(TORY(encoding=f.encoding, text="<STR_LIT>" % d.year))<EOL><DEDENT><DEDENT><DEDENT>if "<STR_LIT>" in self:<EOL><INDENT>f = self.pop("<STR_LIT>")<EOL>if f.text:<EOL><INDENT>d = f.text[<NUM_LIT:0>]<EOL>if d.year and "<STR_LIT>" not in self:<EOL><INDENT>self.add(TYER(encoding=f.encoding, text="<STR_LIT>" % d.year))<EOL><DEDENT>if d.month and d.day and "<STR_LIT>" not in self:<EOL><INDENT>self.add(TDAT(encoding=f.encoding,<EOL>text="<STR_LIT>" % (d.day, d.month)))<EOL><DEDENT>if d.hour and d.minute and "<STR_LIT>" not in self:<EOL><INDENT>self.add(TIME(encoding=f.encoding,<EOL>text="<STR_LIT>" % (d.hour, d.minute)))<EOL><DEDENT><DEDENT><DEDENT>v24_frames = [<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>]<EOL>for key in v24_frames:<EOL><INDENT>if key in self:<EOL><INDENT>del(self[key])<EOL><DEDENT><DEDENT>

Convert older (and newer) tags into an ID3v2.3 tag.

        This updates incompatible ID3v2 frames to ID3v2.3 ones. If you
        intend to save tags as ID3v2.3, you must call this function
        at some point.

        If you want to to go off spec and include some v2.4 frames
        in v2.3, remove them before calling this and add them back afterwards.


if ID3 is None:<EOL><INDENT>ID3 = self.ID3<EOL><DEDENT>if self.tags is None:<EOL><INDENT>self.ID3 = ID3<EOL>self.tags = ID3()<EOL><DEDENT>else:<EOL><INDENT>raise error("<STR_LIT>")<EOL><DEDENT>

Add an empty ID3 tag to the file.

        A custom tag reader may be used in instead of the default
        mutagen.id3.ID3 object, e.g. an EasyID3 reader.


def load(self, filename, ID3=None, **kwargs):

if ID3 is None:<EOL><INDENT>ID3 = self.ID3<EOL><DEDENT>else:<EOL><INDENT>self.ID3 = ID3<EOL><DEDENT>self.filename = filename<EOL>try:<EOL><INDENT>self.tags = ID3(filename, **kwargs)<EOL><DEDENT>except error:<EOL><INDENT>self.tags = None<EOL><DEDENT>if self.tags is not None:<EOL><INDENT>try:<EOL><INDENT>offset = self.tags.size<EOL><DEDENT>except AttributeError:<EOL><INDENT>offset = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>offset = None<EOL><DEDENT>try:<EOL><INDENT>fileobj = open(filename, "<STR_LIT:rb>")<EOL>self.info = self._Info(fileobj, offset)<EOL><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>

Load stream and tag information from a file.

        A custom tag reader may be used in instead of the default
        mutagen.id3.ID3 object, e.g. an EasyID3 reader.


def _validate23(self, frame, value, **kwargs):

return value<EOL>

Return a possibly modified value which, if written,
        results in valid id3v2.3 data.


try:<EOL><INDENT>return (self.write() == other.write())<EOL><DEDENT>except AttributeError:<EOL><INDENT>return False<EOL><DEDENT>

Two Ogg pages are the same if they write the same data.


data = [<EOL>struct.pack("<STR_LIT>", b"<STR_LIT>", self.version, self.__type_flags,<EOL>self.position, self.serial, self.sequence, <NUM_LIT:0>)<EOL>]<EOL>lacing_data = []<EOL>for datum in self.packets:<EOL><INDENT>quot, rem = divmod(len(datum), <NUM_LIT:255>)<EOL>lacing_data.append(b"<STR_LIT>" * quot + chr_(rem))<EOL><DEDENT>lacing_data = b"<STR_LIT>".join(lacing_data)<EOL>if not self.complete and lacing_data.endswith(b"<STR_LIT:\x00>"):<EOL><INDENT>lacing_data = lacing_data[:-<NUM_LIT:1>]<EOL><DEDENT>data.append(chr_(len(lacing_data)))<EOL>data.append(lacing_data)<EOL>data.extend(self.packets)<EOL>data = b"<STR_LIT>".join(data)<EOL>crc = (~zlib.crc32(data.translate(cdata.bitswap), -<NUM_LIT:1>)) & <NUM_LIT><EOL>crc = cdata.to_uint_be(crc).translate(cdata.bitswap)<EOL>data = data[:<NUM_LIT>] + crc + data[<NUM_LIT>:]<EOL>return data<EOL>

Return a string encoding of the page header and data.

        A ValueError is raised if the data is too big to fit in a
        single page.


header_size = <NUM_LIT> <EOL>for datum in self.packets:<EOL><INDENT>quot, rem = divmod(len(datum), <NUM_LIT:255>)<EOL>header_size += quot + <NUM_LIT:1><EOL><DEDENT>if not self.complete and rem == <NUM_LIT:0>:<EOL><INDENT>header_size -= <NUM_LIT:1><EOL><DEDENT>header_size += sum(map(len, self.packets))<EOL>return header_size<EOL>


@staticmethod<EOL><INDENT>def renumber(fileobj, serial, start):<DEDENT>

number = start<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>page = OggPage(fileobj)<EOL><DEDENT>except EOFError:<EOL><INDENT>break<EOL><DEDENT>else:<EOL><INDENT>if page.serial != serial:<EOL><INDENT>continue<EOL><DEDENT>fileobj.seek(-page.size, <NUM_LIT:1>)<EOL><DEDENT>page.sequence = number<EOL>fileobj.write(page.write())<EOL>fileobj.seek(page.offset + page.size, <NUM_LIT:0>)<EOL>number += <NUM_LIT:1><EOL><DEDENT>

Renumber pages belonging to a specified logical stream.

        fileobj must be opened with mode r+b or w+b.

        Starting at page number 'start', renumber all pages belonging
        to logical stream 'serial'. Other pages will be ignored.

        fileobj must point to the start of a valid Ogg page; any
        occuring after it and part of the specified logical stream
        will be numbered. No adjustment will be made to the data in
        the pages nor the granule position; only the page number, and
        so also the CRC.

        If an error occurs (e.g. non-Ogg data is found), fileobj will
        be left pointing to the place in the stream the error occured,
        but the invalid data will be left intact (since this function
        does not change the total file size).


serial = pages[<NUM_LIT:0>].serial<EOL>sequence = pages[<NUM_LIT:0>].sequence<EOL>packets = []<EOL>if strict:<EOL><INDENT>if pages[<NUM_LIT:0>].continued:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if not pages[-<NUM_LIT:1>].complete:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>elif pages and pages[<NUM_LIT:0>].continued:<EOL><INDENT>packets.append([b"<STR_LIT>"])<EOL><DEDENT>for page in pages:<EOL><INDENT>if serial != page.serial:<EOL><INDENT>raise ValueError("<STR_LIT>" % page)<EOL><DEDENT>elif sequence != page.sequence:<EOL><INDENT>raise ValueError("<STR_LIT>" % page)<EOL><DEDENT>else:<EOL><INDENT>sequence += <NUM_LIT:1><EOL><DEDENT>if page.continued:<EOL><INDENT>packets[-<NUM_LIT:1>].append(page.packets[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>packets.append([page.packets[<NUM_LIT:0>]])<EOL><DEDENT>packets.extend([p] for p in page.packets[<NUM_LIT:1>:])<EOL><DEDENT>return [b"<STR_LIT>".join(p) for p in packets]<EOL>

Construct a list of packet data from a list of Ogg pages.

        If strict is true, the first page must start a new packet,
        and the last page must end the last packet.


chunk_size = (default_size // <NUM_LIT:255>) * <NUM_LIT:255><EOL>pages = []<EOL>page = OggPage()<EOL>page.sequence = sequence<EOL>for packet in packets:<EOL><INDENT>page.packets.append(b"<STR_LIT>")<EOL>while packet:<EOL><INDENT>data, packet = packet[:chunk_size], packet[chunk_size:]<EOL>if page.size < default_size and len(page.packets) < <NUM_LIT:255>:<EOL><INDENT>page.packets[-<NUM_LIT:1>] += data<EOL><DEDENT>else:<EOL><INDENT>if page.packets[-<NUM_LIT:1>]:<EOL><INDENT>page.complete = False<EOL>if len(page.packets) == <NUM_LIT:1>:<EOL><INDENT>page.position = -<NUM_LIT:1><EOL><DEDENT><DEDENT>else:<EOL><INDENT>page.packets.pop(-<NUM_LIT:1>)<EOL><DEDENT>pages.append(page)<EOL>page = OggPage()<EOL>page.continued = not pages[-<NUM_LIT:1>].complete<EOL>page.sequence = pages[-<NUM_LIT:1>].sequence + <NUM_LIT:1><EOL>page.packets.append(data)<EOL><DEDENT>if len(packet) < wiggle_room:<EOL><INDENT>page.packets[-<NUM_LIT:1>] += packet<EOL>packet = b"<STR_LIT>"<EOL><DEDENT><DEDENT><DEDENT>if page.packets:<EOL><INDENT>pages.append(page)<EOL><DEDENT>return pages<EOL>

Construct a list of Ogg pages from a list of packet data.

        The algorithm will generate pages of approximately
        default_size in size (rounded down to the nearest multiple of
        255). However, it will also allow pages to increase to
        approximately default_size + wiggle_room if allowing the
        wiggle room would finish a packet (only one packet will be
        finished in this way per page; if the next packet would fit
        into the wiggle room, it still starts on a new page).

        This method reduces packet fragmentation when packet sizes are
        slightly larger than the default page size, while still
        ensuring most pages are of the average size.

        Pages are numbered started at 'sequence'; other information is
        uninitialized.


@classmethod<EOL><INDENT>def replace(cls, fileobj, old_pages, new_pages):<DEDENT>

<EOL>first = old_pages[<NUM_LIT:0>].sequence<EOL>for page, seq in zip(new_pages, range(first, first + len(new_pages))):<EOL><INDENT>page.sequence = seq<EOL>page.serial = old_pages[<NUM_LIT:0>].serial<EOL><DEDENT>new_pages[<NUM_LIT:0>].first = old_pages[<NUM_LIT:0>].first<EOL>new_pages[<NUM_LIT:0>].last = old_pages[<NUM_LIT:0>].last<EOL>new_pages[<NUM_LIT:0>].continued = old_pages[<NUM_LIT:0>].continued<EOL>new_pages[-<NUM_LIT:1>].first = old_pages[-<NUM_LIT:1>].first<EOL>new_pages[-<NUM_LIT:1>].last = old_pages[-<NUM_LIT:1>].last<EOL>new_pages[-<NUM_LIT:1>].complete = old_pages[-<NUM_LIT:1>].complete<EOL>if not new_pages[-<NUM_LIT:1>].complete and len(new_pages[-<NUM_LIT:1>].packets) == <NUM_LIT:1>:<EOL><INDENT>new_pages[-<NUM_LIT:1>].position = -<NUM_LIT:1><EOL><DEDENT>new_data = b'<STR_LIT>'.join(cls.write(p) for p in new_pages)<EOL>delta = len(new_data)<EOL>fileobj.seek(old_pages[<NUM_LIT:0>].offset, <NUM_LIT:0>)<EOL>insert_bytes(fileobj, delta, old_pages[<NUM_LIT:0>].offset)<EOL>fileobj.seek(old_pages[<NUM_LIT:0>].offset, <NUM_LIT:0>)<EOL>fileobj.write(new_data)<EOL>new_data_end = old_pages[<NUM_LIT:0>].offset + delta<EOL>old_pages.reverse()<EOL>for old_page in old_pages:<EOL><INDENT>adj_offset = old_page.offset + delta<EOL>delete_bytes(fileobj, old_page.size, adj_offset)<EOL><DEDENT>if len(old_pages) != len(new_pages):<EOL><INDENT>fileobj.seek(new_data_end, <NUM_LIT:0>)<EOL>serial = new_pages[-<NUM_LIT:1>].serial<EOL>sequence = new_pages[-<NUM_LIT:1>].sequence + <NUM_LIT:1><EOL>cls.renumber(fileobj, serial, sequence)<EOL><DEDENT>

Replace old_pages with new_pages within fileobj.

        old_pages must have come from reading fileobj originally.
        new_pages are assumed to have the 'same' data as old_pages,
        and so the serial and sequence numbers will be copied, as will
        the flags for the first and last pages.

        fileobj will be resized and pages renumbered as necessary. As
        such, it must be opened r+b or w+b.


<EOL>try:<EOL><INDENT>fileobj.seek(-<NUM_LIT>*<NUM_LIT>, <NUM_LIT:2>)<EOL><DEDENT>except IOError:<EOL><INDENT>fileobj.seek(<NUM_LIT:0>)<EOL><DEDENT>data = fileobj.read()<EOL>try:<EOL><INDENT>index = data.rindex(b"<STR_LIT>")<EOL><DEDENT>except ValueError:<EOL><INDENT>raise error("<STR_LIT>")<EOL><DEDENT>bytesobj = cBytesIO(data[index:])<EOL>best_page = None<EOL>try:<EOL><INDENT>page = OggPage(bytesobj)<EOL><DEDENT>except error:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>if page.serial == serial:<EOL><INDENT>if page.last:<EOL><INDENT>return page<EOL><DEDENT>else:<EOL><INDENT>best_page = page<EOL><DEDENT><DEDENT>else:<EOL><INDENT>best_page = None<EOL><DEDENT><DEDENT>fileobj.seek(<NUM_LIT:0>)<EOL>try:<EOL><INDENT>page = OggPage(fileobj)<EOL>while not page.last:<EOL><INDENT>page = OggPage(fileobj)<EOL>while page.serial != serial:<EOL><INDENT>page = OggPage(fileobj)<EOL><DEDENT>best_page = page<EOL><DEDENT>return page<EOL><DEDENT>except error:<EOL><INDENT>return best_page<EOL><DEDENT>except EOFError:<EOL><INDENT>return best_page<EOL><DEDENT>

Find the last page of the stream 'serial'.

        If the file is not multiplexed this function is fast. If it is,
        it must read the whole the stream.

        This finds the last page in the actual file object, or the last
        page in the stream (with eos set), whichever comes first.


self.filename = filename<EOL>fileobj = open(filename, "<STR_LIT:rb>")<EOL>try:<EOL><INDENT>try:<EOL><INDENT>self.info = self._Info(fileobj)<EOL>self.tags = self._Tags(fileobj, self.info)<EOL>self.info._post_tags(fileobj)<EOL><DEDENT>except error as e:<EOL><INDENT>reraise(self._Error, e, sys.exc_info()[<NUM_LIT:2>])<EOL><DEDENT>except EOFError:<EOL><INDENT>raise self._Error("<STR_LIT>")<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>


if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>self.tags.clear()<EOL>fileobj = open(filename, "<STR_LIT>")<EOL>try:<EOL><INDENT>try:<EOL><INDENT>self.tags._inject(fileobj)<EOL><DEDENT>except error as e:<EOL><INDENT>reraise(self._Error, e, sys.exc_info()[<NUM_LIT:2>])<EOL><DEDENT>except EOFError:<EOL><INDENT>raise self._Error("<STR_LIT>")<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>

Remove tags from a file.

        If no filename is given, the one most recently loaded is used.


if filename is None:<EOL><INDENT>filename = self.filename<EOL><DEDENT>fileobj = open(filename, "<STR_LIT>")<EOL>try:<EOL><INDENT>try:<EOL><INDENT>self.tags._inject(fileobj)<EOL><DEDENT>except error as e:<EOL><INDENT>reraise(self._Error, e, sys.exc_info()[<NUM_LIT:2>])<EOL><DEDENT>except EOFError:<EOL><INDENT>raise self._Error("<STR_LIT>")<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>

Save a tag to a file.

        If no filename is given, the one most recently loaded is used.


assert bits <= <NUM_LIT:8><EOL>mask = (((<NUM_LIT:1> << (<NUM_LIT:8> - bits)) - <NUM_LIT:1>) << bits)<EOL>if isinstance(value, integer_types):<EOL><INDENT>while value:<EOL><INDENT>if value & mask:<EOL><INDENT>return False<EOL><DEDENT>value >>= <NUM_LIT:8><EOL><DEDENT><DEDENT>elif isinstance(value, bytes):<EOL><INDENT>for byte in bytearray(value):<EOL><INDENT>if byte & mask:<EOL><INDENT>return False<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError<EOL><DEDENT>return True<EOL>


OggFLAC(filename).delete()<EOL>


<EOL>fileobj.seek(<NUM_LIT:0>)<EOL>page = OggPage(fileobj)<EOL>while not page.packets[<NUM_LIT:0>].startswith(b"<STR_LIT>"):<EOL><INDENT>page = OggPage(fileobj)<EOL><DEDENT>first_page = page<EOL>while not (page.sequence == <NUM_LIT:1> and page.serial == first_page.serial):<EOL><INDENT>page = OggPage(fileobj)<EOL><DEDENT>old_pages = [page]<EOL>while not (old_pages[-<NUM_LIT:1>].complete or len(old_pages[-<NUM_LIT:1>].packets) > <NUM_LIT:1>):<EOL><INDENT>page = OggPage(fileobj)<EOL>if page.serial == first_page.serial:<EOL><INDENT>old_pages.append(page)<EOL><DEDENT><DEDENT>packets = OggPage.to_packets(old_pages, strict=False)<EOL>data = self.write()<EOL>data = packets[<NUM_LIT:0>][:<NUM_LIT:1>] + struct.pack("<STR_LIT>", len(data))[-<NUM_LIT:3>:] + data<EOL>packets[<NUM_LIT:0>] = data<EOL>new_pages = OggPage.from_packets(packets, old_pages[<NUM_LIT:0>].sequence)<EOL>OggPage.replace(fileobj, old_pages, new_pages)<EOL>

Write tag data into the FLAC Vorbis comment packet/page.


header = fileobj.read(<NUM_LIT:32>)<EOL>if len(header) != <NUM_LIT:32> or not header.startswith(b"<STR_LIT>"):<EOL><INDENT>raise WavPackHeaderError("<STR_LIT>" % header)<EOL><DEDENT>block_size = cdata.uint_le(header[<NUM_LIT:4>:<NUM_LIT:8>])<EOL>version = cdata.ushort_le(header[<NUM_LIT:8>:<NUM_LIT:10>])<EOL>track_no = ord(header[<NUM_LIT:10>:<NUM_LIT:11>])<EOL>index_no = ord(header[<NUM_LIT:11>:<NUM_LIT:12>])<EOL>samples = cdata.uint_le(header[<NUM_LIT:12>:<NUM_LIT:16>])<EOL>if samples == <NUM_LIT:2>**<NUM_LIT:32> - <NUM_LIT:1>:<EOL><INDENT>samples = -<NUM_LIT:1><EOL><DEDENT>block_index = cdata.uint_le(header[<NUM_LIT:16>:<NUM_LIT:20>])<EOL>block_samples = cdata.uint_le(header[<NUM_LIT:20>:<NUM_LIT>])<EOL>flags = cdata.uint_le(header[<NUM_LIT>:<NUM_LIT>])<EOL>crc = cdata.uint_le(header[<NUM_LIT>:<NUM_LIT:32>])<EOL>return _WavPackHeader(block_size, version, track_no, index_no,<EOL>samples, block_index, block_samples, flags, crc)<EOL>

A new _WavPackHeader or raises WavPackHeaderError


OggOpus(filename).delete()<EOL>


if PY3 and isinstance(key, bytes):<EOL><INDENT>raise ValueError<EOL><DEDENT>for c in key:<EOL><INDENT>if c < "<STR_LIT:U+0020>" or c > "<STR_LIT:}>" or c == "<STR_LIT:=>":<EOL><INDENT>return False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return bool(key)<EOL><DEDENT>

Return true if a string is a valid Vorbis comment key.

    Valid Vorbis comment keys are printable ASCII between 0x20 (space)
    and 0x7D ('}'), excluding '='.

    Takes str/unicode in Python 2, unicode in Python 3


def load(self, fileobj, errors='<STR_LIT:replace>', framing=True):

try:<EOL><INDENT>vendor_length = cdata.uint_le(fileobj.read(<NUM_LIT:4>))<EOL>self.vendor = fileobj.read(vendor_length).decode('<STR_LIT:utf-8>', errors)<EOL>count = cdata.uint_le(fileobj.read(<NUM_LIT:4>))<EOL>for i in xrange(count):<EOL><INDENT>length = cdata.uint_le(fileobj.read(<NUM_LIT:4>))<EOL>try:<EOL><INDENT>string = fileobj.read(length).decode('<STR_LIT:utf-8>', errors)<EOL><DEDENT>except (OverflowError, MemoryError):<EOL><INDENT>raise error("<STR_LIT>" % length)<EOL><DEDENT>try:<EOL><INDENT>tag, value = string.split('<STR_LIT:=>', <NUM_LIT:1>)<EOL><DEDENT>except ValueError as err:<EOL><INDENT>if errors == "<STR_LIT:ignore>":<EOL><INDENT>continue<EOL><DEDENT>elif errors == "<STR_LIT:replace>":<EOL><INDENT>tag, value = u"<STR_LIT>" % i, string<EOL><DEDENT>else:<EOL><INDENT>reraise(VorbisEncodingError, err, sys.exc_info()[<NUM_LIT:2>])<EOL><DEDENT><DEDENT>try:<EOL><INDENT>tag = tag.encode('<STR_LIT:ascii>', errors)<EOL><DEDENT>except UnicodeEncodeError:<EOL><INDENT>raise VorbisEncodingError("<STR_LIT>" % tag)<EOL><DEDENT>else:<EOL><INDENT>if PY3:<EOL><INDENT>tag = tag.decode("<STR_LIT:ascii>")<EOL><DEDENT>if is_valid_key(tag):<EOL><INDENT>self.append((tag, value))<EOL><DEDENT><DEDENT><DEDENT>if framing and not bytearray(fileobj.read(<NUM_LIT:1>))[<NUM_LIT:0>] & <NUM_LIT>:<EOL><INDENT>raise VorbisUnsetFrameError("<STR_LIT>")<EOL><DEDENT><DEDENT>except (cdata.error, TypeError):<EOL><INDENT>raise error("<STR_LIT>")<EOL><DEDENT>

Parse a Vorbis comment from a file-like object.

        Keyword arguments:

        * errors:
            'strict', 'replace', or 'ignore'. This affects Unicode decoding
            and how other malformed content is interpreted.
        * framing -- if true, fail if a framing bit is not present

        Framing bits are required by the Vorbis comment specification,
        but are not used in FLAC Vorbis comment blocks.


<EOL>if PY3:<EOL><INDENT>if not isinstance(self.vendor, text_type):<EOL><INDENT>raise ValueError<EOL><DEDENT>for key, value in self:<EOL><INDENT>if not isinstance(key, text_type):<EOL><INDENT>raise ValueError<EOL><DEDENT>if not isinstance(value, text_type):<EOL><INDENT>raise ValueError<EOL><DEDENT><DEDENT><DEDENT>if not isinstance(self.vendor, text_type):<EOL><INDENT>try:<EOL><INDENT>self.vendor.decode('<STR_LIT:utf-8>')<EOL><DEDENT>except UnicodeDecodeError:<EOL><INDENT>raise ValueError<EOL><DEDENT><DEDENT>for key, value in self._internal:<EOL><INDENT>try:<EOL><INDENT>if not is_valid_key(key):<EOL><INDENT>raise ValueError<EOL><DEDENT><DEDENT>except:<EOL><INDENT>raise ValueError("<STR_LIT>" % key)<EOL><DEDENT>if not isinstance(value, text_type):<EOL><INDENT>try:<EOL><INDENT>value.decode("<STR_LIT:utf-8>")<EOL><DEDENT>except:<EOL><INDENT>raise ValueError("<STR_LIT>" % value)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Validate keys and values.

        Check to make sure every key used is a valid Vorbis key, and
        that every value used is a valid Unicode or UTF-8 string. If
        any invalid keys or values are found, a ValueError is raised.

        In Python 3 all keys and values have to be a string.


for i in list(self._internal):<EOL><INDENT>self._internal.remove(i)<EOL><DEDENT>


self.validate()<EOL>def _encode(value):<EOL><INDENT>if not isinstance(value, bytes):<EOL><INDENT>return value.encode('<STR_LIT:utf-8>')<EOL><DEDENT>return value<EOL><DEDENT>f = BytesIO()<EOL>vendor = _encode(self.vendor)<EOL>f.write(cdata.to_uint_le(len(vendor)))<EOL>f.write(vendor)<EOL>f.write(cdata.to_uint_le(len(self)))<EOL>for tag, value in self._internal:<EOL><INDENT>tag = _encode(tag)<EOL>value = _encode(value)<EOL>comment = tag + b"<STR_LIT:=>" + value<EOL>f.write(cdata.to_uint_le(len(comment)))<EOL>f.write(comment)<EOL><DEDENT>if framing:<EOL><INDENT>f.write(b"<STR_LIT>")<EOL><DEDENT>return f.getvalue()<EOL>

Return a string representation of the data.

        Validation is always performed, so calling this function on
        invalid data may raise a ValueError.

        Keyword arguments:

        * framing -- if true, append a framing bit (see load)


if not is_valid_key(key):<EOL><INDENT>raise ValueError<EOL><DEDENT>key = key.lower()<EOL>values = [value for (k, value) in self._internal if k.lower() == key]<EOL>if not values:<EOL><INDENT>raise KeyError(key)<EOL><DEDENT>else:<EOL><INDENT>return values<EOL><DEDENT>

A list of values for the key.

        This is a copy, so comment['title'].append('a title') will not
        work.


if not is_valid_key(key):<EOL><INDENT>raise ValueError<EOL><DEDENT>key = key.lower()<EOL>to_delete = [x for x in self._internal if x[<NUM_LIT:0>].lower() == key]<EOL>if not to_delete:<EOL><INDENT>raise KeyError(key)<EOL><DEDENT>else:<EOL><INDENT>for item in to_delete:<EOL><INDENT>self._internal.remove(item)<EOL><DEDENT><DEDENT>

Delete all values associated with the key.


if not is_valid_key(key):<EOL><INDENT>raise ValueError<EOL><DEDENT>if not isinstance(values, list):<EOL><INDENT>values = [values]<EOL><DEDENT>try:<EOL><INDENT>del(self[key])<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>if PY2:<EOL><INDENT>key = key.encode('<STR_LIT:ascii>')<EOL><DEDENT>for value in values:<EOL><INDENT>self.append((key, value))<EOL><DEDENT>

Set a key's value or values.

        Setting a value overwrites all old ones. The value may be a
        list of Unicode or UTF-8 strings, or a single Unicode or UTF-8
        string.


d = {}<EOL>for key, value in self._internal:<EOL><INDENT>d.setdefault(key.lower(), []).append(value)<EOL><DEDENT>return d<EOL>

Return a copy of the comment data in a real dict.


<EOL>size = len(data) + <NUM_LIT:8><EOL>if size <= <NUM_LIT>:<EOL><INDENT>return struct.pack("<STR_LIT>", size, name) + data<EOL><DEDENT>else:<EOL><INDENT>return struct.pack("<STR_LIT>", <NUM_LIT:1>, name, size + <NUM_LIT:8>) + data<EOL><DEDENT>


def findall(self, name, recursive=False):

if self.children is not None:<EOL><INDENT>for child in self.children:<EOL><INDENT>if child.name == name:<EOL><INDENT>yield child<EOL><DEDENT>if recursive:<EOL><INDENT>for atom in child.findall(name, True):<EOL><INDENT>yield atom<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Recursively find all child atoms by specified name.


if not remaining:<EOL><INDENT>return self<EOL><DEDENT>elif self.children is None:<EOL><INDENT>raise KeyError("<STR_LIT>" % self.name)<EOL><DEDENT>for child in self.children:<EOL><INDENT>if child.name == remaining[<NUM_LIT:0>]:<EOL><INDENT>return child[remaining[<NUM_LIT:1>:]]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise KeyError("<STR_LIT>" % remaining[<NUM_LIT:0>])<EOL><DEDENT>

Look up a child atom, potentially recursively.

        e.g. atom['udta', 'meta'] => <Atom name='meta' ...>


path = [self]<EOL>for name in names:<EOL><INDENT>path.append(path[-<NUM_LIT:1>][name, ])<EOL><DEDENT>return path[<NUM_LIT:1>:]<EOL>

Look up and return the complete path of an atom.

        For example, atoms.path('moov', 'udta', 'meta') will return a
        list of three atoms, corresponding to the moov, udta, and meta
        atoms.


if isinstance(names, bytes):<EOL><INDENT>names = names.split(b"<STR_LIT:.>")<EOL><DEDENT>for child in self.atoms:<EOL><INDENT>if child.name == names[<NUM_LIT:0>]:<EOL><INDENT>return child[names[<NUM_LIT:1>:]]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise KeyError("<STR_LIT>" % names[<NUM_LIT:0>])<EOL><DEDENT>

Look up a child atom.

        'names' may be a list of atoms (['moov', 'udta']) or a string
        specifying the complete path ('moov.udta').


values = []<EOL>items = sorted(self.items(), key=MP4Tags.__get_sort_stats )<EOL>for key, value in items:<EOL><INDENT>info = self.__atoms.get(key[:<NUM_LIT:4>], (None, type(self).__render_text))<EOL>try:<EOL><INDENT>values.append(info[<NUM_LIT:1>](self, key, value, *info[<NUM_LIT:2>:]))<EOL><DEDENT>except (TypeError, ValueError) as s:<EOL><INDENT>reraise(MP4MetadataValueError, s, sys.exc_info()[<NUM_LIT:2>])<EOL><DEDENT><DEDENT>data = Atom.render(b"<STR_LIT>", b"<STR_LIT>".join(values))<EOL>fileobj = open(filename, "<STR_LIT>")<EOL>try:<EOL><INDENT>atoms = Atoms(fileobj)<EOL>try:<EOL><INDENT>path = atoms.path(b"<STR_LIT>", b"<STR_LIT>", b"<STR_LIT>", b"<STR_LIT>")<EOL><DEDENT>except KeyError:<EOL><INDENT>self.__save_new(fileobj, atoms, data)<EOL><DEDENT>else:<EOL><INDENT>self.__save_existing(fileobj, atoms, path, data)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>fileobj.close()<EOL><DEDENT>

Save the metadata to the given filename.


def __update_parents(self, fileobj, path, delta):

for atom in path:<EOL><INDENT>fileobj.seek(atom.offset)<EOL>size = cdata.uint_be(fileobj.read(<NUM_LIT:4>))<EOL>if size == <NUM_LIT:1>:  <EOL><INDENT>size = cdata.ulonglong_be(fileobj.read(<NUM_LIT:12>)[<NUM_LIT:4>:])<EOL>fileobj.seek(atom.offset + <NUM_LIT:8>)<EOL>fileobj.write(cdata.to_ulonglong_be(size + delta))<EOL><DEDENT>else:  <EOL><INDENT>fileobj.seek(atom.offset)<EOL>fileobj.write(cdata.to_uint_be(size + delta))<EOL><DEDENT><DEDENT>

Update all parent atoms with the new size.


def __update_offset_table(self, fileobj, fmt, atom, delta, offset):

if atom.offset > offset:<EOL><INDENT>atom.offset += delta<EOL><DEDENT>fileobj.seek(atom.offset + <NUM_LIT:12>)<EOL>data = fileobj.read(atom.length - <NUM_LIT:12>)<EOL>fmt = fmt % cdata.uint_be(data[:<NUM_LIT:4>])<EOL>offsets = struct.unpack(fmt, data[<NUM_LIT:4>:])<EOL>offsets = [o + (<NUM_LIT:0>, delta)[offset < o] for o in offsets]<EOL>fileobj.seek(atom.offset + <NUM_LIT:16>)<EOL>fileobj.write(struct.pack(fmt, *offsets))<EOL>

Update offset table in the specified atom.


def __update_offsets(self, fileobj, atoms, delta, offset):

if delta == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>moov = atoms[b"<STR_LIT>"]<EOL>for atom in moov.findall(b'<STR_LIT>', True):<EOL><INDENT>self.__update_offset_table(fileobj, "<STR_LIT>", atom, delta, offset)<EOL><DEDENT>for atom in moov.findall(b'<STR_LIT>', True):<EOL><INDENT>self.__update_offset_table(fileobj, "<STR_LIT>", atom, delta, offset)<EOL><DEDENT>try:<EOL><INDENT>for atom in atoms[b"<STR_LIT>"].findall(b'<STR_LIT>', True):<EOL><INDENT>self.__update_tfhd(fileobj, atom, delta, offset)<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>

Update offset tables in all 'stco' and 'co64' atoms.


self.clear()<EOL>self.save(filename)<EOL>

Remove the metadata from the given filename.


num = <NUM_LIT:0><EOL>for i in xrange(limit):<EOL><INDENT>c = fileobj.read(<NUM_LIT:1>)<EOL>if len(c) != <NUM_LIT:1>:<EOL><INDENT>raise EOFError<EOL><DEDENT>num = (num << <NUM_LIT:7>) | (ord_(c) & <NUM_LIT>)<EOL>if not ord_(c) & <NUM_LIT>:<EOL><INDENT>return num, i + <NUM_LIT:1><EOL><DEDENT><DEDENT>if limit > <NUM_LIT:0>:<EOL><INDENT>raise ValueError<EOL><DEDENT>return <NUM_LIT:0>, <NUM_LIT:0><EOL>

Reads (max limit) bytes from fileobj until the MSB is zero.
    All 7 LSB will be merged to a big endian uint.

    Raises ValueError in case not MSB is zero, or EOFError in
    case the file ended before limit is reached.

    Returns (parsed number, number of bytes read)


@classmethod<EOL><INDENT>def RegisterKey(cls, key,<EOL>getter=None, setter=None, deleter=None, lister=None):<DEDENT>

key = key.lower()<EOL>if getter is not None:<EOL><INDENT>cls.Get[key] = getter<EOL><DEDENT>if setter is not None:<EOL><INDENT>cls.Set[key] = setter<EOL><DEDENT>if deleter is not None:<EOL><INDENT>cls.Delete[key] = deleter<EOL><DEDENT>if lister is not None:<EOL><INDENT>cls.List[key] = lister<EOL><DEDENT>

Register a new key mapping.

        A key mapping is four functions, a getter, setter, deleter,
        and lister. The key may be either a string or a glob pattern.

        The getter, deleted, and lister receive an MP4Tags instance
        and the requested key name. The setter also receives the
        desired value, which will be a list of strings.

        The getter, setter, and deleter are used to implement __getitem__,
        __setitem__, and __delitem__.

        The lister is used to implement keys(). It should return a
        list of keys that are actually in the MP4 instance, provided
        by its associated getter.


@classmethod<EOL><INDENT>def RegisterTextKey(cls, key, atomid):<DEDENT>

def getter(tags, key):<EOL><INDENT>return tags[atomid]<EOL><DEDENT>def setter(tags, key, value):<EOL><INDENT>tags[atomid] = value<EOL><DEDENT>def deleter(tags, key):<EOL><INDENT>del(tags[atomid])<EOL><DEDENT>cls.RegisterKey(key, getter, setter, deleter)<EOL>

Register a text key.

        If the key you need to register is a simple one-to-one mapping
        of MP4 atom name to EasyMP4Tags key, then you can use this
        function::

            EasyMP4Tags.RegisterTextKey("artist", b"\xa9ART")


@classmethod<EOL><INDENT>def RegisterIntKey(cls, key, atomid, min_value=<NUM_LIT:0>, max_value=<NUM_LIT:2>**<NUM_LIT:16>-<NUM_LIT:1>):<DEDENT>

def getter(tags, key):<EOL><INDENT>return list(map(text_type, tags[atomid]))<EOL><DEDENT>def setter(tags, key, value):<EOL><INDENT>clamp = lambda x: min(max(min_value, x), max_value)<EOL>tags[atomid] = [clamp(v) for v in map(int, value)]<EOL><DEDENT>def deleter(tags, key):<EOL><INDENT>del(tags[atomid])<EOL><DEDENT>cls.RegisterKey(key, getter, setter, deleter)<EOL>


@classmethod<EOL><INDENT>def RegisterFreeformKey(cls, key, name, mean=b"<STR_LIT>"):<DEDENT>

atomid = b"<STR_LIT>" + mean + b"<STR_LIT::>" + name<EOL>def getter(tags, key):<EOL><INDENT>return [s.decode("<STR_LIT:utf-8>", "<STR_LIT:replace>") for s in tags[atomid]]<EOL><DEDENT>def setter(tags, key, value):<EOL><INDENT>tags[atomid] = [utf8(v) for v in value]<EOL><DEDENT>def deleter(tags, key):<EOL><INDENT>del(tags[atomid])<EOL><DEDENT>cls.RegisterKey(key, getter, setter, deleter)<EOL>

Register a text key.

        If the key you need to register is a simple one-to-one mapping
        of MP4 freeform atom (----) and name to EasyMP4Tags key, then
        you can use this function::

            EasyMP4Tags.RegisterFreeformKey(
                "musicbrainz_artistid", b"MusicBrainz Artist Id")


strings = []<EOL>for key in sorted(self.keys()):<EOL><INDENT>values = self[key]<EOL>for value in values:<EOL><INDENT>strings.append("<STR_LIT>" % (key, value))<EOL><DEDENT><DEDENT>return "<STR_LIT:\n>".join(strings)<EOL>


@lru_cache(maxsize=<NUM_LIT:200>)<EOL><INDENT>def selectPolicy(self, origin, request_method=None):<DEDENT>

ret_origin = None<EOL>policyname = None<EOL>if self.matchstrategy in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>for pol in self.activepolicies:<EOL><INDENT>policy=self.policies[pol]<EOL>ret_origin = None<EOL>policyname = policy.name<EOL>if policyname == "<STR_LIT>":<EOL><INDENT>break<EOL><DEDENT>if self.matchstrategy == "<STR_LIT>":<EOL><INDENT>if policy.methods != "<STR_LIT:*>" and not CORS.matchlist(request_method, policy.methods, case_sensitive=True):<EOL><INDENT>continue<EOL><DEDENT><DEDENT>if origin and policy.match:<EOL><INDENT>if CORS.matchlist(origin, policy.match):<EOL><INDENT>ret_origin = origin<EOL><DEDENT><DEDENT>elif policy.origin == "<STR_LIT>":<EOL><INDENT>ret_origin = origin<EOL><DEDENT>elif policy.origin:<EOL><INDENT>ret_origin = policy.origin<EOL><DEDENT>if ret_origin:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>return policyname, ret_origin<EOL>

Based on the matching strategy and the origin and optionally the requested method a tuple of policyname and origin to pass back is returned.


req = prepRequest(hdr)<EOL>res = req.get_response(corsed)<EOL>assert res.body.decode("<STR_LIT:utf-8>") == "<STR_LIT>", "<STR_LIT>" % res.body<EOL>

requests that don't match preflight criteria are ignored


@wraps(func)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>res = func(*args, **kwargs)<EOL>project_command = args[<NUM_LIT:0>]<EOL>project_handler = project_command.vcp.project_handler<EOL>if not project_handler:<EOL><INDENT>return res<EOL><DEDENT>kwargs['<STR_LIT>'] = res<EOL>getattr(project_handler, func.__name__)(**kwargs)<EOL>return res<EOL><DEDENT>return wrapper<EOL>

Calls the project handler same named function

    Note: the project handler may add some extra arguments to the command,
          so when use this decorator, add **kwargs to the end of the arguments


pass<EOL>

Initialize the language specific part of the project, eg pip install or npm install.

        Returns:
            True if the initialization is succeeded, else False


@abstractmethod<EOL><INDENT>def install_to(self, project, env):<DEDENT>

pass<EOL>

Install current (self.project) project to the argument one.

        Args:
            project (Project): the target project
            env (EnvironmentBase): the target environment

        Returns:
            True if the install is succeeded, else False


def define_singleton(carrier, name, cls, cls_args = {}):

instance_name = "<STR_LIT>".format(name)<EOL>setattr(carrier, instance_name, None)<EOL>def getter(self):<EOL><INDENT>instance = getattr(carrier, instance_name)<EOL>if instance is None:<EOL><INDENT>instance = cls(**cls_args)<EOL>setattr(carrier, instance_name, instance)<EOL><DEDENT>return instance<EOL><DEDENT>setattr(type(carrier), name, property(getter))<EOL>

Creates a property with the given name, but the cls will created only with the first call

    Args:
        carrier: an instance of the class where want to reach the cls instance
        name (str): the variable name of the cls instance
        cls (type): the singleton object type
        cls_args (dict): optional dict for createing cls


def get_dependent_projects(self, recursive = True):

projects = {}<EOL>for name, ref in list(self.dependencies.items()):<EOL><INDENT>try:<EOL><INDENT>prj = self.vcp.projects[name]<EOL><DEDENT>except KeyError:<EOL><INDENT>logger.error("<STR_LIT>", name, self.name)<EOL>continue<EOL><DEDENT>projects[name] = prj<EOL>if recursive:<EOL><INDENT>projects.update(prj.get_dependent_projects())<EOL><DEDENT><DEDENT>return projects<EOL>

Get the dependencies of the Project

        Args:
            recursive (bool): add the dependant project's dependencies too

        Returns:
            dict of project name and project instances


matches = self.schema_pattern.search(uri)<EOL>if not matches:<EOL><INDENT>logger.error("<STR_LIT>", uri, list(self.handlers.keys()))<EOL>return None<EOL><DEDENT>schema = matches.group(<NUM_LIT:1>)<EOL>url = matches.group(<NUM_LIT:2>)<EOL>return self.handlers[schema](url, local_path)<EOL>

Create a project handler

        Args:
            uri (str): schema://something formatted uri
            local_path (str): the project configs directory

        Return:
            ProjectHandler derived class instance


projects = {}<EOL>path = os.path.expanduser(self.path)<EOL>if not os.path.isdir(path):<EOL><INDENT>return projects<EOL><DEDENT>logger.debug("<STR_LIT>", path)<EOL>for filename in os.listdir(path):<EOL><INDENT>filename_parts = os.path.splitext(filename)<EOL>if filename_parts[<NUM_LIT:1>][<NUM_LIT:1>:] != PROJECT_CONFIG_EXTENSION:<EOL><INDENT>continue<EOL><DEDENT>name = filename_parts[<NUM_LIT:0>]<EOL>try:<EOL><INDENT>project_file_path = os.path.join(path, filename)<EOL>with open(project_file_path) as f:<EOL><INDENT>data = yaml.load(f)<EOL><DEDENT>projects[name] = data<EOL><DEDENT>except ValueError:<EOL><INDENT>continue<EOL><DEDENT>logger.debug("<STR_LIT>".format(name, project_file_path))<EOL><DEDENT>return projects<EOL>

Load the projects config data from local path

        Returns:
            Dict: project_name -> project_data


base_path = os.path.expanduser(self.path)<EOL>if not os.path.isdir(base_path):<EOL><INDENT>return<EOL><DEDENT>logger.debug("<STR_LIT>", base_path)<EOL>for name, data in list(projects.items()):<EOL><INDENT>project_file_path = self.get_project_config_path(name)<EOL>with open(project_file_path, "<STR_LIT:w>") as f:<EOL><INDENT>yaml.dump(data, stream = f, default_flow_style = False)<EOL>logger.debug("<STR_LIT>", name, project_file_path)<EOL><DEDENT><DEDENT>

Save the projects configs to local path

        Args:
            projects (dict): project_name -> project_data


raise NotImplementedError("<STR_LIT>")<EOL>

Useful for defining weather data published to the server. Each
publication service implements their own supported keyword args, but
should support any number of arguments.


return self._publish( self.args, self.server, self.URI)<EOL>

Perform HTTP session to transmit defined weather values.


def set( self, pressure='<STR_LIT>', dewpoint='<STR_LIT>', humidity='<STR_LIT>', tempf='<STR_LIT>',<EOL>rainin='<STR_LIT>', rainday='<STR_LIT>', dateutc='<STR_LIT>', windgust='<STR_LIT>',<EOL>windgustdir='<STR_LIT>', windspeed='<STR_LIT>', winddir='<STR_LIT>',<EOL>clouds='<STR_LIT>', weather='<STR_LIT>', *args, **kw):

Useful for defining weather data published to the server. Parameters
not set will be reset and not sent to server. Unknown keyword args will
be silently ignored, so be careful. This is necessary for publishers
that support more fields than others.


def set( self, pressure='<STR_LIT>', dewpoint='<STR_LIT>', humidity='<STR_LIT>', tempf='<STR_LIT>',<EOL>rainin='<STR_LIT>', rainday='<STR_LIT>', rainmonth='<STR_LIT>', rainyear='<STR_LIT>',<EOL>dateutc='<STR_LIT>', windgust='<STR_LIT>', windspeed='<STR_LIT>', winddir='<STR_LIT>',<EOL>weather='<STR_LIT>', *args, **kw):

Useful for defining weather data published to the server. Parameters not
sent will be cleared and not set to server. Unknown keyword args will be
silently ignored, so be careful. This is necessary for publishers that
support more fields than others.


self.args = kw<EOL>log.debug( self.args )<EOL>

Store keyword args to be written to output file.


with open( self.file_name, '<STR_LIT:w>') as fh:<EOL><INDENT>for k,v in self.args.iteritems():<EOL><INDENT>buf = StringIO.StringIO()<EOL>buf.write(k)<EOL>self._append_vals(buf,v)<EOL>fh.write(buf.getvalue() + '<STR_LIT:\n>')<EOL>buf.close()<EOL><DEDENT><DEDENT>


return self.unpack_from( buf, offset=<NUM_LIT:0> )<EOL>


def unpack_from(self, buf, offset=<NUM_LIT:0> ):

data = super(Struct,self).unpack_from( buf, offset)<EOL>items = dict(zip(self.fields,data))<EOL>return self._post_unpack(items)<EOL>

unpacks data from 'buf' and returns a dication of named fields. the
fields can be post-processed by extending the _post_unpack() method.


return items<EOL>

perform data modification of any values, after unpacking from a buffer.


crc = <NUM_LIT:0><EOL>for byte in array('<STR_LIT:B>', data):<EOL><INDENT>crc = (VProCRC.CRC_TABLE[(crc >> <NUM_LIT:8>) ^ byte] ^ ((crc & <NUM_LIT>) << <NUM_LIT:8>))<EOL><DEDENT>return crc<EOL>

return CRC calc value from raw serial data


if len(data) == <NUM_LIT:0>:<EOL><INDENT>return False<EOL><DEDENT>crc = VProCRC.get(data)<EOL>if crc:<EOL><INDENT>log.info("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>log.debug("<STR_LIT>")<EOL><DEDENT>return not crc<EOL>

perform CRC check on raw serial data, return true if valid.
a valid CRC == 0.


<EOL>return "<STR_LIT>" % divmod(val, <NUM_LIT:100>)<EOL>

given a packed time field, unpack and return "HH:MM" string.


year = (date & <NUM_LIT>) + <NUM_LIT>  <EOL>day = (date >> <NUM_LIT:7>) & <NUM_LIT>  <EOL>month = (date >> <NUM_LIT:12>) & <NUM_LIT>  <EOL>return "<STR_LIT>" % (year, month, day)<EOL>

given a packed storm date field, unpack and return 'YYYY-MM-DD' string.


def __init__(self, device, log_interval=<NUM_LIT:5>, logStartDate=None, clear=False):

self.port = serial.Serial(device, BAUD, timeout=READ_DELAY)<EOL>if logStartDate is None:<EOL><INDENT>self._archive_time = (<NUM_LIT:0>, <NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>self._archive_time = (self.calcDateStamp(logStartDate), self.calcTimeStamp(logStartDate))<EOL><DEDENT>if clear:<EOL><INDENT>self._cmd('<STR_LIT>')  <EOL><DEDENT>self._cmd('<STR_LIT>', log_interval, ok=True)<EOL>

Initialize the serial connection with the console.
:param device: /dev/yourConsoleDevice
:param log_interval: default 5
:param logStartDate: the datetime.datetime object representing the starting log date. Default None aka "all"
:param clear: boolean, if true clean all the log in the console. Default False


return date.day + date.month * <NUM_LIT:32> + (date.year - <NUM_LIT>) * <NUM_LIT><EOL>

As stated into the Vantage Serial Protocol manual, this method converts a datetime object into the right DateStamp
:param date: the datetime object to convert
:return: the dateStamp integer


return <NUM_LIT:100> * date.hour + date.minute<EOL>

As stated into the Vantage Serial Protocol manual, this method converts a datetime object into the right TimeStamp
:param date: the datetime object to convert
:return: the timeStamp integer


self.port.close()<EOL>

close serial port when object is deleted.


def _use_rev_b_archive(self, records, offset):

<EOL>if type(self._ARCHIVE_REV_B) is bool:<EOL><INDENT>return self._ARCHIVE_REV_B<EOL><DEDENT>data = ArchiveBStruct.unpack_from(records, offset)<EOL>if data['<STR_LIT>'] == <NUM_LIT:0>:<EOL><INDENT>log.info('<STR_LIT>')<EOL>self._ARCHIVE_REV_B = True<EOL><DEDENT>else:<EOL><INDENT>log.info('<STR_LIT>')<EOL>self._ARCHIVE_REV_B = False<EOL><DEDENT>return self._ARCHIVE_REV_B<EOL>

return True if weather station returns Rev.B archives


log.info("<STR_LIT>")<EOL>for i in xrange(<NUM_LIT:3>):<EOL><INDENT>self.port.write('<STR_LIT:\n>')  <EOL>ack = self.port.read(len(self.WAKE_ACK))  <EOL>log_raw('<STR_LIT>', ack)<EOL>if ack == self.WAKE_ACK:<EOL><INDENT>return<EOL><DEDENT><DEDENT>raise NoDeviceException('<STR_LIT>')<EOL>

issue wakeup command to device to take out of standby mode.


ok = kw.setdefault('<STR_LIT>', False)<EOL>self._wakeup()<EOL>if args:<EOL><INDENT>cmd = "<STR_LIT>" % (cmd, '<STR_LIT:U+0020>'.join(str(a) for a in args))<EOL><DEDENT>for i in xrange(<NUM_LIT:3>):<EOL><INDENT>log.info("<STR_LIT>" + cmd)<EOL>self.port.write(cmd + '<STR_LIT:\n>')<EOL>if ok:<EOL><INDENT>ack = self.port.read(len(self.OK))  <EOL>log_raw('<STR_LIT>', ack)<EOL>if ack == self.OK:<EOL><INDENT>return<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ack = self.port.read(len(self.ACK))  <EOL>log_raw('<STR_LIT>', ack)<EOL>if ack == self.ACK:<EOL><INDENT>return<EOL><DEDENT><DEDENT><DEDENT>raise NoDeviceException('<STR_LIT>')<EOL>

write a single command, with variable number of arguments. after the
command, the device must return ACK


self._cmd('<STR_LIT>', <NUM_LIT:1>)<EOL>raw = self.port.read(LoopStruct.size)  <EOL>log_raw('<STR_LIT>', raw)<EOL>return raw<EOL>

reads a raw string containing data read from the device
provided (in /dev/XXX) format. all reads are non-blocking.


records = []<EOL>tbuf = struct.pack('<STR_LIT>', *time_fields)<EOL>self._cmd('<STR_LIT>')<EOL>crc = VProCRC.get(tbuf)<EOL>crc = struct.pack('<STR_LIT>', crc)  <EOL>log_raw('<STR_LIT>', tbuf + crc)<EOL>self.port.write(tbuf + crc)  <EOL>ack = self.port.read(len(self.ACK))  <EOL>log_raw('<STR_LIT>', ack)<EOL>if ack != self.ACK: return  <EOL>raw = self.port.read(DmpStruct.size)<EOL>log_raw('<STR_LIT>', raw)<EOL>if not VProCRC.verify(raw):  <EOL><INDENT>log_raw('<STR_LIT>', self.ESC)<EOL>self.port.write(self.ESC)  <EOL>return<EOL><DEDENT>log_raw('<STR_LIT>', self.ACK)<EOL>self.port.write(self.ACK)  <EOL>dmp = DmpStruct.unpack(raw)<EOL>log.info('<STR_LIT>' %<EOL>(dmp['<STR_LIT>'], dmp['<STR_LIT>']))<EOL>for i in xrange(dmp['<STR_LIT>']):<EOL><INDENT>raw = self.port.read(DmpPageStruct.size)<EOL>log_raw('<STR_LIT>', raw)<EOL>if not VProCRC.verify(raw):  <EOL><INDENT>log_raw('<STR_LIT>', self.ESC)<EOL>self.port.write(self.ESC)  <EOL>return<EOL><DEDENT>log_raw('<STR_LIT>', self.ACK)<EOL>self.port.write(self.ACK)  <EOL>page = DmpPageStruct.unpack(raw)<EOL>offset = <NUM_LIT:0>  <EOL>if i == <NUM_LIT:0>:<EOL><INDENT>offset = dmp['<STR_LIT>'] * ArchiveAStruct.size<EOL><DEDENT>while offset < ArchiveAStruct.size * <NUM_LIT:5>:<EOL><INDENT>log.info('<STR_LIT>' %<EOL>(page['<STR_LIT>'], offset))<EOL>if self._use_rev_b_archive(page['<STR_LIT>'], offset):<EOL><INDENT>a = ArchiveBStruct.unpack_from(page['<STR_LIT>'], offset)<EOL><DEDENT>else:<EOL><INDENT>a = ArchiveAStruct.unpack_from(page['<STR_LIT>'], offset)<EOL><DEDENT>if a['<STR_LIT>'] != <NUM_LIT> and a['<STR_LIT>'] != <NUM_LIT>:<EOL><INDENT>records.append(a)<EOL><DEDENT>offset += ArchiveAStruct.size<EOL><DEDENT><DEDENT>log.info('<STR_LIT>')<EOL>return records<EOL>

issue a command to read the archive records after a known time stamp.


for i in xrange(<NUM_LIT:3>):<EOL><INDENT>records = self._dmpaft_cmd(self._archive_time)<EOL>if records is not None: break<EOL>time.sleep(<NUM_LIT:1>)<EOL><DEDENT>if records is None:<EOL><INDENT>raise NoDeviceException('<STR_LIT>')<EOL><DEDENT>new_rec = None<EOL>for r in records:<EOL><INDENT>new_time = (r['<STR_LIT>'], r['<STR_LIT>'])<EOL>if self._archive_time < new_time:<EOL><INDENT>self._archive_time = new_time<EOL>new_rec = r<EOL><DEDENT><DEDENT>return new_rec<EOL>

returns a dictionary of fields from the newest archive record in the
device. return None when no records are new.


<EOL>temp = fields['<STR_LIT>']<EOL>hum = fields['<STR_LIT>']<EOL>wind = fields['<STR_LIT>']<EOL>wind10min = fields['<STR_LIT>']<EOL>fields['<STR_LIT>'] = calc_heat_index(temp, hum)<EOL>fields['<STR_LIT>'] = calc_wind_chill(temp, wind, wind10min)<EOL>fields['<STR_LIT>'] = calc_dewpoint(temp, hum)<EOL>now = time.localtime()<EOL>fields['<STR_LIT>'] = time.strftime("<STR_LIT>", now)<EOL>fields['<STR_LIT>'] = now[<NUM_LIT:0>]<EOL>fields['<STR_LIT>'] = str(now[<NUM_LIT:1>]).zfill(<NUM_LIT:2>)<EOL>now = time.gmtime()<EOL>fields['<STR_LIT>'] = time.strftime("<STR_LIT>", now)<EOL>fields['<STR_LIT>'] = now[<NUM_LIT:0>]<EOL>fields['<STR_LIT>'] = str(now[<NUM_LIT:1>]).zfill(<NUM_LIT:2>)<EOL>

calculates the derived fields (those fields that are calculated)


fields = self._get_loop_fields()<EOL>fields['<STR_LIT>'] = self._get_new_archive_fields()<EOL>self._calc_derived_fields(fields)<EOL>self.fields = fields<EOL>

read and parse a set of data read from the console.  after the
data is parsed it is available in the fields variable.


return kts * <NUM_LIT><EOL>


return kts<EOL>

Knots (kt) to nautical miles/hour (nmph)


return ft * <NUM_LIT><EOL>


return km * <NUM_LIT><EOL>


return m * <NUM_LIT><EOL>


return mph * <NUM_LIT><EOL>


return mph<EOL>

Nautical miles/hour (nmph) to knots (kt)


return mph * <NUM_LIT><EOL>

Miles/hour (mph) to feet/minute (ft/min)


return mph * <NUM_LIT><EOL>

Miles/hour (mph) to kilometers/hour (kph)


return ft * <NUM_LIT><EOL>

Feet/minute (ft/min) to miles/hour (mph)


return km * <NUM_LIT><EOL>

Kilometers/hour (kph) to miles/hour (mph)


return atm * <NUM_LIT><EOL>

Atmospheres (atm) to inches of mercury @32F (inHg32)


return atm * <NUM_LIT><EOL>

Atmospheres (atm) to inches of mercury @60F (inHg60)


return atm * <NUM_LIT><EOL>


return atm * <NUM_LIT><EOL>

Atmospheres (atm) to pounds/square inch (lb/in**2)


return inches * <NUM_LIT><EOL>

Inches of mercury @32F (inHg32) to millibars (mb)


return inches * <NUM_LIT><EOL>


return inches * <NUM_LIT><EOL>

Inches of mercury @32F (inHg32) to pounds/square inch (lb/in**2)


return inches * <NUM_LIT><EOL>

Inches of mercury @60F (inHg60) to atmospheres (atm)


return inches * <NUM_LIT><EOL>

Inches of mercury @60F (inHg60) to millibars (mb)


return inches * <NUM_LIT><EOL>

Inches of mercury @60F (inHg60) to pounds/square inch (lb/in**2)


return mb * <NUM_LIT><EOL>


return mb<EOL>


return mb * <NUM_LIT><EOL>

Millibars (mb) to inches of mercury @32F (inHg60)


return mb * <NUM_LIT><EOL>

Millibars (mb) to inches of mercury @60F (inHg60)


return mb * <NUM_LIT:0.1><EOL>


return mb * <NUM_LIT><EOL>

Millibars (mb) to millimeters of mercury @32F (mmHg)


return mb * <NUM_LIT><EOL>

Millibars (mb) to millimeters of mercury @60F (mmHg)


return mb * <NUM_LIT:100><EOL>

Millibars (mb) to newtons/square meter (N/m**2)


return mb * <NUM_LIT:100><EOL>


return mb * <NUM_LIT><EOL>

Millibars (mb) to pounds/square foot (lb/ft**2)


return mb * <NUM_LIT><EOL>

Millibars (mb) to pounds/square inch (lb/in**2)


return mm32 * <NUM_LIT><EOL>

Millimeters of mercury @32F (mmHg) to millibars (mb)


return mm60 * <NUM_LIT><EOL>

Millimeters of mercury @60F (mmHg) to millibars (mb)


return nsqm * <NUM_LIT><EOL>

Newtons/square meter (N/m**2) to millibars (mb)


return pa * <NUM_LIT><EOL>


return hpa<EOL>


return hpa * <NUM_LIT:10><EOL>


return lbs * <NUM_LIT><EOL>

Pounds/square foot (lb/ft**2) to millibars (mb)


return lbs * <NUM_LIT><EOL>

Pounds/square inch (lb/in**2) to atmospheres (atm)


return lbs * <NUM_LIT><EOL>

Pounds/square inch (lb/in**2) to inches of mercury @32F (inHg32)


return lbs * <NUM_LIT><EOL>

Pounds/square inch (lb/in**2) to inches of mercury @60F (inHg60)


return lbs * <NUM_LIT><EOL>

Pounds/square inch (lb/in**2) to millibars (mb)


return (c * <NUM_LIT>) + <NUM_LIT><EOL>

Degrees Celsius (C) to degrees Fahrenheit (F)


return c + <NUM_LIT><EOL>

Degrees Celsius (C) to degrees Kelvin (K)


return (c * <NUM_LIT>) + <NUM_LIT><EOL>

Degrees Celsius (C) to degrees Rankine (R)


return (f - <NUM_LIT>) * <NUM_LIT><EOL>

Degrees Fahrenheit (F) to degrees Celsius (C)


return (f * <NUM_LIT>) + <NUM_LIT><EOL>

Degrees Fahrenheit (F) to degrees Kelvin (K)


return f + <NUM_LIT><EOL>

Degrees Fahrenheit (F) to degrees Rankine (R)


return k - <NUM_LIT><EOL>

Degrees Kelvin (K) to degrees Celsius (C)


return (k - <NUM_LIT>) * <NUM_LIT><EOL>

Degrees Kelvin (K) to degrees Fahrenheit (F)


return k * <NUM_LIT><EOL>

Degrees Kelvin (K) to degrees Rankine (R)


return (r - <NUM_LIT>) * <NUM_LIT><EOL>

Degrees Rankine (R) to degrees Celsius (C)


return r - <NUM_LIT><EOL>

Degrees Rankine (R) to degrees Fahrenheit (F)


return r * <NUM_LIT><EOL>

Degrees Rankine (R) to degrees Kelvin (K)


if (temp < <NUM_LIT>):<EOL><INDENT>return temp<EOL><DEDENT>else:<EOL><INDENT>return -<NUM_LIT> + <NUM_LIT> * temp + <NUM_LIT> * hum - <NUM_LIT> *temp * hum - <NUM_LIT> * (<NUM_LIT:10> ** -<NUM_LIT:3>) * (temp ** <NUM_LIT:2>) - <NUM_LIT> *(<NUM_LIT:10> ** -<NUM_LIT:2>) * (hum ** <NUM_LIT:2>) + <NUM_LIT> * (<NUM_LIT:10> ** -<NUM_LIT:3>) * (temp ** <NUM_LIT:2>) *hum + <NUM_LIT> * (<NUM_LIT:10> ** -<NUM_LIT:4>) * temp * (hum ** <NUM_LIT:2>) - <NUM_LIT> *(<NUM_LIT:10> ** -<NUM_LIT:6>) * (temp ** <NUM_LIT:2>) * (hum ** <NUM_LIT:2>);<EOL><DEDENT>

calculates the heat index based upon temperature (in F) and humidity.
http://www.srh.noaa.gov/bmx/tables/heat_index.html

returns the heat index in degrees F.


def calc_wind_chill(t, windspeed, windspeed10min=None):

w = max(windspeed10min, windspeed)<EOL>return <NUM_LIT> + <NUM_LIT> * t - <NUM_LIT> * (w ** <NUM_LIT>) + <NUM_LIT> * t * (w ** <NUM_LIT>)<EOL>

calculates the wind chill value based upon the temperature (F) and
wind.

returns the wind chill in degrees F.


t = fahrenheit_to_celsius(temp)<EOL>td = fahrenheit_to_celsius(dewpoint)<EOL>num = <NUM_LIT> - (<NUM_LIT:0.1> * t) + td<EOL>denom = <NUM_LIT> + (<NUM_LIT> * t)<EOL>rh = math.pow((num / denom), <NUM_LIT:8>)<EOL>return rh<EOL>

calculates the humidity via the formula from weatherwise.org
return the relative humidity


c = fahrenheit_to_celsius(temp)<EOL>x = <NUM_LIT:1> - <NUM_LIT> * hum;<EOL>dewpoint = (<NUM_LIT> + <NUM_LIT> * c) * x;<EOL>dewpoint = dewpoint + ((<NUM_LIT> + <NUM_LIT> * c) * x) ** <NUM_LIT:3>;<EOL>dewpoint = dewpoint + (<NUM_LIT> + <NUM_LIT> * c) * x ** <NUM_LIT>;<EOL>dewpoint = c - dewpoint;<EOL>return celsius_to_fahrenheit(dewpoint)<EOL>

calculates the dewpoint via the formula from weatherwise.org
return the dewpoint in degrees F.


def weather_update(station, pub_sites, interval):

station.parse()      <EOL>if station.fields['<STR_LIT>'] > <NUM_LIT:200>:<EOL><INDENT>raise NoSensorException(<EOL>'<STR_LIT>' %<EOL>(station.fields['<STR_LIT>'],))<EOL><DEDENT>gust, gust_dir = WindGust.get( station, interval )<EOL>for ps in pub_sites:<EOL><INDENT>try: <EOL><INDENT>ps.set(<EOL>pressure    = station.fields['<STR_LIT>'],<EOL>dewpoint    = station.fields['<STR_LIT>'],<EOL>humidity    = station.fields['<STR_LIT>'],<EOL>tempf       = station.fields['<STR_LIT>'],<EOL>rainin      = station.fields['<STR_LIT>'],<EOL>rainday     = station.fields['<STR_LIT>'],<EOL>dateutc     = station.fields['<STR_LIT>'],<EOL>windspeed   = station.fields['<STR_LIT>'],<EOL>winddir     = station.fields['<STR_LIT>'],<EOL>windgust    = gust,<EOL>windgustdir = gust_dir, )<EOL>ps.publish()<EOL><DEDENT>except (Exception) as e:<EOL><INDENT>log.warn('<STR_LIT>'%(ps.__class__.__name__,e))<EOL><DEDENT><DEDENT>

main execution loop. query weather data and post to online service.


from logging.handlers import SysLogHandler<EOL>fmt = logging.Formatter( os.path.basename(sys.argv[<NUM_LIT:0>]) +<EOL>"<STR_LIT>")<EOL>facility = SysLogHandler.LOG_DAEMON<EOL>syslog = SysLogHandler(address='<STR_LIT>',facility=facility)<EOL>syslog.setFormatter( fmt )<EOL>log.addHandler(syslog)<EOL>if not quiet:<EOL><INDENT>console = logging.StreamHandler()<EOL>console.setFormatter( fmt )<EOL>log.addHandler(console)<EOL>log.setLevel(logging.INFO)<EOL>if debug:<EOL><INDENT>log.setLevel(logging.DEBUG)<EOL><DEDENT><DEDENT>

setup system logging to desired verbosity.


sites = []<EOL>for p_key in vars(opts).keys():<EOL><INDENT>args = getattr(opts,p_key)<EOL>if p_key in PUB_SERVICES and args:<EOL><INDENT>if isinstance(args,tuple):<EOL><INDENT>ps = PUB_SERVICES[p_key](*args)<EOL><DEDENT>else:<EOL><INDENT>ps = PUB_SERVICES[p_key](args)<EOL><DEDENT>sites.append( ps )<EOL><DEDENT><DEDENT>return sites<EOL>

use values in opts data to generate instances of publication services.


<EOL>pub_g = optparse.OptionGroup( parser, "<STR_LIT>",<EOL>'''<STR_LIT>''', )<EOL>pub_g.add_option('<STR_LIT>', '<STR_LIT>', nargs=<NUM_LIT:2>, type='<STR_LIT:string>', dest='<STR_LIT>',<EOL>help='<STR_LIT>')<EOL>pub_g.add_option('<STR_LIT>', '<STR_LIT>', nargs=<NUM_LIT:2>, type='<STR_LIT:string>', dest='<STR_LIT>',<EOL>help='<STR_LIT>')<EOL>pub_g.add_option('<STR_LIT>', '<STR_LIT>', nargs=<NUM_LIT:1>, type='<STR_LIT:string>', dest='<STR_LIT:file>',<EOL>help='<STR_LIT>')<EOL>parser.add_option_group(pub_g)<EOL>parser.add_option('<STR_LIT>', '<STR_LIT>', dest='<STR_LIT>', action="<STR_LIT:store_true>",<EOL>default=False, help='<STR_LIT>')<EOL>parser.add_option('<STR_LIT>', '<STR_LIT>', dest='<STR_LIT>', action="<STR_LIT:store_true>",<EOL>default=False, help='<STR_LIT>')<EOL>parser.add_option('<STR_LIT>', '<STR_LIT>', dest='<STR_LIT>', default='<STR_LIT>',<EOL>help='<STR_LIT>')<EOL>parser.add_option('<STR_LIT>', '<STR_LIT>', dest='<STR_LIT>', default=<NUM_LIT>,<EOL>type='<STR_LIT:int>', help='<STR_LIT>')<EOL>return parser.parse_args()<EOL>

read command line options to configure program behavior.


rec = station.fields['<STR_LIT>']<EOL>if rec:<EOL><INDENT>threshold = station.fields['<STR_LIT>'] + GUST_MPH_MIN<EOL>if rec['<STR_LIT>'] >= threshold:<EOL><INDENT>self.value = (rec['<STR_LIT>'],rec['<STR_LIT>'])<EOL>self.count = GUST_TTL * <NUM_LIT> / interval<EOL><DEDENT>else:<EOL><INDENT>self.value = self.NO_VALUE<EOL><DEDENT><DEDENT>if self.count:<EOL><INDENT>self.count -= <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>self.value = self.NO_VALUE<EOL><DEDENT>log.debug('<STR_LIT>'.format(*self.value))<EOL>return self.value<EOL>

return gust data, if above threshold value and current time is inside
reporting window period


def compress(string, mode=MODE_GENERIC, quality=<NUM_LIT:11>, lgwin=<NUM_LIT>, lgblock=<NUM_LIT:0>):

compressor = Compressor(mode=mode, quality=quality, lgwin=lgwin,<EOL>lgblock=lgblock)<EOL>return compressor.process(string) + compressor.finish()<EOL>

Compress a byte string.

    Args:
      string (bytes): The input data.
      mode (int, optional): The compression mode can be MODE_GENERIC (default),
        MODE_TEXT (for UTF-8 format text input) or MODE_FONT (for WOFF 2.0).
      quality (int, optional): Controls the compression-speed vs compression-
        density tradeoff. The higher the quality, the slower the compression.
        Range is 0 to 11. Defaults to 11.
      lgwin (int, optional): Base 2 logarithm of the sliding window size. Range
        is 10 to 24. Defaults to 22.
      lgblock (int, optional): Base 2 logarithm of the maximum input block size.
        Range is 16 to 24. If set to 0, the value will be set based on the
        quality. Defaults to 0.

    Returns:
      The compressed byte string.

    Raises:
      brotli.error: If arguments are invalid, or compressor fails.


assert stream in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'], '<STR_LIT>'<EOL>stdio = getattr(sys, stream)<EOL>if sys.version_info[<NUM_LIT:0>] < <NUM_LIT:3>:<EOL><INDENT>if sys.platform == '<STR_LIT:win32>':<EOL><INDENT>runtime = platform.python_implementation()<EOL>if runtime == '<STR_LIT>':<EOL><INDENT>mode = '<STR_LIT:rb>' if stream == '<STR_LIT>' else '<STR_LIT:wb>'<EOL>stdio = os.fdopen(stdio.fileno(), mode, <NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>import msvcrt<EOL>msvcrt.setmode(stdio.fileno(), os.O_BINARY)<EOL><DEDENT><DEDENT>return stdio<EOL><DEDENT>else:<EOL><INDENT>if hasattr(stdio, '<STR_LIT>'):<EOL><INDENT>return stdio.buffer<EOL><DEDENT>else:<EOL><INDENT>orig_stdio = getattr(sys, '<STR_LIT>' % stream)<EOL>return orig_stdio.buffer<EOL><DEDENT><DEDENT>

Return the specified standard input, output or errors stream as a
    'raw' buffer object suitable for reading/writing binary data from/to it.


<EOL>if <NUM_LIT:32><c<<NUM_LIT>: return chr(c)<EOL>elif c==<NUM_LIT:10>: return '<STR_LIT>'<EOL>elif c==<NUM_LIT>: return '<STR_LIT>'<EOL>elif c==<NUM_LIT:32>: return '<STR_LIT>'<EOL>else: return '<STR_LIT>'.format(c)<EOL>


result = '<STR_LIT>'<EOL>def formatSubString(s):<EOL><INDENT>for c in s:<EOL><INDENT>if c==<NUM_LIT:32>: yield '<STR_LIT:U+0020>'<EOL>else: yield outputCharFormatter(c)<EOL><DEDENT><DEDENT>if len(result)<<NUM_LIT:200>: return '<STR_LIT>'.join(formatSubString(s))<EOL>else:<EOL><INDENT>return '<STR_LIT>'.join(formatSubString(s[:<NUM_LIT:100>]))+'<STR_LIT>'+'<STR_LIT>'.join(formatSubString(s[-<NUM_LIT:100>:]))<EOL><DEDENT>


return "<STR_LIT>".format(self.pos>><NUM_LIT:3>, self.pos&<NUM_LIT:7>)<EOL>

Representation
        >>> olleke
        BitStream(pos=0:0)


value = self.peek(n)<EOL>self.pos += n<EOL>if self.pos>len(self.data)*<NUM_LIT:8>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return value<EOL>

Read n bits from the stream and return as an integer.
        Produces zero bits beyond the stream.
        >>> olleke.data[0]==27
        True
        >>> olleke.read(5)
        27

        >>> olleke
        BitStream(pos=0:5)


<EOL>return int.from_bytes(<EOL>self.data[self.pos>><NUM_LIT:3>:self.pos+n+<NUM_LIT:7>>><NUM_LIT:3>],<EOL>'<STR_LIT>')>>(self.pos&<NUM_LIT:7>) & (<NUM_LIT:1><<n)-<NUM_LIT:1><EOL>

Peek an n bit integer from the stream without updating the pointer.
        It is not an error to read beyond the end of the stream.
        >>> olleke.data[:2]==b'\x1b\x2e' and 0x2e1b==11803
        True
        >>> olleke.peek(15)
        11803
        >>> hex(olleke.peek(32))
        '0x2e1b'


if self.pos&<NUM_LIT:7>: raise ValueError('<STR_LIT>')<EOL>result = self.data[self.pos>><NUM_LIT:3>:(self.pos>><NUM_LIT:3>)+n]<EOL>self.pos += <NUM_LIT:8>*n<EOL>return result<EOL>

Read n bytes from the stream on a byte boundary.


return self.code.length(self.index)<EOL>

Number of bits in the prefix notation of this symbol


return self.code.bitPattern(self.index)<EOL>


return self.code.extraBits(self.index)<EOL>

Number of extra bits to read for this symbol


return self.code.mnemonic(self.index)<EOL>

Short descriptor of the symbol without extra bits.


if isinstance(self.code, WithExtra):<EOL><INDENT>if not <NUM_LIT:0><=extra<<NUM_LIT:1><<self.extraBits():<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return self.code.value(self.index, extra)<EOL><DEDENT>if extra is not None:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return self.code.value(self.index)<EOL>

The value used for processing. Can be a tuple.
        with optional extra bits


if isinstance(self.code, WithExtra):<EOL><INDENT>return self.code.callback(self, extra)<EOL><DEDENT>return self.code.callback(self)<EOL>

Long explanation of the value from the numeric value
        with optional extra bits
        Used by Layout.verboseRead when printing the value


return map(partial(Symbol, self), range(len(self)))<EOL>


return self.maxLength<EOL>

Encoding length of given symbol.
        Does not depend on index in this case.


return self.maxLength, Symbol(self, data&(<NUM_LIT:1><<self.maxLength)-<NUM_LIT:1>)<EOL>

Find which symbol index matches the given data (from peek, as a number)
        and return the number of bits decoded.
        Can also be used to figure out length of a symbol.


return self.lengthTable[index]<EOL>


<EOL>lo, hi = self.minLength, self.maxLength<EOL>while lo<=hi:<EOL><INDENT>mid = lo+hi>><NUM_LIT:1><EOL>mask = (<NUM_LIT:1><<mid)-<NUM_LIT:1><EOL>try: index = self.decodeTable[data&mask]<EOL>except KeyError:<EOL><INDENT>hi = mid-<NUM_LIT:1><EOL>continue<EOL><DEDENT>symbolLength = self.lengthTable[index]<EOL>if symbolLength<=mid:<EOL><INDENT>return symbolLength, Symbol(self, index)<EOL><DEDENT>lo = mid+<NUM_LIT:1><EOL><DEDENT>return lo, Symbol(self, index)<EOL>


self.decodeTable = decodeTable<EOL>todo = set(decodeTable)<EOL>maskLength = <NUM_LIT:0><EOL>lengthTable = {}<EOL>while todo:<EOL><INDENT>mask = (<NUM_LIT:1><<maskLength)-<NUM_LIT:1><EOL>splitSymbols = defaultdict(list)<EOL>for s in todo: splitSymbols[s&mask].append(s)<EOL>for s,subset in splitSymbols.items():<EOL><INDENT>if len(subset)==<NUM_LIT:1>:<EOL><INDENT>lengthTable[self.decodeTable[s]] = maskLength<EOL>todo.remove(s)<EOL><DEDENT><DEDENT>maskLength +=<NUM_LIT:1><EOL><DEDENT>self.lengthTable = lengthTable<EOL>self.minLength = min(lengthTable.values())<EOL>self.maxLength = max(lengthTable.values())<EOL>self.switchToPrefix()<EOL>

Store decodeTable,
        and compute lengthTable, minLength, maxLength from encodings.


self.lengthTable = lengthTable<EOL>self.minLength = min(lengthTable.values())<EOL>self.maxLength = max(lengthTable.values())<EOL>nextCodes = []<EOL>code = <NUM_LIT:0><EOL>for bits in range(self.maxLength+<NUM_LIT:1>):<EOL><INDENT>code <<= <NUM_LIT:1><EOL>nextCodes.append(code)<EOL>code += sum(x==bits for x in lengthTable.values())<EOL><DEDENT>self.decodeTable = {}<EOL>for symbol in sorted(lengthTable):<EOL><INDENT>bits = lengthTable[symbol]<EOL>bitpattern = '<STR_LIT>'.format(nextCodes[bits], bits)<EOL>self.decodeTable[int(bitpattern[::-<NUM_LIT:1>], <NUM_LIT:2>)] = symbol<EOL>nextCodes[bits] += <NUM_LIT:1><EOL><DEDENT>self.switchToPrefix()<EOL>

Given the bit pattern lengths for symbols given in lengthTable,
        set decodeTable, minLength, maxLength


self.mode = PrefixDecoder<EOL>

This routine makes sure the prefix decoder is activated.


def __init__(self, name=None, *, callback=None, description='<STR_LIT>', **args):

<EOL>if name is not None: self.name = name<EOL>if callback is not None: self.callback = callback<EOL>self.description = description<EOL>if '<STR_LIT>' in args or '<STR_LIT>' in args:<EOL><INDENT>self.mode = RangeDecoder<EOL>RangeDecoder.__init__(self, **args)<EOL><DEDENT>elif '<STR_LIT>' in args:<EOL><INDENT>self.mode = PrefixDecoder<EOL>PrefixDecoder.__init__(self, **args)<EOL><DEDENT>else:<EOL><INDENT>super().__init__(**args)<EOL><DEDENT>

Don't forget to set either alphabetSize or decodeTable


if extra is not None:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return index<EOL>

Get value of symbol for computations.
        Override where needed.


return str(self.value(index))<EOL>

Give mnemonic of symbol.
        Override where needed.


value = self.value(index)<EOL>return '<STR_LIT>'.format(<EOL>self.description and self.description+'<STR_LIT>',<EOL>self.bitPattern(index),<EOL>value,<EOL>)<EOL>

Long explanation of the value from the numeric value
        This is a default routine.
        You can customize in three ways:
        - set description to add some text
        - override to get more control
        - set callback to make it dependent on you local variables


<EOL>symbolStrings = [<EOL>(self.bitPattern(s.index), self.mnemonic(s.index))<EOL>for s in self<EOL>]<EOL>leftColWidth, rightColWidth = map(max, map(<EOL>map,<EOL>repeat(len),<EOL>zip(*symbolStrings)<EOL>))<EOL>colwidth = leftColWidth+rightColWidth<EOL>columns = <NUM_LIT>//(colwidth+<NUM_LIT:2>)<EOL>rows = -(-len(symbolStrings)//columns)<EOL>def justify(bs):<EOL><INDENT>b,s = bs<EOL>return b.rjust(leftColWidth)+'<STR_LIT::>'+s.ljust(rightColWidth)<EOL><DEDENT>for i in range(rows):<EOL><INDENT>print('<STR_LIT:U+0020>'.join(map(justify, symbolStrings[i::rows])).rstrip())<EOL><DEDENT>

Show all words of the code in a nice format.


length, symbol = self.decodePeek(stream.peek(self.maxLength))<EOL>stream.pos += length<EOL>return length, symbol<EOL>

Read symbol from stream. Returns symbol, length.


return self.extraTable[index]<EOL>

Get the number of extra bits for this symbol.


return str(index)<EOL>

This value must be independent of extra.


length, symbol = self.decodePeek(stream.peek(self.maxLength))<EOL>stream.pos += length<EOL>extraBits = self.extraBits(symbol.index)<EOL>return length, symbol, extraBits, stream.read(extraBits)<EOL>

Read symbol and extrabits from stream.
        Returns symbol length, symbol, extraBits, extra
        >>> olleke.pos = 6
        >>> MetablockLengthAlphabet().readTupleAndExtra(olleke)
        (2, Symbol(MLEN, 4), 16, 46)


def explanation(self, index, extra=None):

extraBits = <NUM_LIT:0> if extra is None else self.extraBits(index)<EOL>if not hasattr(self, '<STR_LIT>'):<EOL><INDENT>formatString = '<STR_LIT>'<EOL>lo = hi = value = self.value(index, extra)<EOL><DEDENT>elif extraBits==<NUM_LIT:0>:<EOL><INDENT>formatString = '<STR_LIT>'<EOL>lo, hi = self.span(index)<EOL>value = lo<EOL><DEDENT>else:<EOL><INDENT>formatString = '<STR_LIT>'<EOL>lo, hi = self.span(index)<EOL>value = lo+extra<EOL><DEDENT>return formatString.format(<EOL>self.description and self.description+'<STR_LIT>',<EOL>'<STR_LIT:x>'*extraBits,<EOL>self.bitPattern(index),<EOL>lo, hi,<EOL>extra,<EOL>value,<EOL>)<EOL>

Expanded version of Code.explanation supporting extra bits.
        If you don't supply extra, it is not mentioned.


if index>=len(self.extraTable):<EOL><INDENT>raise ValueError("<STR_LIT>".format(<EOL>self.__class__.__name__, index))<EOL><DEDENT>return Symbol(self, index)<EOL>


lower, upper = self.span(index)<EOL>value = lower+(extra or <NUM_LIT:0>)<EOL>if value>upper:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return value<EOL>

Override if you don't define value0 and extraTable


lower = self.value0+sum(<NUM_LIT:1><<x for x in self.extraTable[:index])<EOL>upper = lower+(<NUM_LIT:1><<self.extraTable[index])<EOL>return lower, upper-<NUM_LIT:1><EOL>

Give the range of possible values in a tuple
        Useful for mnemonic and explanation


if index==<NUM_LIT:1>:<EOL><INDENT>if extra><NUM_LIT:3>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return '<STR_LIT>', extra+<NUM_LIT:1><EOL><DEDENT>if extra:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return '<STR_LIT>', index<EOL>

Returns ('Simple', #codewords) or ('Complex', HSKIP)


if extra><NUM_LIT:15>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return index, extra<<index<EOL>


index = index<EOL>if index==<NUM_LIT:0>: return <NUM_LIT:1>, <NUM_LIT:0><EOL>if index<=self.RLEMAX: return (<NUM_LIT:1><<index)+extra, <NUM_LIT:0><EOL>return <NUM_LIT:1>, index-self.RLEMAX<EOL>


<EOL>row = [<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:2>,<NUM_LIT:1>,<NUM_LIT:3>,<NUM_LIT:2>,<NUM_LIT:3>,<NUM_LIT:3>][index>><NUM_LIT:6>]<EOL>col = [<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:0>,<NUM_LIT:2>,<NUM_LIT:1>,<NUM_LIT:2>][index>><NUM_LIT:6>]<EOL>insertLengthCode = row<<<NUM_LIT:3> | index>><NUM_LIT:3>&<NUM_LIT:7><EOL>if row: insertLengthCode -= <NUM_LIT:8><EOL>copyLengthCode = col<<<NUM_LIT:3> | index&<NUM_LIT:7><EOL>return (<EOL>Symbol(self.insertLengthAlphabet, insertLengthCode),<EOL>Symbol(self.copyLengthAlphabet, copyLengthCode),<EOL>row==<NUM_LIT:0><EOL>)<EOL>

Give relevant values for computations:
        (insertSymbol, copySymbol, dist0flag)


i,c,d0 = self.splitSymbol(index)<EOL>iLower, _ = i.code.span(i.index)<EOL>iExtra = i.extraBits()<EOL>cLower, _ = c.code.span(c.index)<EOL>cExtra = c.extraBits()<EOL>return '<STR_LIT>'.format(<EOL>iLower,<EOL>'<STR_LIT:+>' if iExtra else '<STR_LIT>',<EOL>'<STR_LIT:x>'*iExtra if iExtra<<NUM_LIT:6> else '<STR_LIT>'.format(iExtra),<EOL>cLower,<EOL>'<STR_LIT:+>' if cExtra else '<STR_LIT>',<EOL>'<STR_LIT:x>'*cExtra if cExtra<<NUM_LIT:6> else '<STR_LIT>'.format(cExtra),<EOL>'<STR_LIT>' if d0 else '<STR_LIT>')<EOL>


if index<<NUM_LIT:16>+self.NDIRECT: return <NUM_LIT:0><EOL>return <NUM_LIT:1> + ((index - self.NDIRECT - <NUM_LIT:16>) >> (self.NPOSTFIX + <NUM_LIT:1>))<EOL>

Indicate how many extra bits are needed to interpret symbol
        >>> d = DistanceAlphabet('D', NPOSTFIX=2, NDIRECT=10)
        >>> [d[i].extraBits() for i in range(26)]
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        >>> [d[i].extraBits() for i in range(26,36)]
        [1, 1, 1, 1, 1, 1, 1, 1, 2, 2]


if dcode<<NUM_LIT:16>:<EOL><INDENT>return [(<NUM_LIT:1>,<NUM_LIT:0>),(<NUM_LIT:2>,<NUM_LIT:0>),(<NUM_LIT:3>,<NUM_LIT:0>),(<NUM_LIT:4>,<NUM_LIT:0>),<EOL>(<NUM_LIT:1>,-<NUM_LIT:1>),(<NUM_LIT:1>,+<NUM_LIT:1>),(<NUM_LIT:1>,-<NUM_LIT:2>),(<NUM_LIT:1>,+<NUM_LIT:2>),(<NUM_LIT:1>,-<NUM_LIT:3>),(<NUM_LIT:1>,+<NUM_LIT:3>),<EOL>(<NUM_LIT:2>,-<NUM_LIT:1>),(<NUM_LIT:2>,+<NUM_LIT:1>),(<NUM_LIT:2>,-<NUM_LIT:2>),(<NUM_LIT:2>,+<NUM_LIT:2>),(<NUM_LIT:2>,-<NUM_LIT:3>),(<NUM_LIT:2>,+<NUM_LIT:3>)<EOL>][dcode]<EOL><DEDENT>if dcode<<NUM_LIT:16>+self.NDIRECT:<EOL><INDENT>return (<NUM_LIT:0>,dcode-<NUM_LIT:16>)<EOL><DEDENT>POSTFIX_MASK = (<NUM_LIT:1> << self.NPOSTFIX) - <NUM_LIT:1><EOL>ndistbits = <NUM_LIT:1> + ((dcode - self.NDIRECT - <NUM_LIT:16>) >> (self.NPOSTFIX + <NUM_LIT:1>))<EOL>hcode = (dcode - self.NDIRECT - <NUM_LIT:16>) >> self.NPOSTFIX<EOL>lcode = (dcode - self.NDIRECT - <NUM_LIT:16>) & POSTFIX_MASK<EOL>offset = ((<NUM_LIT:2> + (hcode & <NUM_LIT:1>)) << ndistbits) - <NUM_LIT:4><EOL>distance = ((offset + dextra) << self.NPOSTFIX) + lcode + self.NDIRECT + <NUM_LIT:1><EOL>return (<NUM_LIT:0>,distance)<EOL>

Decode value of symbol together with the extra bits.
        >>> d = DistanceAlphabet('D', NPOSTFIX=2, NDIRECT=10)
        >>> d[34].value(2)
        (0, 35)


def mnemonic(self, index, verbose=False):

if index<<NUM_LIT:16>:<EOL><INDENT>return ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'<EOL>][index]<EOL><DEDENT>if index<<NUM_LIT:16>+self.NDIRECT:<EOL><INDENT>return str(index-<NUM_LIT:16>)<EOL><DEDENT>index -= self.NDIRECT+<NUM_LIT:16><EOL>hcode = index >> self.NPOSTFIX<EOL>lcode = index & (<NUM_LIT:1><<self.NPOSTFIX)-<NUM_LIT:1><EOL>if self.NPOSTFIX: formatString = '<STR_LIT>'<EOL>else: formatString = '<STR_LIT>'<EOL>return formatString.format(<EOL>hcode&<NUM_LIT:1>,<EOL>'<STR_LIT:x>'*(<NUM_LIT:2>+hcode>><NUM_LIT:1>) if hcode<<NUM_LIT> or verbose else '<STR_LIT>'.format(<NUM_LIT:2>+hcode>><NUM_LIT:1>),<EOL>lcode, self.NPOSTFIX,<EOL>self.NDIRECT+<NUM_LIT:1>-(<NUM_LIT:4><<self.NPOSTFIX))<EOL>

Give mnemonic representation of meaning.
        verbose compresses strings of x's


extraBits = self.extraBits(index)<EOL>extraString = '<STR_LIT>'.format(extra, extraBits)<EOL>return '<STR_LIT>'.format(<EOL>self.mnemonic(index, True).replace('<STR_LIT:x>'*(extraBits or <NUM_LIT:1>), extraString),<EOL>self.value(index, extra))<EOL>


self.mode = mode<EOL>


self.chars.append(index)<EOL>

Adjust the context for output char (as int).


<EOL>ndbits = self.NDBITS[size]<EOL>index = dist&(<NUM_LIT:1><<ndbits)-<NUM_LIT:1><EOL>action = dist>>ndbits<EOL>position = sum(n<<self.NDBITS[n] for n in range(<NUM_LIT:4>,size))+size*index<EOL>self.file.seek(position)<EOL>return self.doAction(self.file.read(size), action)<EOL>


import re<EOL>self.actionList = actions = [None]*<NUM_LIT><EOL>actions[<NUM_LIT>] = "<STR_LIT>"<EOL>actionLines = self.actionTable.splitlines()<EOL>colonPositions = [m.start()<EOL>for m in re.finditer('<STR_LIT::>',actionLines[<NUM_LIT:1>])<EOL>]+[<NUM_LIT:100>]<EOL>columns = [(colonPositions[i]-<NUM_LIT:3>,colonPositions[i+<NUM_LIT:1>]-<NUM_LIT:3>)<EOL>for i in range(len(colonPositions)-<NUM_LIT:1>)]<EOL>for line in self.actionTable.splitlines(keepends=False):<EOL><INDENT>for start,end in columns:<EOL><INDENT>action = line[start:end]<EOL>if not action or action.isspace(): continue<EOL>index, colon, action = action[:<NUM_LIT:3>], action[<NUM_LIT:3>], action[<NUM_LIT:4>:]<EOL>assert colon=='<STR_LIT::>'<EOL>action = action.rstrip()<EOL>action = action.replace('<STR_LIT:_>', '<STR_LIT:U+0020>')<EOL>wPos = action.index('<STR_LIT:w>')<EOL>action = re.sub(r"<STR_LIT>", r"<STR_LIT>", action)<EOL>action = re.sub(r"<STR_LIT>", r"<STR_LIT>", action)<EOL>action = action.replace("<STR_LIT>", "<STR_LIT>")<EOL>actions[int(index)] = action<EOL><DEDENT><DEDENT>

Build the action table from the text above


<EOL>U = self.upperCase1<EOL>return eval(self.actionList[action], locals())<EOL>


firstAddress = pos+<NUM_LIT:7>>><NUM_LIT:3><EOL>lastAddress = self.stream.pos+<NUM_LIT:7>>><NUM_LIT:3><EOL>return '<STR_LIT>'.join(map('<STR_LIT>'.format,<EOL>self.stream.data[firstAddress:lastAddress]))<EOL>

Produce hex dump of all data containing the bits
        from pos to stream.pos


def formatBitData(self, pos, width1, width2=<NUM_LIT:0>):

result = []<EOL>if width1==<NUM_LIT:0>: result = ['<STR_LIT>', '<STR_LIT:U+002C>']<EOL>for width in width1, width2:<EOL><INDENT>if width==<NUM_LIT:0>: continue<EOL>while width><NUM_LIT:0>:<EOL><INDENT>availableBits = <NUM_LIT:8>-(pos&<NUM_LIT:7>)<EOL>if width<availableBits:<EOL><INDENT>data = self.stream.data[pos>><NUM_LIT:3>] >> (pos&<NUM_LIT:7>) & (<NUM_LIT:1><<width)-<NUM_LIT:1><EOL>result.append('<STR_LIT>'.format(data, width))<EOL><DEDENT>elif availableBits<<NUM_LIT:8>:<EOL><INDENT>data = self.stream.data[pos>><NUM_LIT:3>] >> (pos&<NUM_LIT:7>)<EOL>result.append('<STR_LIT>'.format(data, availableBits))<EOL><DEDENT>else:<EOL><INDENT>data = self.stream.data[pos>><NUM_LIT:3>]<EOL>result.append('<STR_LIT>'.format(data))<EOL><DEDENT>width -= availableBits<EOL>pos += availableBits<EOL><DEDENT>pos += width<EOL>result.append('<STR_LIT:U+002C>')<EOL><DEDENT>return '<STR_LIT>'.join(result[-<NUM_LIT:2>::-<NUM_LIT:1>])<EOL>

Show formatted bit data:
        Bytes are separated by commas
        whole bytes are displayed in hex
        >>> Layout(olleke).formatBitData(6, 2, 16)
        '|00h|2Eh,|00'
        >>> Layout(olleke).formatBitData(4, 1, 0)
        '1'


mode, numberOfSymbols = self.verboseRead(PrefixCodeHeader(alphabet.name))<EOL>if mode=='<STR_LIT>':<EOL><INDENT>self.readComplexCode(numberOfSymbols, alphabet)<EOL>return alphabet<EOL><DEDENT>else:<EOL><INDENT>table = []<EOL>lengths = [[<NUM_LIT:0>], [<NUM_LIT:1>,<NUM_LIT:1>], [<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:2>], '<STR_LIT>'][numberOfSymbols-<NUM_LIT:1>]<EOL>def myMnemonic(index):<EOL><INDENT>return '<STR_LIT>'.format(<EOL>lengths[i],<EOL>'<STR_LIT>' if lengths[i]==<NUM_LIT:1> else '<STR_LIT:s>',<EOL>alphabet.__class__.mnemonic(alphabet, index)<EOL>)<EOL><DEDENT>alphabet.mnemonic = myMnemonic<EOL>for i in range(numberOfSymbols):<EOL><INDENT>table.append(self.verboseRead(alphabet, skipExtra=True).index)<EOL><DEDENT>del alphabet.mnemonic<EOL>if numberOfSymbols==<NUM_LIT:4>:<EOL><INDENT>lengths = self.verboseRead(TreeShapeAlhabet())<EOL><DEDENT>alphabet.setLength(dict(zip(table, lengths)))<EOL><DEDENT>return alphabet<EOL>

give alphabet the prefix code that is read from the stream
        Called for the following alphabets, in this order:
        The alphabet in question must have a "logical" order,
        otherwise the assignment of symbols doesn't work.