private bool TryGetDefaultValue(ArgumentModel arg, ParseArguments parseArgs, out object defaultValue) { defaultValue = arg.DefaultValue; if (defaultValue == null) { if (arg.Optional) { defaultValue = arg.Type.GetEmptyValue(); return(true); } return(false); } switch (defaultValue) { case string stringValue: parseArgs.Values = new[] { stringValue }; parseArgs.ValuesOffset = 0; defaultValue = ParseValue(arg, parseArgs, out var _); break; case string[] stringValues when stringValues.Length > 0: parseArgs.Values = stringValues; parseArgs.ValuesOffset = 0; defaultValue = ParseValue(arg, parseArgs, out var _); break; default: defaultValue = CastDefaultValue(arg, defaultValue); break; } return(true); }
protected virtual AbstractDataGrid FileToAbstractGrid(IFormFile file, ParseArguments args) { // Determine an appropriate file handler based on the file metadata FileHandlerBase handler; if (file.ContentType == "text/csv" || file.FileName.EndsWith(".csv")) { handler = new CsvHandler(_localizer); } else if (file.ContentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || file.FileName.EndsWith(".xlsx")) { handler = new ExcelHandler(_localizer); } else { throw new FormatException(_localizer["Error_UnknownFileFormat"]); } using (var fileStream = file.OpenReadStream()) { // Use the handler to unpack the file into an abstract grid and return it AbstractDataGrid abstractGrid = handler.ToAbstractGrid(fileStream); return(abstractGrid); } }
public void TestParseCloudOrganization() { Dictionary <string, string> args = new Dictionary <string, string>(); args.Add("-cloudOrganization", "D51E18A1-CA04-4E7C-A649-6FD2829E3223-danipen-unity"); Assert.AreEqual("danipen-unity", ParseArguments.CloudOrganization(args)); }
public void TestParseProjectPath() { Dictionary <string, string> args = new Dictionary <string, string>(); args.Add("-createProject", @"c:\tmp\newproj"); Assert.AreEqual(@"c:\tmp\newproj", ParseArguments.ProjectPath(args)); }
public void TestParseCloudProject() { Dictionary <string, string> args = new Dictionary <string, string>(); args.Add("-cloudProject", "fpsmicrogame"); Assert.AreEqual("fpsmicrogame", ParseArguments.CloudProject(args)); }
public object[] Parse( IReadOnlyList <ArgumentModel> argsModel, KeyValuePair <string, string>[] options, string[] operands, IServiceProvider services) { Validate(argsModel, options, operands, services); var values = new object[argsModel.Count]; var parseArgs = new ParseArguments { Services = services }; int operandsOffset = 0; for (int i = 0; i < argsModel.Count; i++) { var arg = argsModel[i]; try { switch (arg.Kind) { case ArgumentKind.Service: parseArgs.Values = null; parseArgs.ValuesOffset = 0; parseArgs.SingleValuePolicy = _options.OptionsSingleValuePolicy; values[i] = GetServiceOrDefault(arg, parseArgs); break; case ArgumentKind.Option: parseArgs.Values = GetOptionValues(options, arg); parseArgs.ValuesOffset = 0; parseArgs.SingleValuePolicy = _options.OptionsSingleValuePolicy; values[i] = ParseValueOrGetDefault(arg, parseArgs, out int _); break; case ArgumentKind.Operand: parseArgs.Values = operands; parseArgs.ValuesOffset = operandsOffset; parseArgs.SingleValuePolicy = SingleValuePolicy.UseFirstValue; values[i] = ParseValueOrGetDefault(arg, parseArgs, out int operandsUsed); operandsOffset += operandsUsed; break; default: throw new ArgumentParseException(arg, $"Unknown argument kind `{arg.Kind}`."); } } catch (Exception ex) when(NotParseException(ex)) { throw new ArgumentParseException(arg, ex.Message, ex); } } return(values); }
private object GetServiceOrDefault(ArgumentModel arg, ParseArguments parseArgs) { var service = parseArgs.Services.GetService(arg.Type); if (service != null) { return(service); } if (!TryGetDefaultValue(arg, parseArgs, out var value)) { throw new ArgumentParseException(arg, $"Service `{arg.Type.Name}` is not registered."); } return(value); }
static int Main(string[] args) { Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults(); try { var parser = new ParseArguments <Arguments>(); var a = parser.Parse(args, "s"); if (a == null) { Console.WriteLine("RoslynMacros use:"); Console.WriteLine("----------------"); foreach (var c in parser.ParseHelp()) { Console.WriteLine(c); } return(1); } var project = FindProject(); if (string.IsNullOrEmpty(project)) { throw new FileNotFoundException("Project file not found", ""); } Console.WriteLine($"Using project file: {project}."); var conf = new Configuration(a, new FileInfo(project)); ExecuteCmd(project, conf); Console.WriteLine("END."); return(0); } finally { if (Debugger.IsAttached) { Console.WriteLine("Press any key to continue . . ."); while (Console.KeyAvailable) { Console.ReadKey(); } Console.ReadKey(); } } }
private object ParseValueOrGetDefault(ArgumentModel arg, ParseArguments parseArgs, out int valuesUsed) { if (parseArgs.Values == null || parseArgs.ValuesOffset == parseArgs.Values.Length) { if (!TryGetDefaultValue(arg, parseArgs, out var value)) { // TODO: Or prompt value. // Use double Enter to end filling collection. throw new ArgumentParseException(arg, "Value is missing."); } valuesUsed = 0; return(value); } return(ParseValue(arg, parseArgs, out valuesUsed)); }
public void GenerateLCDText(ref StringBuilder displayLines, List <IMyThrust> allThrusters, string line) { ParseArguments arguments = new ParseArguments(line); List <DirectionalThrusters> thrusters = new List <DirectionalThrusters>(); if (!string.IsNullOrEmpty(arguments.Group)) { displayLines.Append($" {arguments.Group}:\n"); try { GridTerminalSystem.GetBlockGroupWithName(arguments.Group).GetBlocksOfType <IMyThrust>(allThrusters); } catch (Exception) { Echo($"No thrusters detected in {arguments.Group} group or the group doesn't exist."); return; } } FillDirectionThrusterList(ref thrusters, allThrusters, arguments); foreach (DirectionalThrusters directionalThruster in thrusters) { displayLines.Append($" {directionalThruster.Direction.ToString()} {ToSI(directionalThruster.CurrentThrust, "n0")}N/{ToSI(directionalThruster.MaxEffectiveThrust, "n0")}N\n"); displayLines.Append($" {directionalThruster.Percentage().ToString("n1")}%\n"); } }
private object ParseValue(ArgumentModel arg, ParseArguments parseArgs, out int valuesUsed) { IReadOnlyList <string> stringValues = null; if (parseArgs.ValuesOffset == 0) { stringValues = parseArgs.Values; } else { int valuesCount = parseArgs.Values.Length - parseArgs.ValuesOffset; stringValues = new ArraySegment <string>(parseArgs.Values, parseArgs.ValuesOffset, valuesCount); } var result = _multiValueParser.Parse( arg.Type, stringValues, parseArgs.SingleValuePolicy, arg.ValueParser, _options.FormatProvider); valuesUsed = result.ValuesUsed; return(result.Value); }
[HttpPost("parse"), RequestSizeLimit(5 * 1024 * 1024)] // 5MB public virtual async Task <ActionResult <List <TEntityForSave> > > Parse([FromQuery] ParseArguments args) { // This method doesn't import the file in the DB, it simply parses it to // Entities that are ripe for saving, and returns those Entities to the requester // This supports scenarios where only part of the required fields are present // in the imported file, or to support previewing the import before committing it try { var file = Request.Form.Files.FirstOrDefault(); var entities = await ParseImplAsync(args); return(Ok(entities)); } catch (UnprocessableEntityException ex) { return(UnprocessableEntity(ex.ModelState)); } catch (Exception ex) { _logger.LogError($"Error: {ex.Message} {ex.StackTrace}"); return(BadRequest(ex.Message)); } }
private void FillDirectionThrusterList(ref List <DirectionalThrusters> directionalThrusters, List <IMyThrust> thrusters, ParseArguments arguments) { // Build the list of directions to show. if (!arguments.directions.Any()) { directionalThrusters.Add(new DirectionalThrusters(Directions.Up)); directionalThrusters.Add(new DirectionalThrusters(Directions.Down)); directionalThrusters.Add(new DirectionalThrusters(Directions.Forward)); directionalThrusters.Add(new DirectionalThrusters(Directions.Backward)); directionalThrusters.Add(new DirectionalThrusters(Directions.Left)); directionalThrusters.Add(new DirectionalThrusters(Directions.Right)); } else { foreach (Directions direction in arguments.directions) { directionalThrusters.Add(new DirectionalThrusters(direction)); } } DirectionalThrusters.GetThrust(thrusters, ref directionalThrusters); }
protected override async Task <(List <AgentForSave>, Func <string, int?>)> ToDtosForSave(AbstractDataGrid grid, ParseArguments args) { // Get the properties of the DTO for Save, excluding Id or EntityState string mode = args.Mode; var readType = typeof(Agent); var custodySaveType = typeof(CustodyForSave); var agentSaveType = typeof(AgentForSave); var readProps = readType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .ToDictionary(prop => _metadataProvider.GetMetadataForProperty(readType, prop.Name)?.DisplayName ?? prop.Name, StringComparer.InvariantCultureIgnoreCase); var orgExemptProperties = new string[] { nameof(Agent.Title), nameof(Agent.Title2), nameof(Agent.Gender) }; var saveProps = custodySaveType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Union(agentSaveType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) .Where(e => ViewId() == INDIVIDUAL || orgExemptProperties.Contains(e.Name)) // Take away .ToDictionary(prop => _metadataProvider.GetMetadataForProperty(agentSaveType, prop.Name)?.DisplayName ?? prop.Name, StringComparer.InvariantCultureIgnoreCase); // Maps the index of the grid column to a property on the DtoForSave var saveColumnMap = new List <(int Index, PropertyInfo Property)>(grid.RowSize); // Make sure all column header labels are recognizable // and construct the save column map var firstRow = grid[0]; for (int c = 0; c < firstRow.Length; c++) { var column = firstRow[c]; string headerLabel = column.Content?.ToString(); // So any thing after an empty column is ignored if (string.IsNullOrWhiteSpace(headerLabel)) { break; } if (saveProps.ContainsKey(headerLabel)) { var prop = saveProps[headerLabel]; saveColumnMap.Add((c, prop)); } else if (readProps.ContainsKey(headerLabel)) { // All good, just ignore } else { AddRowError(1, _localizer["Error_Column0NotRecognizable", headerLabel]); } } // Milestone 1: columns in the abstract grid mapped if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Construct the result using the map generated earlier List <AgentForSave> result = new List <AgentForSave>(grid.Count - 1); for (int i = 1; i < grid.Count; i++) // Skip the header { var row = grid[i]; // Anything after an empty row is ignored if (saveColumnMap.All((p) => string.IsNullOrWhiteSpace(row[p.Index].Content?.ToString()))) { break; } var entity = new AgentForSave(); foreach (var(index, prop) in saveColumnMap) { var content = row[index].Content; var propName = _metadataProvider.GetMetadataForProperty(readType, prop.Name).DisplayName; // Special handling for choice lists if (content != null) { var choiceListAttr = prop.GetCustomAttribute <ChoiceListAttribute>(); if (choiceListAttr != null) { List <string> displayNames = choiceListAttr.DisplayNames.Select(e => _localizer[e].Value).ToList(); string stringContent = content.ToString(); var displayNameIndex = displayNames.IndexOf(stringContent); if (displayNameIndex == -1) { string seperator = _localizer[", "]; AddRowError(i + 1, _localizer["Error_Value0IsNotValidFor1AcceptableValuesAre2", stringContent, propName, string.Join(seperator, displayNames)]); } else { content = choiceListAttr.Choices[displayNameIndex]; } } } // Special handling for DateTime and DateTimeOffset if (prop.PropertyType.IsDateOrTime()) { try { var date = ParseImportedDateTime(content); content = date; if (prop.PropertyType.IsDateTimeOffset()) { content = AddUserTimeZone(date); } } catch (Exception) { AddRowError(i + 1, _localizer["Error_TheValue0IsNotValidFor1Field", content?.ToString(), propName]); } } // Try setting the value and return an error if it doesn't work try { prop.SetValue(entity, content); } catch (ArgumentException) { AddRowError(i + 1, _localizer["Error_TheValue0IsNotValidFor1Field", content?.ToString(), propName]); } } result.Add(entity); } // Milestone 2: DTOs created if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Prepare a dictionary of indices in order to construct any validation errors performantly // "IndexOf" is O(n), this brings it down to O(1) Dictionary <AgentForSave, int> indicesDic = result.ToIndexDictionary(); // For each entity, set the Id and EntityState depending on import mode if (mode == "Insert") { // For Insert mode, all are marked inserted and all Ids are null // Any duplicate codes will be handled later in the validation result.ForEach(e => e.Id = null); result.ForEach(e => e.EntityState = EntityStates.Inserted); } else { // For all other modes besides Insert, we need to match the entity codes to Ids by querying the DB // Load the code Ids from the database var nonNullCodes = result.Where(e => !string.IsNullOrWhiteSpace(e.Code)); var codesDataTable = DataTable(nonNullCodes.Select(e => new { e.Code })); var entitiesTvp = new SqlParameter("@Codes", codesDataTable) { TypeName = $"dbo.CodeList", SqlDbType = SqlDbType.Structured }; string agentType = ViewId(); var idCodesDic = await _db.CodeIds.FromSql( $@"SELECT c.Code, e.Id FROM @Codes c JOIN [dbo].[Custodies] e ON c.Code = e.Code WHERE e.CustodyType = 'Agent' && e.AgentType == {agentType};" , entitiesTvp).ToDictionaryAsync(e => e.Code, e => e.Id); result.ForEach(e => { if (!string.IsNullOrWhiteSpace(e.Code) && idCodesDic.ContainsKey(e.Code)) { e.Id = idCodesDic[e.Code]; } else { e.Id = null; } }); // Make sure no codes are mentioned twice, if we don't do it here, the save validation later will complain // about duplicated Id, but the error will not be clear since user deals with code while importing from Excel var duplicateIdGroups = result.Where(e => e.Id != null).GroupBy(e => e.Id.Value).Where(g => g.Count() > 1); foreach (var duplicateIdGroup in duplicateIdGroups) { foreach (var entity in duplicateIdGroup) { int index = indicesDic[entity]; AddRowError(index + 2, _localizer["Error_TheCode0IsDuplicated", entity.Code]); } } if (mode == "Merge") { // Merge simply inserts codes that are not found, and updates codes that are found result.ForEach(e => { if (e.Id != null) { e.EntityState = EntityStates.Updated; } else { e.EntityState = EntityStates.Inserted; } }); } else { // In the case of update: codes are required, and MUST match database Ids if (mode == "Update") { for (int index = 0; index < result.Count; index++) { var entity = result[index]; if (string.IsNullOrWhiteSpace(entity.Code)) { AddRowError(index + 2, _localizer["Error_CodeIsRequiredForImportModeUpdate"]); } else if (entity.Id == null) { AddRowError(index + 2, _localizer["Error_TheCode0DoesNotExist", entity.Code]); } } result.ForEach(e => e.EntityState = EntityStates.Updated); } else { throw new InvalidOperationException("Unknown save mode"); // Developer bug } } } // Milestone 3: Id and EntityState are set if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Function that maps any future validation errors back to specific rows int?errorKeyMap(string key) { int?rowNumber = null; if (key != null && key.StartsWith("[")) { var indexStr = key.TrimStart('[').Split(']')[0]; if (int.TryParse(indexStr, out int index)) { // Add 2: // 1 for the header in the abstract grid // 1 for the difference between index and number rowNumber = index + 2; } } return(rowNumber); } return(result, errorKeyMap); }
public void Run() { if (_disposed) { throw new ObjectDisposedException("Server has already been disposed of"); } while (true) { try { using (Connection conn = new Connection(_server.AcceptTcpClient())) { if (conn.RecvMessage() == MessageCode.Arguments) { // get arguments // method: send int of number of arguments // then send the arguments seperately int nargs = conn.RecvMessageInt(); string[] args = new string[nargs]; for (int i = 0; i < nargs; i++) { args[i] = conn.RecvMessageString(); } // setup redirect classes DText.DStdOut nOut = new DText.DStdOut(conn); DText.DStdIn nIn = new DText.DStdIn(conn); DText.DStdErr nErr = new DText.DStdErr(conn); // apply redirection nOut.EnableRedirect(); nIn.EnableRedirect(); nErr.EnableRedirect(); // event args for status code changing ParseEventArgs eargs = new ParseEventArgs(args); // raise parse arguments event to process data try { ParseArguments?.Invoke(this, eargs); } catch (Exception ex) { // an event handler threw, so tell the client // and exit conn.SendMessage(MessageCode.Error, ex.ToString()); throw ex; } finally { // cleanup redirection nOut.DisableRedirect(); nIn.DisableRedirect(); nErr.DisableRedirect(); } // tell the client that we're done and gives the // exit code conn.SendMessage(MessageCode.Finished, eargs.ExitStatus); } } } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { break; } throw ex; } } }
protected Task <(List <TEntityForSave>, Func <string, int?>)> ToEntitiesForSave(AbstractDataGrid _1, ParseArguments _2) { throw new NotImplementedException(); }
// Abstract and virtual members protected virtual async Task <(List <TEntityForSave>, Func <string, int?>)> ParseImplAsync(ParseArguments args) { var file = Request.Form.Files.FirstOrDefault(); if (file == null) { throw new BadRequestException(_localizer["Error_NoFileWasUploaded"]); } var abstractGrid = FileToAbstractGrid(file, args); if (abstractGrid.Count < 2) { ModelState.AddModelError("", _localizer["Error_EmptyImportFile"]); throw new UnprocessableEntityException(ModelState); } // Change the abstract grid to entities for save, and make sure no errors resulted that weren't thrown var(entitiesForSave, keyMap) = await ToEntitiesForSave(abstractGrid, args); if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } return(entitiesForSave, keyMap); }
public static void Parse(string source, ParseArguments args) { var i = 0; #region SkipWhiteSpaces Action SkipWhiteSpaces = delegate { if (i == source.Length) return; while (char.IsWhiteSpace(source, i)) { i++; // eof if (i == source.Length) break; } }; #endregion BooleanContinuation MoveNext = null; #region FoundString Continuation FoundString = a => { // lets remember how our string was qouted var q = source[i]; var w = new StringBuilder(); while (true) { i++; // now we need to parse a json string which should be in utf8 encoing and might be escaped var c = source[i]; if (c == q) { a.FoundString(w.ToString()); i++; return; } // are we entering escape mode? if (c == '\\') { throw new NotImplementedException(); } w.Append(c); } }; #endregion #region FoundArray Continuation FoundArray = a => { i++; // first element? while (MoveNext(a)) { SkipWhiteSpaces(); if (source[i] != ',') break; i++; } SkipWhiteSpaces(); // we have a state here... if (source[i] == ']') { i++; return; } throw new NotSupportedException(); }; #endregion MoveNext = a => { SkipWhiteSpaces(); if (source[i] == '\"') { FoundString(a); return true; } if (source[i] == '[') { a.FoundArray(FoundArray); return true; } return false; }; if (MoveNext(args)) { SkipWhiteSpaces(); // we should now be at the end! return; } throw new NotSupportedException(); }
public static void Parse(string source, ParseArguments args) { var i = 0; #region SkipWhiteSpaces Action SkipWhiteSpaces = delegate { if (i == source.Length) { return; } while (char.IsWhiteSpace(source, i)) { i++; // eof if (i == source.Length) { break; } } }; #endregion BooleanContinuation MoveNext = null; #region FoundString Continuation FoundString = a => { // lets remember how our string was qouted var q = source[i]; var w = new StringBuilder(); while (true) { i++; // now we need to parse a json string which should be in utf8 encoing and might be escaped var c = source[i]; if (c == q) { a.FoundString(w.ToString()); i++; return; } // are we entering escape mode? if (c == '\\') { throw new NotImplementedException(); } w.Append(c); } }; #endregion #region FoundArray Continuation FoundArray = a => { i++; // first element? while (MoveNext(a)) { SkipWhiteSpaces(); if (source[i] != ',') { break; } i++; } SkipWhiteSpaces(); // we have a state here... if (source[i] == ']') { i++; return; } throw new NotSupportedException(); }; #endregion MoveNext = a => { SkipWhiteSpaces(); if (source[i] == '\"') { FoundString(a); return(true); } if (source[i] == '[') { a.FoundArray(FoundArray); return(true); } return(false); }; if (MoveNext(args)) { SkipWhiteSpaces(); // we should now be at the end! return; } throw new NotSupportedException(); }
protected override Task <(List <ViewForSave>, Func <string, int?>)> ToDtosForSave(AbstractDataGrid grid, ParseArguments args) { throw new NotImplementedException(); }
protected abstract Task <(List <TDtoForSave>, Func <string, int?>)> ToDtosForSave(AbstractDataGrid grid, ParseArguments args);