// Reads an array, decompressing it if required Array ReadArray(ReadPrimitive readPrimitive, Type arrayType) { var len = stream.ReadInt32(); var encoding = stream.ReadInt32(); var compressedLen = stream.ReadInt32(); var ret = Array.CreateInstance(arrayType, len); var s = stream; var endPos = stream.BaseStream.Position + compressedLen; if (encoding != 0) { if(errorLevel >= ErrorLevel.Checked) { if(encoding != 1) throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression encoding (must be 0 or 1)"); var cmf = stream.ReadByte(); if((cmf & 0xF) != 8 || (cmf >> 4) > 7) throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression format " + cmf); var flg = stream.ReadByte(); if(errorLevel >= ErrorLevel.Strict && ((cmf << 8) + flg) % 31 != 0) throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression FCHECK"); if((flg & (1 << 5)) != 0) throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression flags; dictionary not supported"); } else { stream.BaseStream.Position += 2; } var codec = new DeflateWithChecksum(stream.BaseStream, CompressionMode.Decompress); s = new BinaryReader(codec); } try { for (int i = 0; i < len; i++) ret.SetValue(readPrimitive(s), i); } catch (InvalidDataException) { throw new FbxException(stream.BaseStream.Position - 1, "Compressed data was malformed"); } if (encoding != 0) { if (errorLevel >= ErrorLevel.Checked) { stream.BaseStream.Position = endPos - sizeof(int); var checksumBytes = new byte[sizeof(int)]; stream.BaseStream.Read(checksumBytes, 0, checksumBytes.Length); int checksum = 0; for (int i = 0; i < checksumBytes.Length; i++) checksum = (checksum << 8) + checksumBytes[i]; if(checksum != ((DeflateWithChecksum)s.BaseStream).Checksum) throw new FbxException(stream.BaseStream.Position, "Compressed data has invalid checksum"); } else { stream.BaseStream.Position = endPos; } } return ret; }
// Reads an array, decompressing it if required public Array ReadArray(ReadPrimitive readPrimitive, Type arrayType) { var len = binStream.ReadInt32(); var encoding = binStream.ReadInt32(); var compressedLen = binStream.ReadInt32(); var ret = Array.CreateInstance(arrayType, len); var s = binStream; var endPos = binStream.BaseStream.Position + compressedLen; if (encoding != 0) { if (errorLevel >= ErrorLevel.Checked) { if (encoding != 1) { throw new FbxException(binStream.BaseStream.Position - 1, "Invalid compression encoding (must be 0 or 1)"); } var cmf = binStream.ReadByte(); if ((cmf & 0xF) != 8 || (cmf >> 4) > 7) { throw new FbxException(binStream.BaseStream.Position - 1, "Invalid compression format " + cmf); } var flg = binStream.ReadByte(); if (errorLevel >= ErrorLevel.Strict && ((cmf << 8) + flg) % 31 != 0) { throw new FbxException(binStream.BaseStream.Position - 1, "Invalid compression FCHECK"); } if ((flg & (1 << 5)) != 0) { throw new FbxException(binStream.BaseStream.Position - 1, "Invalid compression flags; dictionary not supported"); } } else { binStream.BaseStream.Position += 2; } var codec = new DeflateWithChecksum(binStream.BaseStream, CompressionMode.Decompress); s = new BinaryReader(codec); } try { for (int i = 0; i < len; i++) { ret.SetValue(readPrimitive(s), i); } } catch (FbxException) //InvalidDataException { throw new FbxException(binStream.BaseStream.Position - 1, "Compressed data was malformed"); } if (encoding != 0) { if (errorLevel >= ErrorLevel.Checked) { binStream.BaseStream.Position = endPos - sizeof(int); var checksumBytes = new byte[sizeof(int)]; binStream.BaseStream.Read(checksumBytes, 0, checksumBytes.Length); int checksum = 0; for (int i = 0; i < checksumBytes.Length; i++) { checksum = (checksum << 8) + checksumBytes[i]; } if (checksum != ((DeflateWithChecksum)s.BaseStream).Checksum) { throw new FbxException(binStream.BaseStream.Position, "Compressed data has invalid checksum"); } } else { binStream.BaseStream.Position = endPos; } } return(ret); }
// Reads an array, decompressing it if required T[] ReadArray <T>(ReadPrimitive readPrimitive) { var len = stream.ReadInt32(); var encoding = stream.ReadInt32(); var compressedLen = stream.ReadInt32(); var ret = new T[len]; var s = stream; var endPos = stream.BaseStream.Position + compressedLen; if (encoding == 0) { for (int i = 0; i < len; i++) { ret[i] = (T)readPrimitive(s); } return(ret); } if (errorLevel >= ErrorLevel.Checked) { if (encoding != 1) { throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression encoding (must be 0 or 1)"); } var cmf = stream.ReadByte(); if ((cmf & 0xF) != 8 || (cmf >> 4) > 7) { throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression format " + cmf); } var flg = stream.ReadByte(); if (errorLevel >= ErrorLevel.Strict && ((cmf << 8) + flg) % 31 != 0) { throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression FCHECK"); } if ((flg & (1 << 5)) != 0) { throw new FbxException(stream.BaseStream.Position - 1, "Invalid compression flags; dictionary not supported"); } } else { stream.BaseStream.Position += 2; } using (var codec = new DeflateStream(stream.BaseStream, CompressionMode.Decompress, true)) using (var bs = new ChecksumBinaryReader(codec)) { try { for (int i = 0; i < len; i++) { ret[i] = (T)readPrimitive(bs); } } catch (InvalidDataException) { throw new FbxException(stream.BaseStream.Position - 1, "Compressed data was malformed"); } if (errorLevel >= ErrorLevel.Checked) { stream.BaseStream.Position = endPos - sizeof(int); var checksumBytes = new byte[sizeof(int)]; stream.BaseStream.Read(checksumBytes, 0, checksumBytes.Length); uint checksum = 0; for (int i = 0; i < checksumBytes.Length; i++) { checksum = (checksum << 8) + checksumBytes[i]; } if (checksum != bs.Checksum) { throw new FbxException(stream.BaseStream.Position, "Compressed data has invalid checksum"); } } else { stream.BaseStream.Position = endPos; } } return(ret); }