// Look for ".piece". private static bool FindPieceExtension(string path, ref int position, ref ScanStepDelegate nextStep, ref PieceNameInfo parseResults) { if (!FindString(path, ref position, ".piece")) { return(false); } nextStep = FindIsLast; return(true); }
// Retrieve part name. The position points to the slash past the part name. // So simply return the prefix up to that slash. private static bool FindPartName(string path, ref int position, ref ScanStepDelegate nextStep, ref PieceNameInfo parseResults) { parseResults.PrefixName = path.Substring(0, position); // Subtract the length of the part name from position. position = 0; if (parseResults.PrefixName.Length == 0) { return(false); } Uri partUri = new Uri(ZipPackage.GetOpcNameFromZipItemName(parseResults.PrefixName), UriKind.Relative); PackUriHelper.TryValidatePartUri(partUri, out parseResults.PartUri); return(true); }
// Look for "]" or "].last". private static bool FindIsLast(string path, ref int position, ref ScanStepDelegate nextStep, ref PieceNameInfo parseResults) { // Case of no ".last" member: if (path[position - 1] == ']') { parseResults.IsLastPiece = false; --position; nextStep = FindPieceNumber; return(true); } // There has to be "].last". if (!FindString(path, ref position, "].last")) { return(false); } parseResults.IsLastPiece = true; nextStep = FindPieceNumber; return(true); }
/// <summary> /// Attempts to parse a name as a piece name. Returns true and places the /// output in pieceNameConstituents. Otherwise, returns false and returns /// the default constituent values pieceName, 0, and false. /// </summary> /// <param name="path">The input string.</param> /// <param name="parseResults">An object containing the prefix name (i.e. generally the part name), the 0-based order number of the piece, and whether the piece is last in the part.</param> /// <returns>True for parse success.</returns> /// <remarks> /// Syntax of a piece name: /// piece_name = part_name "/" "[" 1*digit "]" [".last"] ".piece" /// </remarks> private static bool TryParseAsPieceName(string path, out PieceNameInfo parseResults) { parseResults = new PieceNameInfo(); // initialize to CLR default values // Start from the end and look for ".piece". int position = path.Length; ScanStepDelegate nextStep = new ScanStepDelegate(FindPieceExtension); // Scan backward until the whole path has been scanned. while (position > 0) { if (!nextStep.Invoke(path, ref position, ref nextStep, ref parseResults)) { // Scan step failed. Return false. parseResults.IsLastPiece = false; parseResults.PieceNumber = 0; parseResults.PrefixName = path; parseResults.PartUri = null; return(false); } } return(true); }
// Look for "/[" followed by decimal digits. private static bool FindPieceNumber(string path, ref int position, ref ScanStepDelegate nextStep, ref PieceNameInfo parseResults) { if (!char.IsDigit(path[position - 1])) { return(false); } int pieceNumber = 0; int multiplier = 1; // rightmost digit is for units --position; do { pieceNumber += multiplier * (int)char.GetNumericValue(path[position]); multiplier *= 10; } while (char.IsDigit(path[--position])); // Point to the last digit found. ++position; //If we have a leading 0, then its not correct piecename syntax if (multiplier > 10 && (int)char.GetNumericValue(path[position]) == 0) { return(false); } if (!FindString(path, ref position, "/[")) { return(false); } parseResults.PieceNumber = pieceNumber; nextStep = FindPartName; return(true); }