// This is the main routine you should call from your Freeze // callbacks to freeze an object public void ObjRef(object o) { int id; SerUnit altunit; if (Config.SerTrace) { Console.WriteLine("Saving {0} at {1}...", o, wpointer); } if (o == null) // null pointers are special { Byte((byte)SerializationCode.Null); return; } if (reg.CheckWriteObject(unit, o, out altunit, out id)) { if (altunit == unit) { Byte((byte)SerializationCode.SelfRef); } else { int altcode; if (!unit_to_offset.TryGetValue(altunit, out altcode)) { Byte((byte)SerializationCode.NewUnitRef); String(altunit.name); // save the hash too so stale refs can be caught foreach (byte b in altunit.hash) { Byte(b); } unit_to_offset[altunit] = usedunits++; } else { Byte((byte)SerializationCode.ForeignRef); Int(altcode); } } Int((int)id); } else { // must take responsibility for saving the tag IFreeze f = o as IFreeze; if (f != null) { f.Freeze(this); } else { FallbackFreeze(o); } } }
public SerUnit SaveUnit(string name, IFreeze root) { SerUnit su = new SerUnit(); su.name = name; su.root = root; if (units.ContainsKey(name)) { throw new InvalidOperationException("unit " + name + " exists"); } bool success = false; string file = Path.Combine(Backend.obj_dir, Backend.prefix + name.Replace("::", ".") + ".ser"); FreezeBuffer fb = new FreezeBuffer(this, su); units[name] = su; try { fb.String(signature); fb.Int(version); fb.ObjRef(root); byte[] data = fb.GetData(); su.hash = NewHash().ComputeHash(data); File.WriteAllBytes(file, data); success = true; } finally { if (!success) { UnloadUnit(name); } } return(su); }