Exemple #1
0
		// 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;
		}
Exemple #2
0
        // 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);
        }
Exemple #3
0
        // 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);
        }