public RemoteFileMetadata AddFileFragmentData(Uri uri, uint index)
    {
        RemoteFileFragmentMetadata metadata = new RemoteFileFragmentMetadata(uri, index);

        m_FileData.Add(metadata);
        Sort();
        return(this);
    }
    private void BeginDownloadRequest(RemoteFileFragmentMetadata fragmentMetadata)
    {
        // Request
        HTTPRequest request =
            PreparePartialDownloadRequest(fragmentMetadata.uri.AbsoluteUri);

        fragmentMetadata.BeginDownload();
        SendDownloadRequest(request);
    }
    private void BeginHeadRequest(RemoteFileFragmentMetadata fragmentMetadata)
    {
        HTTPRequest headRequest = new HTTPRequest(fragmentMetadata.uri,
                                                  HTTPMethods.Head,
                                                  OnHeadRequestComplete);

        fragmentMetadata.BeginHeadRequest();
        DoHeadRequest(headRequest);
    }
    private void OnDownloadFinish(RemoteFileFragmentMetadata fragment)
    {
        Debug.Log("On request finish");

        OnDownloadComplete();

        if (AreDownloadsFinished())
        {
            //mDownloadComplete = true;
            OnAllDownloadsFinished();
        }
    }
    public RemoteFileFragmentMetadata GetFileFragmentDataFromUri(string absoluteUri)
    {
        for (int i = 0; i < GetFileFragments().Count; ++i)
        {
            RemoteFileFragmentMetadata fragment = GetFileFragments()[i];
            if (fragment.uri.AbsoluteUri == absoluteUri)
            {
                return(fragment);
            }
        }

        return(null);
    }
    public bool IsFinishedDownloading()
    {
        for (int i = 0; i < GetFileFragments().Count; ++i)
        {
            RemoteFileFragmentMetadata fragment = GetFileFragments()[i];
            if (!fragment.IsFinishedDownloading())
            {
                return(false);
            }
        }

        return(true);
    }
    public bool AreHeadRequestsCompleted()
    {
        for (int i = 0; i < GetFileFragments().Count; ++i)
        {
            RemoteFileFragmentMetadata fragment = GetFileFragments()[i];
            if (!(fragment.IsReadyForDownload() ||
                  fragment.IsDownloading() ||
                  fragment.IsFinishedDownloading()))
            {
                return(false);
            }
        }

        return(true);
    }
    private void OnDownloadProcessing(HTTPRequest request, HTTPResponse response)
    {
        Debug.Assert(response != null);
        Debug.Log("Processing request from " + request.Uri.AbsoluteUri);
        RemoteFileFragmentMetadata fragmentMetadata =
            m_RemoteFileMetadata.GetFileFragmentDataFromUri(request.Uri.AbsoluteUri);

        Debug.Log("Fragment index: " + fragmentMetadata.index);

        lock (fragmentMetadata) {
            if (!response.HasStreamedFragments())
            {
                return;
            }
            List <byte[]> fragmentBytesList = response.GetStreamedFragments();

            //if (lastDownloadedURI == request.Uri.AbsoluteUri) {
            //	Debug.LogWarning("Download callback called twice in a row -- ignoring the second one");
            //	return;
            //}
            if (fragmentBytesList == null)
            {
                return;
            }

            for (int i = 0; i < fragmentBytesList.Count; ++i)
            {
                byte[] fragmentBytes = fragmentBytesList[i];
                int    offset        =
                    m_RemoteFileMetadata.GetFileFragmentMemoryOffset(fragmentMetadata)
                    + (int)fragmentMetadata.GetDownloadedBytes();
                int length = fragmentBytes.Length;

                Debug.Log("Copying " + length + " bytes at offset " + offset);
                CopyDownloadedFragment(offset, length, ref fragmentBytes);
                fragmentMetadata.AddDownloadedBytes(length);
                Interlocked.Add(ref mDownloadedContentSize, length);
                Debug.Log("Downloaded content size: " + mDownloadedContentSize + " / " + mContentSize);
            }

            fragmentMetadata.ProcessGetResponse(response);
        }
        lastDownloadedURI = request.Uri.AbsoluteUri;         // for error checking
    }
    /// <summary>
    /// Get this fragment's offset in the buffer. Previous fragments must finish downloading though to make their
    /// content length known (in chunked encoding) though
    /// </summary>
    /// <param name="fragment"></param>
    /// <returns>The offset in memory to which this fragment should be copied to</returns>
    public int GetFileFragmentMemoryOffset(RemoteFileFragmentMetadata fragment)
    {
        int offset = 0;

        for (int i = 0; i < GetFileFragments().Count; i++)
        {
            RemoteFileFragmentMetadata currentFragment = GetFileFragments()[i];

            if (currentFragment != fragment)
            {
                offset += (int)currentFragment.GetSize();
            }
            else
            {
                break;
            }
        }

        return(offset);
    }
    private void OnHeadRequestComplete(HTTPRequest request, HTTPResponse response)
    {
        if (response == null)
        {
            OnHeadRequestError(request);
            return;
        }

        RemoteFileFragmentMetadata fragment =
            m_RemoteFileMetadata.GetFileFragmentDataFromUri(request.Uri.AbsoluteUri);

        fragment.ProcessHeadResponse(response);

        Debug.Log("Head request is complete. Status code: " + response.StatusCode);

        if (m_RemoteFileMetadata.AreHeadRequestsCompleted())
        {
            OnAllHeadRequestsComplete();
        }
    }
    public bool IsValid()
    {
        for (int i = 0; i < GetFileFragments().Count; i++)
        {
            RemoteFileFragmentMetadata fragment = GetFileFragments()[i];
            if (fragment == null)
            {
                Debug.LogWarning("FileFragmentData is NULL");
                return(false);
            }

            if (fragment.index != i)
            {
                Debug.LogWarning("FileFragmentData index is " + fragment.index +
                                 " but should be " + i);
                return(false);
            }
        }

        return(true);
    }
 public RemoteFileMetadata AddFileFragmentData(RemoteFileFragmentMetadata metadata)
 {
     m_FileData.Add(metadata);
     Sort();
     return(this);
 }