private int ComputeContentLength()
    {
        int contentLength = 0;

        for (int i = 0; i < StartRangeBytes.Length; i++)
        {
            contentLength += Convert.ToInt32(EndRangeBytes[i] - StartRangeBytes[i]) + 1;

            if (IsMultipartRequest)
            {
                contentLength += MultipartBoundary.Length
                                 + ResourceMimeType.Length
                                 + StartRangeBytes[i].ToString().Length
                                 + EndRangeBytes[i].ToString().Length
                                 + ResourceLength.ToString().Length
                                 + 49;                                                                      // Length needed for multipart header
            }
        }

        if (IsMultipartRequest)
        {
            contentLength += MultipartBoundary.Length
                             + 8;                                                                               // Length of dash and line break
        }
        return(contentLength);
    }
    /// <summary>
    /// Send the requested resource to the HTTP response stream.
    /// </summary>
    private void ReturnChunkedResponse()
    {
        HttpResponse response = _context.Response;

        byte[] buffer = new byte[BufferSize];
        using (Stream fs = GetResourceStream())
        {
            for (int i = 0; i < StartRangeBytes.Length; i++)
            {
                // Position the stream at the starting byte
                fs.Seek(StartRangeBytes[i], SeekOrigin.Begin);

                long bytesToReadRemaining = EndRangeBytes[i] - StartRangeBytes[i] + 1;

                // Output multipart boundary, if needed
                if (IsMultipartRequest)
                {
                    response.Output.Write("--" + MultipartBoundary);
                    response.Output.Write(String.Format("{0}: {1}", HttpHeaderContentType, ResourceMimeType));
                    response.Output.Write(String.Format("{0}: bytes {1}-{2}/{3}",
                                                        HttpHeaderContentRange,
                                                        StartRangeBytes[i].ToString(),
                                                        EndRangeBytes[i].ToString(),
                                                        ResourceLength.ToString()
                                                        )
                                          );
                    response.Output.WriteLine();
                }

                // Stream out the requested chunks for the current range request
                while (bytesToReadRemaining > 0)
                {
                    if (response.IsClientConnected)
                    {
                        int chunkSize = fs.Read(buffer, 0, BufferSize < bytesToReadRemaining ? BufferSize : Convert.ToInt32(bytesToReadRemaining));
                        response.OutputStream.Write(buffer, 0, chunkSize);

                        bytesToReadRemaining -= chunkSize;

                        response.Flush();

#if DEBUG
                        //Thread.Sleep(DebuggingSleepTime);
#endif
                    }
                    else
                    {
                        // Client disconnected - quit
                        return;
                    }
                }
            }
        }
    }
