Пример #1
0
        public static IDictionary <int, List <AbstractStruct> > ReadClientStructRefs(IUpdateDecoder decoder, YDoc doc)
        {
            var clientRefs = new Dictionary <int, List <AbstractStruct> >();

            var numOfStateUpdates = decoder.Reader.ReadVarUint();

            for (int i = 0; i < numOfStateUpdates; i++)
            {
                var numberOfStructs = (int)decoder.Reader.ReadVarUint();
                Debug.Assert(numberOfStructs >= 0);

                var refs   = new List <AbstractStruct>(numberOfStructs);
                var client = decoder.ReadClient();
                var clock  = (int)decoder.Reader.ReadVarUint();

                clientRefs[client] = refs;

                for (int j = 0; j < numberOfStructs; j++)
                {
                    var info = decoder.ReadInfo();
                    if ((Bits.Bits5 & info) != 0)
                    {
                        // The item that was originally to the left of this item.
                        var leftOrigin = (info & Bit.Bit8) == Bit.Bit8 ? (ID?)decoder.ReadLeftId() : null;
                        // The item that was originally to the right of this item.
                        var rightOrigin        = (info & Bit.Bit7) == Bit.Bit7 ? (ID?)decoder.ReadRightId() : null;
                        var cantCopyParentInfo = (info & (Bit.Bit7 | Bit.Bit8)) == 0;
                        var hasParentYKey      = cantCopyParentInfo ? decoder.ReadParentInfo() : false;

                        // If parent == null and neither left nor right are defined, then we know that 'parent' is child of 'y'
                        // and we read the next string as parentYKey.
                        // It indicates how we store/retrieve parent from 'y.share'.
                        var parentYKey = cantCopyParentInfo && hasParentYKey?decoder.ReadString() : null;

                        var str = new Item(
                            new ID(client, clock),
                            null,                                                                                                                                   // left
                            leftOrigin,
                            null,                                                                                                                                   // right
                            rightOrigin,                                                                                                                            // rightOrigin
                            cantCopyParentInfo && !hasParentYKey ? decoder.ReadLeftId() : (parentYKey != null ? (object)doc.Get <AbstractType>(parentYKey) : null), // parent
                            cantCopyParentInfo && (info & Bit.Bit6) == Bit.Bit6 ? decoder.ReadString() : null,                                                      // parentSub
                            ReadItemContent(decoder, info)                                                                                                          // content
                            );

                        refs.Add(str);
                        clock += str.Length;
                    }
                    else
                    {
                        var length = decoder.ReadLength();
                        refs.Add(new GC(new ID(client, clock), length));
                        clock += length;
                    }
                }
            }

            return(clientRefs);
        }
Пример #2
0
        public static AbsolutePosition TryCreateFromAbsolutePosition(RelativePosition rpos, YDoc doc)
        {
            var          store   = doc.Store;
            var          rightId = rpos.Item;
            var          typeId  = rpos.TypeId;
            var          tName   = rpos.TName;
            int          index   = 0;
            AbstractType type;

            if (rightId != null)
            {
                if (store.GetState(rightId.Value.Client) <= rightId.Value.Clock)
                {
                    return(null);
                }

                var res   = store.FollowRedone(rightId.Value);
                var right = res.item as Item;
                if (right == null)
                {
                    return(null);
                }

                type = right.Parent as AbstractType;
                Debug.Assert(type != null);

                if (type._item == null || !type._item.Deleted)
                {
                    index = right.Deleted || !right.Countable ? 0 : res.diff;
                    var n = right.Left as Item;
                    while (n != null)
                    {
                        if (!n.Deleted && n.Countable)
                        {
                            index += n.Length;
                        }

                        n = n.Left as Item;
                    }
                }
            }
            else
            {
                if (tName != null)
                {
                    type = doc.Get <AbstractType>(tName);
                }
                else if (typeId != null)
                {
                    if (store.GetState(typeId.Value.Client) <= typeId.Value.Clock)
                    {
                        // Type does not exist yet.
                        return(null);
                    }

                    var item = store.FollowRedone(typeId.Value).item as Item;
                    if (item != null && item.Content is ContentType)
                    {
                        type = (item.Content as ContentType).Type;
                    }
                    else
                    {
                        // Struct is garbage collected.
                        return(null);
                    }
                }
                else
                {
                    throw new Exception();
                }

                index = type.Length;
            }

            return(new AbsolutePosition(type, index));
        }