// 读取下一个tag的名字和类型,并不包含数据,以便接下来决策是一次读完还是分级读还是分批读 public NamedBinaryTag ReadNextHalf() { TagType type = ReadTagType(); NamedBinaryTag ret = NamedBinaryTag.Create(type); if (ret.Type == TagType.End) { ret.name = null; return(ret); } ret.name = ReadString(); return(ret); }
public void WriteTagValue(NamedBinaryTag tag) { switch (tag.Type) { case TagType.End: return; case TagType.Byte: WriteByte(tag.GetByte()); return; case TagType.Short: WriteShort(tag.GetShort()); return; case TagType.Int: WriteInt(tag.GetInt()); return; case TagType.Long: WriteLong(tag.GetLong()); return; case TagType.Float: WriteFloat(tag.GetFloat()); return; case TagType.Double: WriteDouble(tag.GetDouble()); return; case TagType.ByteArray: WriteByteArray(tag.GetByteArray()); return; case TagType.String: WriteString(tag.GetString()); return; case TagType.List: WriteList(tag.GetList(), tag.GetItemType()); return; case TagType.Compound: WriteCompound(tag.GetCompound()); return; case TagType.IntArray: WriteIntArray(tag.GetIntArray()); return; case TagType.LongArray: WriteLongArray(tag.GetLongArray()); return; case TagType.None: throw new Exception("tag type is None"); default: throw new Exception("unknown tag type:" + (int)tag.Type); } }
public void WriteTag(NamedBinaryTag tag) { WriteHalf(tag.Type, tag.name); WriteTagValue(tag); }
public NamedBinaryTag FinishReadValue(NamedBinaryTag tag) { int readLen; switch (tag.Type) { case TagType.End: return(tag); case TagType.Byte: tag.SetByte(ReadByte()); return(tag); case TagType.Short: tag.SetShort(ReadShort()); return(tag); case TagType.Int: tag.SetInt(ReadInt()); return(tag); case TagType.Long: tag.SetLong(ReadLong()); return(tag); case TagType.Float: tag.SetFloat(ReadFloat()); return(tag); case TagType.Double: tag.SetDouble(ReadDouble()); return(tag); case TagType.ByteArray: readLen = ReadInt(); byte[] byteArray = new byte[readLen]; readLen = _stream.Read(byteArray, 0, byteArray.Length); if (readLen < byteArray.Length) { throw new Exception("unexpected stream end"); } tag.SetByteArray(byteArray); return(tag); case TagType.String: tag.SetString(ReadString()); return(tag); case TagType.List: NamedBinaryTag tagItem; TagType itemType = ReadTagType(); readLen = ReadInt(); List <NamedBinaryTag> list = new List <NamedBinaryTag>(readLen); for (int i = 0; i < readLen; i++) { tagItem = NamedBinaryTag.Create(itemType); FinishReadValue(tagItem); list.Add(tagItem); } tag.SetList(list); return(tag); case TagType.Compound: Dictionary <string, NamedBinaryTag> compound = new Dictionary <string, NamedBinaryTag>(); while ((tagItem = ReadNextHalf()).Type != TagType.End) { FinishReadValue(tagItem); compound.Add(tagItem.name, tagItem); } tag.SetCompound(compound); return(tag); case TagType.IntArray: readLen = ReadInt(); int[] intArray = new int[readLen]; for (int i = 0; i < readLen; i++) { intArray[i] = ReadInt(); } tag.SetIntArray(intArray); return(tag); case TagType.LongArray: readLen = ReadInt(); long[] longArray = new long[readLen]; for (int i = 0; i < readLen; i++) { longArray[i] = ReadLong(); } tag.SetLongArray(longArray); return(tag); case TagType.None: throw new Exception("tag type is None"); default: throw new Exception("unknown tag type:" + (int)tag.Type); } }
//跳过tag的后一半 public NamedBinaryTag SkipValue(NamedBinaryTag tag) { if (tag.Type == TagType.None) { return(tag); } int valueLen = tagValueLengths[(int)tag.Type]; int readLen; if (valueLen >= 0) { _stream.Seek(valueLen, SeekOrigin.Current); return(tag); } TagType type; switch (tag.Type) { case TagType.ByteArray: readLen = ReadInt(); _stream.Seek(readLen, SeekOrigin.Current); return(tag); case TagType.String: readLen = ReadShort(); _stream.Seek(readLen, SeekOrigin.Current); return(tag); case TagType.List: type = ReadTagType(); NamedBinaryTag skipTag = NamedBinaryTag.Create(type); int count = ReadInt(); for (int i = 0; i < count; i++) { SkipValue(skipTag); } return(tag); case TagType.Compound: while ((type = ReadTagType()) != TagType.End) { skipTag = NamedBinaryTag.Create(type); readLen = ReadShort(); _stream.Seek(readLen, SeekOrigin.Current); SkipValue(skipTag); } return(tag); case TagType.IntArray: readLen = ReadInt(); _stream.Seek(readLen * 4, SeekOrigin.Current); return(tag); case TagType.LongArray: readLen = ReadInt(); _stream.Seek(readLen * 8, SeekOrigin.Current); return(tag); default: throw new Exception("unknown tag type:" + (int)tag.Type); } }