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; } } } } }
/// <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; } } }