private void OnWrappedAdDownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            var wc = sender as WebClient;

            wc.DownloadStringCompleted -= OnWrappedAdDownloadCompleted;

            var args       = (Tuple <IAdSource, VASTAD, Action <VASTAD>, Action <VASTAD, Exception> >)e.UserState;
            var source     = args.Item1;
            var ad         = args.Item2;
            var OnComplete = args.Item3;
            var OnError    = args.Item4;

            if (e.Error == null)
            {
                Exception ex;
                VAST      vast;

                if (VAST.Deserialize(e.Result, out vast, out ex) && vast != null)
                {
                    var wrapperAd = (VASTADWrapper)ad.Item;
                    var key       = GetAdSourceKey(wrapperAd.VASTAdTagURI, source.AltReference);
                    AvailableAds.Add(key, vast);

                    UnWrapAd(source, ad, OnComplete, OnError, vast);
                }
                if (ex != null)
                {
                    OnError(ad, new Exception("Failed to deserialize VAST doc.", ex));
                }
            }
            else
            {
                OnError(ad, new Exception("Unknown error downloading wrapped VAST doc", e.Error));
            }
        }
 /// <summary>
 /// Deserializes workflow markup into an VAST object
 /// </summary>
 /// <param name="xml">string workflow markup to deserialize</param>
 /// <param name="obj">Output VAST object</param>
 /// <param name="exception">output Exception value if deserialize failed</param>
 /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
 public static bool Deserialize(string xml, out VAST obj, out System.Exception exception)
 {
     exception = null;
     obj = default(VAST);
     try
     {
         obj = Deserialize(xml);
         return true;
     }
     catch (System.Exception ex)
     {
         exception = ex;
         return false;
     }
 }
 /// <summary>
 /// Deserializes workflow markup into an VAST object
 /// </summary>
 /// <param name="xml">string workflow markup to deserialize</param>
 /// <param name="obj">Output VAST object</param>
 /// <param name="exception">output Exception value if deserialize failed</param>
 /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
 public static bool Deserialize(string xml, out VAST obj, out System.Exception exception)
 {
     exception = null;
     obj       = default(VAST);
     try
     {
         obj = Deserialize(xml);
         return(true);
     }
     catch (System.Exception ex)
     {
         exception = ex;
         return(false);
     }
 }
        private void OnSourceDownloadCompleted(DownloadStringCompletedEventArgs e, VastAdUnit ad, Action <bool> Completed)
        {
#if LATENCYTEST
            var latencySimulatorTimer = new DispatcherTimer();
            latencySimulatorTimer.Interval = TimeSpan.FromSeconds(3);
            latencySimulatorTimer.Start();
            latencySimulatorTimer.Tick += (ts, te) => {
#endif
            if (e.Error == null)
            {
                Exception ex;
                VAST      vast;

                if (VAST.Deserialize(e.Result, out vast, out ex) && vast != null)
                {
                    var key = GetAdSourceKey(ad.Source);
                    if (!AvailableAds.ContainsKey(key))
                    {
                        AvailableAds.Add(key, vast);
                    }
                    ad.Vast = vast;

                    if (Completed != null)
                    {
                        Completed(true);
                    }
                }
                if (ex != null)
                {
                    if (Completed != null)
                    {
                        Completed(false);
                    }
                }
            }
            else
            {
                //Log.Output(OutputType.Error, "Unknown error handling VAST doc from source url: " + t.Source.uri);
                if (Completed != null)
                {
                    Completed(false);
                }
            }
#if LATENCYTEST
            latencySimulatorTimer.Stop();
        };
#endif
        }
        private void DownloadWrappedAd(IAdSource Source, VASTAD ad, Action <VASTAD> OnComplete, Action <VASTAD, Exception> OnError)
        {
            var wrapperAd = (VASTADWrapper)ad.Item;
            var url       = wrapperAd.VASTAdTagURI;

            //look to see if we have a source already
            var key = GetAdSourceKey(url, Source.AltReference);

            if (AvailableAds.ContainsKey(key))
            {
                VAST vast = AvailableAds[key];
                UnWrapAd(Source, ad, OnComplete, OnError, vast);
            }
            else
            {
                WebClient wc = new WebClient();
                wc.DownloadStringCompleted += OnWrappedAdDownloadCompleted;
                Uri uri = new Uri(url, UriKind.Absolute);
                wc.DownloadStringAsync(uri, new Tuple <IAdSource, VASTAD, Action <VASTAD>, Action <VASTAD, Exception> >(Source, ad, OnComplete, OnError));
            }
        }
        /// <summary>
        /// Populates an AdUnit with the VAST info, downloads the VAST doc if necessary
        /// </summary>
        /// <param name="ad">The VastAdUnit to be populated</param>
        /// <param name="Completed">Fired when the operation is complete, includes a status param</param>
        internal void LoadAdUnitAsync(VastAdUnit ad, Action <bool> Completed)
        {
            if (!string.IsNullOrEmpty(ad.Source.Uri))
            {
                var key = GetAdSourceKey(ad.Source);
                //look to see if we have a source already
                if (AvailableAds.ContainsKey(key))
                {
                    VAST vast = AvailableAds[key];
                    ad.Vast = vast;

                    if (Completed != null)
                    {
                        Completed(true);
                    }
                }
                else if (downloadingAds.ContainsKey(key))
                {
                    // piggy back on the currently downloading doc
                    var wc = downloadingAds[key];
                    wc.DownloadStringCompleted += (s, e) =>
                    {
                        OnSourceDownloadCompleted(e, ad, Completed);
                    };
                }
                else
                {
                    var wc = DownloadSource(ad, Completed);
                    downloadingAds.Add(key, wc);    // add the webclient to a dictionary
                }
            }
            else
            {
                if (Completed != null)
                {
                    Completed(false);
                }
            }
        }
 public static bool Deserialize(string xml, out VAST obj)
 {
     System.Exception exception = null;
     return Deserialize(xml, out obj, out exception);
 }
 private void UnWrapAd(IAdSource Source, VASTAD ad, Action<VASTAD> OnComplete, Action<VASTAD, Exception> OnError, VAST vast)
 {
     // there has to be a one to one relationship between wrapped ads and what their linear counterpart. However, a wrapped ad can point to an entire VAST doc which can contain many ads. Therefore, always just take the first one.
     var newAd = vast.Ad.FirstOrDefault(a => a.Item != null);
     if (newAd == null)
     {
         OnError(ad, new Exception("Wrapped ad was empty"));
     }
     else if (newAd.Item is VASTADWrapper)
     {
         DownloadWrappedAd(Source, newAd, OnComplete, OnError);
     }
     else
     {
         // plug the ad back into the parent
         OnComplete(newAd);
     }
 }
 public static bool Deserialize(string xml, out VAST obj)
 {
     System.Exception exception = null;
     return(Deserialize(xml, out obj, out exception));
 }
        private void UnWrapAd(IAdSource Source, VASTAD ad, Action <VASTAD> OnComplete, Action <VASTAD, Exception> OnError, VAST vast)
        {
            // there has to be a one to one relationship between wrapped ads and what their linear counterpart. However, a wrapped ad can point to an entire VAST doc which can contain many ads. Therefore, always just take the first one.
            var newAd = vast.Ad.FirstOrDefault(a => a.Item != null);

            if (newAd == null)
            {
                OnError(ad, new Exception("Wrapped ad was empty"));
            }
            else if (newAd.Item is VASTADWrapper)
            {
                DownloadWrappedAd(Source, newAd, OnComplete, OnError);
            }
            else
            {
                // plug the ad back into the parent
                OnComplete(newAd);
            }
        }