public static CapsResOnDiskManifest Save(CapsResManifest inmem)
        {
            if (inmem == null)
            {
                return(null);
            }
            CapsResOnDiskManifest rv = ScriptableObject.CreateInstance <CapsResOnDiskManifest>();

            rv.MFlag  = inmem.MFlag;
            rv.DFlag  = inmem.DFlag;
            rv.InMain = inmem.InMain;

            Dictionary <CapsResManifestItem, int> itemlines = new Dictionary <CapsResManifestItem, int>();
            Dictionary <CapsResOnDiskManifestItem, CapsResManifestItem> unknownRefItem = new Dictionary <CapsResOnDiskManifestItem, CapsResManifestItem>();
            Dictionary <string, int> bundlelines = new Dictionary <string, int>();
            List <string>            bundles     = new List <string>();

            bundles.Add("");
            List <CapsResOnDiskManifestNode>  assets   = new List <CapsResOnDiskManifestNode>();
            Action <CapsResManifestNode, int> SaveNode = null;

            SaveNode = (node, lvl) =>
            {
                var linen = assets.Count;
                var asset = new CapsResOnDiskManifestNode();
                asset.Level = lvl;
                asset.PPath = node.PPath;
                assets.Add(asset);
                if (node.Item != null)
                {
                    itemlines[node.Item] = linen;
                    CapsResOnDiskManifestItem item = new CapsResOnDiskManifestItem();
                    asset.Item = item;
                    item.Type  = node.Item.Type;
                    if (node.Item.BRef != null)
                    {
                        var bref = node.Item.BRef;
                        int brefline;
                        if (!bundlelines.TryGetValue(bref, out brefline))
                        {
                            brefline          = bundles.Count;
                            bundlelines[bref] = brefline;
                            bundles.Add(bref);
                        }
                        item.BRef = brefline;
                    }
                    if (node.Item.Ref != null)
                    {
                        var aref = node.Item.Ref;
                        int arefline;
                        if (itemlines.TryGetValue(aref, out arefline))
                        {
                            item.Ref = arefline;
                        }
                        else
                        {
                            unknownRefItem[item] = aref;
                        }
                    }
                    if (node.Item.ExInfo != null)
                    {
                        item.ExInfo = UnityEngine.Object.Instantiate <ScriptableObject>(node.Item.ExInfo);
                    }
                }
                if (node.Children != null)
                {
                    var values = node.Children.Values;
                    for (int i = 0; i < values.Count; ++i)
                    {
                        SaveNode(values[i], lvl + 1);
                    }
                }
            };

            if (inmem.Root != null)
            {
                SaveNode(inmem.Root, 0);
            }

            foreach (var kvpu in unknownRefItem)
            {
                int aref;
                if (itemlines.TryGetValue(kvpu.Value, out aref))
                {
                    kvpu.Key.Ref = aref;
                }
            }

            if (bundles.Count > 1)
            {
                rv.Bundles = bundles.ToArray();
            }
            if (assets.Count > 0)
            {
                rv.Assets = assets.ToArray();
            }

            return(rv);
        }
        public static CapsResManifest Load(CapsResOnDiskManifest ondisk)
        {
            if (ondisk == null)
            {
                return(null);
            }
            CapsResManifest rv = new CapsResManifest();

            rv.MFlag  = ondisk.MFlag;
            rv.DFlag  = ondisk.DFlag;
            rv.InMain = ondisk.InMain;

            if (ondisk.Assets != null && ondisk.Assets.Length > 0)
            {
                List <CapsResManifestNode> nodeStack = new List <CapsResManifestNode>();
                var parsedNodes = new CapsResManifestNode[ondisk.Assets.Length];
                for (int i = 0; i < ondisk.Assets.Length; ++i)
                {
                    var curDiskNode = ondisk.Assets[i];
                    var curlvl      = curDiskNode.Level;
                    if (nodeStack.Count > curlvl)
                    {
                        var removecnt = nodeStack.Count - curlvl;
                        nodeStack.RemoveRange(nodeStack.Count - removecnt, removecnt);
                    }
                    while (nodeStack.Count < curlvl)
                    {
                        // something goes wrong here.
                        nodeStack.Add(null);
                    }

                    CapsResManifestNode curNode;
                    if (curlvl == 0)
                    {
                        curNode = new CapsResManifestNode(rv);
                        rv.Root = curNode;
                        //curNode.PPath = curDiskNode.PPath;
                    }
                    else
                    {
                        var parNode = nodeStack[curlvl - 1];
                        var ppath   = curDiskNode.PPath;
                        curNode = new CapsResManifestNode(parNode, ppath);
                        if (parNode.Children == null)
                        {
                            parNode.Children = new SortedList <string, CapsResManifestNode>();
                        }
                        parNode.Children[ppath] = curNode;
                    }
                    nodeStack.Add(curNode);
                    parsedNodes[i] = curNode;

                    if (curDiskNode.Item != null && curDiskNode.Item.Type != 0)
                    {
                        var item = new CapsResManifestItem(curNode);
                        curNode.Item = item;
                        item.Type    = curDiskNode.Item.Type;
                        if (curDiskNode.Item.BRef > 0)
                        {
                            if (ondisk.Bundles != null && ondisk.Bundles.Length > curDiskNode.Item.BRef)
                            {
                                item.BRef = ondisk.Bundles[curDiskNode.Item.BRef];
                            }
                        }
                        if (curDiskNode.Item.ExInfo != null)
                        {
                            item.ExInfo = UnityEngine.Object.Instantiate <ScriptableObject>(curDiskNode.Item.ExInfo);
                        }
                    }
                }
                for (int i = 0; i < ondisk.Assets.Length; ++i)
                {
                    var curDiskNode = ondisk.Assets[i];
                    if (curDiskNode.Item != null && curDiskNode.Item.Type != 0 && curDiskNode.Item.Ref > 0)
                    {
                        parsedNodes[i].Item.Ref = parsedNodes[curDiskNode.Item.Ref].Item;
                    }
                }
            }

            rv.TrimExcess();

            return(rv);
        }