public override CodeSourceCollection CreateSources(string aFileName) { SIImage image = SIImage.New(base.Tracer, aFileName); if (image == null) { throw new NotSupportedException("The specified image file is not supported"); } // We need to make a source and (single) collection for each content object within the image. // This enables relocation support when an image is actually used (i.e. read & decompress code // on demand, rather than up front). CodeSourceCollection sources = new CodeSourceCollection(); // foreach (SIContent content in image) { CodeCollection collection = CodeCollection.New(base.IdAllocator, aFileName, content.FileName); collection.IsRelocatable = content.IsRelocationSupported; // The URI must be unique string uri = string.Format("{0} [{1}]", aFileName, content.FileName); ImgSource source = new ImgSource(uri, this, collection, content); sources.Add(source); } // return(sources); }
public override void Add(DbgEntity aEntity) { CodeSourceProvider provider = null; // if (aEntity.FSEntity.IsFile) { if (aEntity.Exists && aEntity.FSEntity.IsValid) { provider = ProvisioningManager.GetProvider(aEntity.FSEntity.FullName); } // if (provider != null) { using (CodeSourceCollection sources = provider.CreateSources(aEntity.FullName)) { // Make sure the time to read attribute is setup in alignment with // whether the entity was explicitly added by the user or found implicitly // by scanning. if (aEntity.WasAddedExplicitly == false) { foreach (CodeSource source in sources) { // This means, don't read this source until it is actually // referenced by the client. I.e. until the client activates // a code segment that refers to this source.TimeToRead = CodeSource.TTimeToRead.EReadWhenNeeded; } } // Ownership is transferred iSources.AddRange(sources); sources.Clear(); } } else { throw new NotSupportedException("Specified file type is not supported"); } } else { throw new ArgumentException("SymbianCodeLib does not support directory entities"); } }
public override void Prime(TSynchronicity aSynchronicity) { CodePlugin plugin = this.Plugin; // Wipe any state ready for new priming attempt base.OnPrepareToPrime(); if (base.ResetEngineBeforePriming) { plugin.Clear(); } // Report the "priming started event" prior to adding the sources base.ReportEvent(TPrimeEvent.EEventPrimingStarted, null); // Any sources already registered with the source manager at the start of a new // priming request are assumed to already be complete. RecordAlreadyCompletedSources(); // Initially, whilst adding the sources to the source manager, we'll // operate synchronously. This prevents us from triggering the read // operation in the SourceAdded callback below. iSynchronicity = TSynchronicity.ESynchronous; // Listen to source manager events in case any new sources are // created whilst reading those we already know about. CodeSourceManager sourceManager = this.SourceManager; sourceManager.SourceAdded += new CodeSourceManager.SourceEventHandler(SourceManager_SourceAdded); sourceManager.SourceRemoved += new CodeSourceManager.SourceEventHandler(SourceManager_SourceRemoved); // Tell the source manager which sources we are reading. This also will // call our event handler (added above) so that we can observe source events. CodeSourceCollection sources = iSources; iSources = new CodeSourceCollection(); sourceManager.AddRange(sources); // If we're operating asynchronously, then the loop below will potentially // complete quite quickly. This means that any (new/additional) sources which // are created (asynchronously) whilst reading is underway will not themselves // be read. // // Therefore, we store the synchronisation mode as a data member, and when // 'SourceAdded' is called, if operating asynchronously, we'll also initiate // a read operation for the source (as soon as it is added). // // If we're operating synchronously, then this isn't important. Because we're // behaving synchronously, the loop below will only process one source at a // time (before waiting) and therefore even if that source adds new/additional // sources to the source manager, we'll catch them as soon as we move the // next iteration around the loop. iSynchronicity = aSynchronicity; // TODO: possibly re-write this so that it uses two separate code paths // for synchronous and asynchronous priming? By trying to use one path // this code looks rather complex and isn't terribly robust. try { // Now we can start the sources running. int count = iSourcesYetToBePrimed.Count; while (count > 0) { // Get the head source and remove it from the pending list CodeSource source = iSourcesYetToBePrimed[0]; iSourcesYetToBePrimed.Remove(source); // If the source wants to read it's data immediately, then activated // it right now... if (source.TimeToRead == CodeSource.TTimeToRead.EReadWhenPriming) { source.Read(aSynchronicity); } else { // This source will read it's data on it's own terms so skip // it to ensure that we can track when all the other sources // (that do actually read their files now..) are ready. Skip(source); } count = iSourcesYetToBePrimed.Count; } } catch (Exception e) { // If priming failed, report completion before rethrowing... OnPrimeComplete(); throw e; } }