Mercurial > hg
changeset 35257:3340d46a5c3f
bookmark: add methods to binary encode and decode bookmark values
Coming new bundle2 parts related to bookmark will use a binary encoding. It
encodes a series of '(bookmark, node)' pairs. Bookmark name has a high enough
size limit to not be affected by issue5165. (64K length, we are well covered)
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Sun, 15 Oct 2017 14:59:55 +0200 |
parents | 8fbb2678d8e8 |
children | dbf868623daf |
files | mercurial/bookmarks.py |
diffstat | 1 files changed, 56 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/bookmarks.py Wed Dec 06 09:25:43 2017 -0500 +++ b/mercurial/bookmarks.py Sun Oct 15 14:59:55 2017 +0200 @@ -8,12 +8,14 @@ from __future__ import absolute_import import errno +import struct from .i18n import _ from .node import ( bin, hex, short, + wdirid, ) from . import ( encoding, @@ -550,6 +552,60 @@ binremotemarks[name] = bin(node) return binremotemarks +_binaryentry = struct.Struct('>20sH') + +def binaryencode(bookmarks): + """encode a '(bookmark, node)' iterable into a binary stream + + the binary format is: + + <node><bookmark-length><bookmark-name> + + :node: is a 20 bytes binary node, + :bookmark-length: an unsigned short, + :bookmark-name: the name of the bookmark (of length <bookmark-length>) + + wdirid (all bits set) will be used as a special value for "missing" + """ + binarydata = [] + for book, node in bookmarks: + if not node: # None or '' + node = wdirid + binarydata.append(_binaryentry.pack(node, len(book))) + binarydata.append(book) + return ''.join(binarydata) + +def binarydecode(stream): + """decode a binary stream into an '(bookmark, node)' iterable + + the binary format is: + + <node><bookmark-length><bookmark-name> + + :node: is a 20 bytes binary node, + :bookmark-length: an unsigned short, + :bookmark-name: the name of the bookmark (of length <bookmark-length>)) + + wdirid (all bits set) will be used as a special value for "missing" + """ + entrysize = _binaryentry.size + books = [] + while True: + entry = stream.read(entrysize) + if len(entry) < entrysize: + if entry: + raise error.Abort(_('bad bookmark stream')) + break + node, length = _binaryentry.unpack(entry) + bookmark = stream.read(length) + if len(bookmark) < length: + if entry: + raise error.Abort(_('bad bookmark stream')) + if node == wdirid: + node = None + books.append((bookmark, node)) + return books + def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()): ui.debug("checking for updated bookmarks\n") localmarks = repo._bookmarks