Ejemplo n.º 3
0
            /// <summary>
            /// 解析资源包资源列表。
            /// </summary>
            /// <param name="fileUri">版本资源列表文件路径。</param>
            /// <param name="bytes">要解析的数据。</param>
            /// <param name="errorMessage">错误信息。</param>
            private void ParsePackageList(string fileUri, byte[] bytes, string errorMessage)
            {
                if (bytes == null || bytes.Length <= 0)
                {
                    throw new GameFrameworkException(Utility.Text.Format("Package list '{0}' is invalid, error message is '{1}'.", fileUri, string.IsNullOrEmpty(errorMessage) ? "<Empty>" : errorMessage));
                }

                MemoryStream memoryStream = null;

                try
                {
                    memoryStream = new MemoryStream(bytes, false);
                    using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8))
                    {
                        memoryStream = null;
                        if (binaryReader.ReadChar() != PackageListHeader[0] || binaryReader.ReadChar() != PackageListHeader[1] || binaryReader.ReadChar() != PackageListHeader[2])
                        {
                            throw new GameFrameworkException("Package list header is invalid.");
                        }

                        byte listVersion = binaryReader.ReadByte();

                        if (listVersion == 0)
                        {
                            byte[] encryptBytes = binaryReader.ReadBytes(4);

                            m_ResourceManager.m_ApplicableGameVersion   = m_ResourceManager.GetEncryptedString(binaryReader, encryptBytes);
                            m_ResourceManager.m_InternalResourceVersion = binaryReader.ReadInt32();

                            int assetCount = binaryReader.ReadInt32();
                            m_ResourceManager.m_AssetInfos = new Dictionary <string, AssetInfo>(assetCount);
                            int resourceCount = binaryReader.ReadInt32();
                            m_ResourceManager.m_ResourceInfos = new Dictionary <ResourceName, ResourceInfo>(resourceCount, new ResourceNameComparer());
                            ResourceLength[] resourceLengths = new ResourceLength[resourceCount];

                            for (int i = 0; i < resourceCount; i++)
                            {
                                string       name         = m_ResourceManager.GetEncryptedString(binaryReader, encryptBytes);
                                string       variant      = m_ResourceManager.GetEncryptedString(binaryReader, encryptBytes);
                                ResourceName resourceName = new ResourceName(name, variant);

                                LoadType loadType = (LoadType)binaryReader.ReadByte();
                                int      length   = binaryReader.ReadInt32();
                                int      hashCode = binaryReader.ReadInt32();
                                Utility.Converter.GetBytes(hashCode, m_CachedHashBytes);
                                resourceLengths[i] = new ResourceLength(resourceName, length, length);

                                int assetNamesCount = binaryReader.ReadInt32();
                                for (int j = 0; j < assetNamesCount; j++)
                                {
                                    string assetName = m_ResourceManager.GetEncryptedString(binaryReader, m_CachedHashBytes);

                                    int      dependencyAssetNamesCount = binaryReader.ReadInt32();
                                    string[] dependencyAssetNames      = new string[dependencyAssetNamesCount];
                                    for (int k = 0; k < dependencyAssetNamesCount; k++)
                                    {
                                        dependencyAssetNames[k] = m_ResourceManager.GetEncryptedString(binaryReader, m_CachedHashBytes);
                                    }

                                    if (variant == null || variant == m_CurrentVariant)
                                    {
                                        m_ResourceManager.m_AssetInfos.Add(assetName, new AssetInfo(assetName, resourceName, dependencyAssetNames));
                                    }
                                }

                                if (variant == null || variant == m_CurrentVariant)
                                {
                                    ProcessResourceInfo(resourceName, loadType, length, hashCode);
                                }
                            }

                            Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength);

                            ResourceGroup defaultResourceGroup = m_ResourceManager.GetOrAddResourceGroup(string.Empty);
                            for (int i = 0; i < resourceCount; i++)
                            {
                                if (resourceLengths[i].ResourceName.Variant == null || resourceLengths[i].ResourceName.Variant == m_CurrentVariant)
                                {
                                    defaultResourceGroup.AddResource(resourceLengths[i].ResourceName, resourceLengths[i].Length, resourceLengths[i].ZipLength);
                                }
                            }

                            int resourceGroupCount = binaryReader.ReadInt32();
                            for (int i = 0; i < resourceGroupCount; i++)
                            {
                                string        resourceGroupName          = m_ResourceManager.GetEncryptedString(binaryReader, encryptBytes);
                                ResourceGroup resourceGroup              = m_ResourceManager.GetOrAddResourceGroup(resourceGroupName);
                                int           resourceGroupResourceCount = binaryReader.ReadInt32();
                                for (int j = 0; j < resourceGroupResourceCount; j++)
                                {
                                    ushort index = binaryReader.ReadUInt16();
                                    if (index >= resourceCount)
                                    {
                                        throw new GameFrameworkException(Utility.Text.Format("Package index '{0}' is invalid, resource count is '{1}'.", index.ToString(), resourceCount.ToString()));
                                    }

                                    if (resourceLengths[index].ResourceName.Variant == null || resourceLengths[index].ResourceName.Variant == m_CurrentVariant)
                                    {
                                        resourceGroup.AddResource(resourceLengths[index].ResourceName, resourceLengths[index].Length, resourceLengths[index].ZipLength);
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new GameFrameworkException("Package list version is invalid.");
                        }
                    }

                    ResourceInitComplete();
                }
                catch (Exception exception)
                {
                    if (exception is GameFrameworkException)
                    {
                        throw;
                    }

                    throw new GameFrameworkException(Utility.Text.Format("Parse package list exception '{0}'.", exception.Message), exception);
                }
                finally
                {
                    if (memoryStream != null)
                    {
                        memoryStream.Dispose();
                        memoryStream = null;
                    }
                }
            }