/// <summary> /// Internal version of ValidateFormData that takes a delegate. /// </summary> /// <param name="getFileDelegate">Delegate to get the file stream and name.</param> internal void ValidateFormData(GetFileDelegate getFileDelegate) { if (Context.View == SessionView.Execute) { // Ensure that there is an HttpPostedFile for every expected field name by calling // getFileDelegate for each expected field name, based on the interaction response option count. // getFileDelegate will throw InvalidFormDataException if asked for a file that isn't in // m_files. int responseOptionCount = (int)Interaction.ExtensionData[InteractionExtensionDataKeys.ResponseOptionCount]; for (int ordinal = 0; ordinal < responseOptionCount; ordinal++) { string ordinalString = ordinal.ToString(CultureInfo.InvariantCulture); string formFieldName = FileAssessmentRenderer.RenderFormFieldName(Interaction.Id, ordinalString); string filename; Stream stream; // Get the file stream and name getFileDelegate(formFieldName, out stream, out filename); } } }
/// <summary> /// Internal version of <c>ProcessFormData</c> for easier unit testing purposes. /// </summary> internal void ProcessFormData(NameValueCollection formData, GetFileDelegate getFileDelegate) { if (Context.View == SessionView.Execute) { ExecuteViewProcessFormData(formData, getFileDelegate); } else if (Context.View == SessionView.RandomAccess) { ProcessRandomAccessView(formData); } }
/// <summary> /// Internal version of <c>ProcessFormData</c> for execute view. /// </summary> internal void ExecuteViewProcessFormData(NameValueCollection formData, GetFileDelegate getFileDelegate) { int responseOptionCount = (int)Interaction.ExtensionData[InteractionExtensionDataKeys.ResponseOptionCount]; // For each form field name that corresponds to this interaction, store the attachment keys in the // LearnerResponse. // E.g. attachmentKey = ms.learningcomponents.fileAttachment.<ordinal> // If there is a file, // store it as ExtensionData[attachmentKey] = byte[] byte array of file // ExtensionData[attachmentKey + ".fileExtension"] = file extension of attached file // Else // set ExtensionData[attachmentKey] = (bool)false; // remove ExtensionData[attachmentKey + "fileExtension"] if it exists string hidDetach = formData["hidDetach"]; // form field name of the file to detach if (hidDetach == null) hidDetach = String.Empty; // makes string comparison easier StringBuilder bld = new StringBuilder(); // for learner response for (int ordinal = 0; ordinal < responseOptionCount; ordinal++) { string ordinalString = ordinal.ToString(CultureInfo.InvariantCulture); string formFieldName = FileAssessmentRenderer.RenderFormFieldName(Interaction.Id, ordinalString); string filename; // For each form field name that corresponds to this interaction, store the attachment keys in the // LearnerResponse. // E.g. attachmentKey = ms.learningcomponents.fileAttachment.<ordinal> AppendLearnerResponse(bld, InteractionExtensionDataKeys.FileAttachment(ordinalString)); // If the hidDetach field has a value that indicates one of the files should be detached, do that. // Note that the Detach button calls Submit, so there will only ever be one file to be detached at a time. if (0 == String.Compare(formData["hidDetach"], formFieldName, StringComparison.OrdinalIgnoreCase)) { // Remove any file extension and set file attachment to false. if (Interaction.ExtensionData.ContainsKey(InteractionExtensionDataKeys.FileExtension(ordinalString))) { Interaction.ExtensionData.Remove(InteractionExtensionDataKeys.FileExtension(ordinalString)); } if (Interaction.ExtensionData.ContainsKey(InteractionExtensionDataKeys.FileAttachment(ordinalString))) { Interaction.ExtensionData[InteractionExtensionDataKeys.FileAttachment(ordinalString)] = false; } else { Interaction.ExtensionData.Add(InteractionExtensionDataKeys.FileAttachment(ordinalString), false); } } else { // Get the file stream and name Stream stream; getFileDelegate(formFieldName, out stream, out filename); // If the filename is empty, or stream is null or its length is zero, no file was chosen for upload. // However, one may already be attached for this form field. if ((stream != null) && !String.IsNullOrEmpty(filename) && stream.Length != 0) { // Add the file data to the extension data. The file data is guaranteed to exist since it was validated // in the ValidateFormData method. // If a file attachment was previously stored, remove it. It will be replaced. if (Interaction.ExtensionData.ContainsKey(InteractionExtensionDataKeys.FileAttachment(ordinalString))) { Interaction.ExtensionData.Remove(InteractionExtensionDataKeys.FileAttachment(ordinalString)); } byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, (int)stream.Length); Interaction.ExtensionData.Add(InteractionExtensionDataKeys.FileAttachment(ordinalString), buffer); // Add or replace the file extension, which is the all-caps version of the letters after the last // "." in the file name. If no "." exists in the file name, the file extension is String.Empty. string fileExtension = Path.GetExtension(filename).ToUpperInvariant(); if (Interaction.ExtensionData.ContainsKey(InteractionExtensionDataKeys.FileExtension(ordinalString))) { Interaction.ExtensionData[InteractionExtensionDataKeys.FileExtension(ordinalString)] = fileExtension; } else { Interaction.ExtensionData.Add(InteractionExtensionDataKeys.FileExtension(ordinalString), fileExtension); } } else { // If there is not a form field value for this ordinal, create the attachment key if it doesn't // exist already, and set its value to (bool)false, but leave it alone if it already exists. if (!Interaction.ExtensionData.ContainsKey(InteractionExtensionDataKeys.FileAttachment(ordinalString))) { Interaction.ExtensionData.Add(InteractionExtensionDataKeys.FileAttachment(ordinalString), false); } } } } Interaction.LearnerResponse = bld.ToString(); }
/// <summary> /// Patches files into a rom, where file VROM mappings are identical /// </summary> /// <param name="OutputFilename"></param> /// <param name="hostRom"></param> /// <param name="UpdateFiles"></param> /// <param name="GetFile"></param> private static void PatchFiles_SameVrom_Compressed(Stream output, ORom hostRom, Dictionary <long, string> UpdateFiles, GetFileDelegate GetFile) { List <FileRecord> newDmaTable = new List <FileRecord>(); foreach (FileRecord record in hostRom.Files) { long physicalStart = output.Position; long vromFilesize; long romFilesize; Stream file; //if the file is being replaced with a custom file if (UpdateFiles.ContainsKey(record.VRom.Start)) { //get source file file = GetFile(UpdateFiles[record.VRom.Start]); //Get virtual file size if (record.IsCompressed) { Yaz.DecodeSize(file, out vromFilesize); } else { vromFilesize = Align.To16(file.Length); } //get the physical file size with padding romFilesize = Align.To16(file.Length); } else //copy a source rom file. { vromFilesize = record.VRom.Size; romFilesize = record.Data.Size; if (romFilesize > 0x800000) { throw new Exception("Internal file too large"); } file = hostRom.Files.GetPhysicalFile(record.VRom.Start); } //copy file file.CopyTo(output); file.Close(); //pad out output.PadToLength(physicalStart + romFilesize); //generate a new file table record newDmaTable.Add(new FileRecord( new FileAddress(record.VRom.Start, record.VRom.Start + vromFilesize), new FileAddress(physicalStart, (record.IsCompressed) ? physicalStart + romFilesize : 0))); } output.PadToLength(0x2000000); WriteFileTable(output, hostRom.Files.GetDmaDataStart(), newDmaTable); //write crc CRC.Write(output); }
public static void PatchFiles_SameVrom(Stream output, bool outputIsCompressed, ORom hostRom, Dictionary <long, string> updateFiles, GetFileDelegate getFile) { if (outputIsCompressed) { PatchFiles_SameVrom_Compressed(output, hostRom, updateFiles, getFile); } else { throw new NotImplementedException(); } }
public Backend(GetFileDelegate gfd) { _getFileDelegate = gfd; StartService(); }