public static FormatBadPointerExceptionMessage ( object sender, uint streamPos, uint pointer ) : string | ||
sender | object | |
streamPos | uint | |
pointer | uint | |
리턴 | string |
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); base.Construct(br, type); QbItemBase qib; QbItemType headerType; uint headerValue; for (int i = 0; i < base.ItemCount; i++) { if (base.StreamPos(br) != base.Pointers[i]) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), base.Pointers[i])); } headerValue = br.ReadUInt32(this.Root.PakFormat.EndianType); headerType = this.Root.PakFormat.GetQbItemType(headerValue); switch (headerType) { case QbItemType.StructHeader: qib = new QbItemStruct(this.Root); break; default: throw new ApplicationException(string.Format("Location 0x{0}: Not a struct header type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), headerValue.ToString("X").PadLeft(8, '0'))); } qib.Construct(br, headerType); AddItem(qib); } base.ConstructEnd(br); }
/// <summary> /// Call after derived class has read its data in Construct() /// </summary> /// <param name="br"></param> public virtual void ConstructEnd(BinaryEndianReader br) { #region switch switch (_qbFormat) { case QbFormat.SectionValue: //Simple section type: // ItemId, FileId, Value, Reserved _reserved = br.ReadUInt32(this.Root.PakFormat.EndianType); _length += (1 * 4); break; case QbFormat.StructItemPointer: if (_nextItemPointer != 0 && this.StreamPos(br) != _nextItemPointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _nextItemPointer)); } break; case QbFormat.StructItemValue: //Simple struct type: // ItemId, Value (4 byte), NextItemPointer _nextItemPointer = br.ReadUInt32(this.Root.PakFormat.EndianType); _length += (1 * 4); if (_nextItemPointer != 0 && this.StreamPos(br) != _nextItemPointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _nextItemPointer)); } break; case QbFormat.ArrayPointer: //Complex array type: // ItemCount, Pointer, Pointers - (if length is 1 then pointer points to first item and Pointers are abscent) for (int i = 0; i < _items.Count; i++) //_items.Count is 0 for strings (it checks it's own) { if (_pointers[i] != _items[i].Position) { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, _items[i].Position, _pointers[i])); } } break; default: break; } #endregion setChildMode(); //_itemCount = (uint)this.CalcItemCount(); }
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); base.Construct(br, type); QbItemBase qib; QbItemType floatsType; uint floatsValue; bool is3d; for (int i = 0; i < base.ItemCount; i++) { if (base.StreamPos(br) != base.Pointers[i]) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), base.Pointers[i])); } floatsValue = br.ReadUInt32(this.Root.PakFormat.EndianType); floatsType = this.Root.PakFormat.GetQbItemType(floatsValue); is3d = (type == QbItemType.SectionFloatsX3 || type == QbItemType.StructItemFloatsX3 || type == QbItemType.ArrayFloatsX3); switch (floatsType) { case QbItemType.Floats: qib = new QbItemFloats(this.Root, is3d); break; default: throw new ApplicationException(string.Format("Location 0x{0}: Not a float type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), floatsValue.ToString("X").PadLeft(8, '0'))); } qib.Construct(br, floatsType); AddItem(qib); base.ConstructEnd(br); } }
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); base.Construct(br, type); uint pointer; if (type != QbItemType.StructHeader) { _headerValue = br.ReadUInt32(base.Root.PakFormat.EndianType); } else { _headerValue = base.Root.PakFormat.GetQbItemValue(type, this.Root); } _headerType = base.Root.PakFormat.GetQbItemType(_headerValue); QbItemBase qib = null; QbItemType structType; uint structValue; if (_headerType == QbItemType.StructHeader) { pointer = br.ReadUInt32(base.Root.PakFormat.EndianType); //Should be the current stream position after reading _iniNextItemPointer = pointer; if (pointer != 0 && base.StreamPos(br) != pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), pointer)); } while (pointer != 0) { structValue = br.ReadUInt32(this.Root.PakFormat.EndianType); structType = this.Root.PakFormat.GetQbItemType(structValue); switch (structType) { case QbItemType.StructItemStruct: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemStruct(this.Root); break; case QbItemType.StructItemStringPointer: case QbItemType.StructItemInteger: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemInteger(this.Root); break; case QbItemType.StructItemQbKeyString: case QbItemType.StructItemQbKeyStringQs: case QbItemType.StructItemQbKey: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemQbKey(this.Root); break; case QbItemType.StructItemString: case QbItemType.StructItemStringW: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemString(this.Root); break; case QbItemType.StructItemFloat: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemFloat(this.Root); break; case QbItemType.StructItemFloatsX2: case QbItemType.StructItemFloatsX3: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.StructItemArray: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemArray(this.Root); break; //Convert array types to structitems to fit in with this parser (if QbFile.HasStructItems is false then internal type will be swapped back to array) case QbItemType.ArrayStruct: structType = QbItemType.StructItemStruct; qib = new QbItemArray(this.Root); break; case QbItemType.ArrayInteger: structType = QbItemType.StructItemInteger; qib = new QbItemInteger(this.Root); break; case QbItemType.ArrayQbKeyString: structType = QbItemType.StructItemQbKeyString; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayStringPointer: structType = QbItemType.StructItemStringPointer; qib = new QbItemInteger(this.Root); break; case QbItemType.ArrayQbKeyStringQs: structType = QbItemType.StructItemQbKeyStringQs; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayQbKey: structType = QbItemType.StructItemQbKey; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayString: structType = QbItemType.StructItemString; qib = new QbItemString(this.Root); break; case QbItemType.ArrayStringW: structType = QbItemType.StructItemStringW; qib = new QbItemString(this.Root); break; case QbItemType.ArrayFloat: structType = QbItemType.StructItemFloat; qib = new QbItemFloat(this.Root); break; case QbItemType.ArrayFloatsX2: structType = QbItemType.StructItemFloatsX2; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.ArrayFloatsX3: structType = QbItemType.StructItemFloatsX3; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.ArrayArray: structType = QbItemType.StructItemArray; qib = new QbItemArray(this.Root); break; default: qib = null; break; } if (qib != null) { if (this.Root.PakFormat.StructItemChildrenType == StructItemChildrenType.NotSet) //will have been set to structItem if qib is not null) { this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.ArrayItems; } qib.Construct(br, structType); AddItem(qib); pointer = qib.NextItemPointer; } else { throw new ApplicationException(string.Format("Location 0x{0}: Unknown item type 0x{1} in struct ", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), structValue.ToString("X").PadLeft(8, '0'))); } } } else { throw new ApplicationException(string.Format("Location 0x{0}: Struct without header type", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); } base.ConstructEnd(br); }
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); _isUnicode = ((type == QbItemType.SectionStringW || type == QbItemType.ArrayStringW || type == QbItemType.StructItemStringW) && (base.Root.PakFormat.PakFormatType == PakFormatType.PC || base.Root.PakFormat.PakFormatType == PakFormatType.XBox)); byte[] bytes; base.Construct(br, type); this.Strings = new string[base.ItemCount]; _charWidth = !_isUnicode ? 1 : 2; if (base.ItemCount != 0) { //use pointers to read quickly if (base.ItemCount > 1) { for (int i = 0; i < base.ItemCount - 1; i++) { if (base.StreamPos(br) != base.Pointers[i]) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), base.Pointers[i])); } bytes = br.ReadBytes((int)((base.Pointers[i + 1] - _charWidth) - base.StreamPos(br))); _strings[i] = bytesToString(bytes); //handles unicode if (!_isUnicode ? (br.ReadByte() != 0) : (br.ReadByte() != 0 || br.ReadByte() != 0)) { throw new ApplicationException(string.Format("Null byte expected reading string array at 0x{0}", (base.StreamPos(br) - _charWidth).ToString("X").PadLeft(8, '0'))); } } if (base.StreamPos(br) != base.Pointers[base.ItemCount - 1]) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), base.Pointers[base.ItemCount - 1])); } } //use the slow method read the last string StringBuilder sb = new StringBuilder(); //if we have come from an array we must align our position to %4 int byteAmount = (int)(4 - (base.StreamPos(br) % 4)); do { bytes = br.ReadBytes(byteAmount); sb.Append(bytesToString(bytes)); byteAmount = 4; }while (!_isUnicode ? (bytes[bytes.Length - 1] != '\0') : (bytes[bytes.Length - 1] != '\0' || bytes[bytes.Length - 2] != '\0')); //get text and remove any trailing null bytes _strings[base.ItemCount - 1] = sb.ToString().TrimEnd(new char[] { '\0' }); } base.ConstructEnd(br); }
/// <summary> /// Load type data from binary reader /// </summary> public virtual void Construct(BinaryEndianReader br, QbItemType type) { setQbFormat(type); _qbItemType = type; _qbItemValue = this.Root.PakFormat.GetQbItemValue(type, this.Root); _position = this.StreamPos(br) - (1 * 4); //subtract the already read header uint itemQbKeyCrc = 0; #region switch switch (_qbFormat) { case QbFormat.SectionPointer: //Complex section type: // ItemId, FileId, Pointer, Reserved _hasQbKey = true; itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType); _fileId = br.ReadUInt32(this.Root.PakFormat.EndianType); _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType); _reserved = br.ReadUInt32(this.Root.PakFormat.EndianType); _length = (5 * 4); if (type == QbItemType.SectionScript) { _itemCount = 0; } else { _itemCount = 1; } _pointers = new uint[1]; _pointers[0] = _pointer; if (this.StreamPos(br) != _pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer)); } break; case QbFormat.SectionValue: //Simple section type: // ItemId, FileId, Value, Reserved _hasQbKey = true; itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType); _fileId = br.ReadUInt32(this.Root.PakFormat.EndianType); _itemCount = 1; _length = (3 * 4); break; case QbFormat.StructItemPointer: //Complex struct type: // ItemId, Pointer, NextItemPointer _hasQbKey = true; itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType); _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType); _nextItemPointer = br.ReadUInt32(this.Root.PakFormat.EndianType); if (this.StreamPos(br) != _pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer)); } _itemCount = 1; _pointers = new uint[1]; _pointers[0] = _pointer; _length = (4 * 4); break; case QbFormat.StructItemValue: //Simple struct type: // ItemId, Value (4 byte), NextItemPointer _hasQbKey = true; itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType); //always null? if (_itemQbKey == 0 && _qbItemType == QbItemType.StructItemQbKeyString) { _itemQbKey = null; } _itemCount = 1; _length = (2 * 4); break; case QbFormat.ArrayPointer: //Complex array type: // ItemCount, Pointer, Pointers - (if length is 1 then pointer points to first item and Pointers are abscent) _hasQbKey = false; _itemCount = br.ReadUInt32(this.Root.PakFormat.EndianType); _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType); itemQbKeyCrc = 0; _length = (3 * 4); if (_pointer != 0 && this.StreamPos(br) != _pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer)); } _pointers = new uint[_itemCount]; if (_itemCount == 1) { _pointers[0] = _pointer; } else if (_itemCount > 1) { for (int i = 0; i < _itemCount; i++) { _pointers[i] = br.ReadUInt32(this.Root.PakFormat.EndianType); } _length += (_itemCount * 4); } break; case QbFormat.ArrayValue: //Simple array type: // ItemCount, Pointer, Pointers - (if length is 1 then pointer points to first item and Pointers are abscent) _hasQbKey = false; itemQbKeyCrc = 0; _itemCount = br.ReadUInt32(this.Root.PakFormat.EndianType); _length = (2 * 4); if (_itemCount > 1) { _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType); if (this.StreamPos(br) != _pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer)); } _length += (1 * 4); } break; case QbFormat.StructHeader: //when struct array item _hasQbKey = false; _length = (1 * 4); break; case QbFormat.Floats: _hasQbKey = false; _length = (1 * 4); break; case QbFormat.Unknown: _hasQbKey = false; _position += 4; //there is no header so re add the previously removed 4 _length = (0 * 4); break; default: break; } #endregion if (!_hasQbKey) { _itemQbKey = null; } else { string debugName = Root.LookupDebugName(itemQbKeyCrc); if (debugName.Length != 0) { _itemQbKey = QbKey.Create(itemQbKeyCrc, debugName); } else { _itemQbKey = QbKey.Create(itemQbKeyCrc); } } }