/// <summary> /// Stream the field from a buffer /// </summary> /// <param name="input"></param> public override void Read(IO.EndianReader input) { if (StringType == StringType.Normal) { Value = input.ReadTagString(); } else if (StringType == StringType.Unicode) { Value = input.ReadUnicodeString(Length); } else if (StringType == StringType.Ascii) { Value = input.ReadAsciiString(Length); } else if (StringType == StringType.Halo1Profile) { Value = input.ReadUnicodeString(12); } else if (StringType == StringType.Halo2Profile) { Value = input.ReadUnicodeString(16); } else if (StringType == StringType.CString) { Value = input.ReadCString(); } }
/// <summary></summary> /// <param name="offsets">Buffer containing the offsets of the string values in <paramref name="buffer"/></param> /// <param name="buffer">Buffer containing the string values</param> /// <param name="is_packed">If true, reads the strings as null terminated strings, else as 128 character strings</param> /// <param name="count">Number of dynamic strings for <paramref name="set_index"/></param> /// <remarks> /// Doesn't use <paramref name="offsets"/> for reading the strings, assumes the strings are in sequential order in <paramref name="buffer"/>. /// /// Ignores <see cref="IsReadOnly"/>; will always add new IDs. /// </remarks> public void FromDebugStream(IO.EndianReader offsets, IO.EndianReader buffer, bool is_packed, int count) { if (count <= 0) { throw new ArgumentOutOfRangeException("count", count, "Must be greater than zero"); } // Assume the strings are in sequential order in [buffer] offsets.Seek(sizeof(uint) * count, System.IO.SeekOrigin.Current); int set_index = InitialId.Set, initial_index = InitialId.Index; InitializeSet(count); for (int x = 0; x < count; x++) { var str = is_packed ? buffer.ReadCString() : buffer.ReadAsciiString(128); var sid = mOwner.Definition.Description.Generate(initial_index + x, str.Length, set_index); m_set.Set.Add(sid, str); int hc = str.GetHashCode(); StringId first_sid; if (m_set.SetLookup.TryGetValue(hc, out first_sid)) { Debug.Warn.If(false, "Hash collision! '{0}' ({1}) collides with '{2}' ({3})", m_set.Set[first_sid], first_sid.ToString(), str, sid.ToString()); } else { m_set.SetLookup.Add(str.GetHashCode(), sid); } } }
protected override void ReadTagInstances(IO.EndianReader s, Blam.CacheFile cache) { // Read the tag index items items = new CacheItem[tagCount]; for (int x = 0; x < tagCount; x++) { (items[x] = new CacheItem()).Read(s); } // Read the tag filename strings foreach (CacheItem ci in items) { ci.ReferenceName = cache.References.AddOptimized(ci.GroupTag, s.ReadCString()); } }
public override void Read(IO.EndianReader s) { BlamVersion ver = (BlamVersion)s.ReadUInt16(); // HACK: this is a hack if (ver == BlamVersion.Halo1) { ver = BlamVersion.Halo1_CE; } Debug.Assert.If(ver == engine, "Engine version mismatch: expected {0}, but got {1}", engine, ver); s.Seek(2, System.IO.SeekOrigin.Current); #region FileNames int file_count = s.ReadInt32(); for (int x = 0; x < file_count; x++) { files.Add(s.ReadCString()); } #endregion }
static void FixupTagInstanceHeaderName(CacheFile cache, CacheItem instance, int name_offset, IO.EndianReader s) { s.Seek(name_offset); instance.TagNameOffset = s.PositionUnsigned; instance.ReferenceName = cache.References.AddOptimized(instance.GroupTag, s.ReadCString()); }