コード例 #1
0
ファイル: UFile.cs プロジェクト: Kryptos-FR/xenko-reloaded
 /// <summary>
 /// Gets the name of the file with its extension.
 /// </summary>
 /// <value>The name of file.</value>
 public string GetFullPathWithoutExtension()
 {
     var span = new StringSpan(0, FullPath.Length);
     if (NameSpan.IsValid)
     {
         span.Length = NameSpan.Next;
     }
     return span.IsValid ? FullPath.Substring(span) : null;
 }
コード例 #2
0
ファイル: UFile.cs プロジェクト: Ethereal77/stride
        public string GetFullPathWithoutExtension()
        {
            var span = new StringSpan(0, FullPath.Length);

            if (NameSpan.IsValid)
            {
                span.Length = NameSpan.Next;
            }
            return(span.IsValid ? FullPath.Substring(span) : null);
        }
コード例 #3
0
ファイル: UPath.cs プロジェクト: zerodowned/paradox
        private static string Decode(string pathToNormalize, bool isPathDirectory, out StringSpan drive, out StringSpan directory, out StringSpan fileName, out StringSpan fileExtension)
        {
            drive         = new StringSpan();
            directory     = new StringSpan();
            fileName      = new StringSpan();
            fileExtension = new StringSpan();

            if (string.IsNullOrWhiteSpace(pathToNormalize))
            {
                return(string.Empty);
            }

            // Normalize path
            // TODO handle network path/http/file path
            string error;
            var    path = Normalize(pathToNormalize, out drive, out directory, out fileName, out error);

            if (error != null)
            {
                throw new ArgumentException(error);
            }

            if (isPathDirectory)
            {
                // If we are expecting a directory, merge the fileName with the directory
                if (fileName.IsValid)
                {
                    directory.Length = directory.Length + 1 + fileName.Length;
                    fileName         = new StringSpan();
                }
            }
            else
            {
                // In case this is only a directory name and we are expecting a filename, gets the directory name as a filename
                if (directory.IsValid && !fileName.IsValid)
                {
                    fileName  = directory;
                    directory = new StringSpan();
                }

                if (fileName.IsValid)
                {
                    var extensionIndex = path.LastIndexOf('.', fileName.Start);
                    if (extensionIndex > 0)
                    {
                        fileName.Length      = extensionIndex - fileName.Start;
                        fileExtension.Start  = extensionIndex;
                        fileExtension.Length = path.Length - extensionIndex;
                    }
                }
            }

            return(path.ToString());
        }
コード例 #4
0
        /// <summary>
        /// snake_case_string を CamelCaseString にする。
        /// </summary>
        public unsafe static string SnakeToCamel(this string snake)
        {
            var p      = stackalloc char[snake.Length];
            var buffer = new StringSpan(p, snake.Length);

            Join(snake, ref buffer, new Splitter('_'), new ToCamel());

            var len = (int)(buffer.Pointer - p);

            return(new string(p, 0, len));
        }
コード例 #5
0
ファイル: QueryBuilder.cs プロジェクト: dvyu/MyNoSqlServer
        public static IEnumerable <QueryCondition> ParseQueryConditions(this string query)
        {
            var stringSpan = new StringSpan(query);

            stringSpan.MoveToTheNextStartOfString();

            while (!stringSpan.Eof)
            {
                var fieldName = stringSpan.ReadNextString();


                var operation = stringSpan.ReadOperation();



                if (operation == QueryOperation.In)
                {
                    var value = stringSpan.ReadInValues();

                    yield return(new QueryCondition
                    {
                        FieldName = fieldName,
                        Values = value.ToArray(),
                        Operation = operation
                    });
                }
                else
                {
                    var value = stringSpan.ReadNextString();

                    yield return(new QueryCondition
                    {
                        FieldName = fieldName,
                        Values = value.ToSingleArray(),
                        Operation = operation
                    });
                }

                stringSpan.MoveToTheNextStartOfString();

                if (stringSpan.Eof)
                {
                    break;
                }


                var logicalOperator = stringSpan.ReadNextString();

                if (logicalOperator.ToLower() != "and")
                {
                    throw new Exception("Only and logical operation is supported for a while");
                }
            }
        }
コード例 #6
0
        public static List <T> Load <T>(string filename = null, int headerLines = 1) where T : new()
        {
            if (filename == null)
            {
                filename = locations[typeof(T)];
            }
            Profiler.BeginSample("Datasheet.Load");
            var stopwatch = Stopwatch.StartNew();

            Profiler.BeginSample("File.ReadAllText");
            var    fileSw     = Stopwatch.StartNew();
            string csv        = File.ReadAllText(Application.streamingAssetsPath + "/" + filename);
            var    fileReadMs = fileSw.ElapsedMilliseconds;

            Profiler.EndSample();

            Loader <T> loader = GetLoader <T>();

            if (loader == null)
            {
                throw new Exception("Datasheet loader for " + typeof(T) + " not found");
            }

            var splitter = new DatasheetLineSplitter(csv);

            splitter.Skip(headerLines);
            var        records   = new List <T>(1024);
            int        lineIndex = headerLines;
            StringSpan line      = new StringSpan();
            var        stream    = new DatasheetStream();

            while (splitter.ReadLine(ref line))
            {
                if (line.length == 0)
                {
                    continue;
                }

                stream.SetSource(line);
                T obj = new T();
                try
                {
                    loader.LoadRecord(ref obj, stream);
                }
                catch (Exception e)
                {
                    throw new Exception("Datasheet parsing error at line " + lineIndex + ": " + line.str.Substring(0, 32), e);
                }
                records.Add(obj);
            }
            Debug.Log("Load " + filename + " (" + records.Count + " records, elapsed " + stopwatch.Elapsed.Milliseconds + " ms, file read " + fileReadMs + " ms)");
            Profiler.EndSample();
            return(records);
        }
コード例 #7
0
 protected UPath(string fullPath, StringSpan driveSpan, StringSpan directorySpan)
 {
     if (fullPath == null)
     {
         throw new ArgumentNullException(nameof(fullPath));
     }
     FullPath      = fullPath;
     hashCode      = ComputeStringHashCodeCaseInsensitive(fullPath);
     DriveSpan     = driveSpan;
     DirectorySpan = directorySpan;
 }
コード例 #8
0
        public CompileError(Document document, StringSpan span, string message)
        {
            SourceToken = new Token()
            {
                SourceDocument = document,
                Type           = TokenType.None,
                Value          = span
            };

            Message = message;
        }
コード例 #9
0
ファイル: Lexer.cs プロジェクト: GlaireDaggers/cozi-lang
            public StringSpan?Match(Document context, StringSpan text, List <CompileError> outErrors)
            {
                var match = Rule.Match(text);

                if (match.Success)
                {
                    return(text.Slice(0, match.Length));
                }

                return(null);
            }
コード例 #10
0
ファイル: StringSpanTests.cs プロジェクト: ExM/NLanguageTag
        public void Operators(string spanText, string text)
        {
            var span = new StringSpan(spanText);

            Assert.Multiple(() =>
            {
                Assert.IsTrue(span <= text);
                Assert.IsFalse(text <= span);
                Assert.IsFalse(span >= text);
                Assert.IsTrue(text >= span);
            });
        }
コード例 #11
0
        public bool ReadLine(ref StringSpan result)
        {
            if (_index >= _str.Length)
            {
                return(false);
            }
            int startIndex = _index;
            int length     = ReadLine();

            result = new StringSpan(_str, startIndex, length);
            return(true);
        }
コード例 #12
0
        /// <summary>
        /// CamelCaseString を snake_case_string に変換する。
        /// </summary>
        public unsafe static string CamelToSnake(this string camel)
        {
            // 全部大文字の時がワーストケースで、元の長さの2倍。
            var p      = stackalloc char[camel.Length * 2];
            var buffer = new StringSpan(p, camel.Length);

            Join(camel, ref buffer, new UpperCaseSplitter(), default(ToSnake));

            var len = (int)(buffer.Pointer - p);

            return(new string(p, 0, len));
        }
コード例 #13
0
        public static int Split(string input, char c, int start, out StringSpan span)
        {
            for (int i = start; i < input.Length; i++)
            {
                if (input[i] == c)
                {
                    span = new StringSpan(input, start, i - start);
                }
            }

            span = new StringSpan(null, -1, -1);
            return(input.Length);
        }
コード例 #14
0
        /// <summary>
        /// <paramref name="s"/>を<paramref name="splitter"/>で分割して<paramref name="formatter"/>で結合する。
        /// </summary>
        /// <param name="s">元の文字列。</param>
        /// <param name="buffer">書き込み先。</param>
        /// <param name="splitter">分割用。</param>
        /// <param name="formatter">結合用。</param>
        public unsafe static void Join <TSplitter, TFormatter>(this string s, ref StringSpan buffer, TSplitter splitter = default, TFormatter formatter = default)
            where TSplitter : IStringSplitter
            where TFormatter : IStringFormatter
        {
            fixed(char *p = s)
            {
                var span = new StringSpan(p, s.Length);

                while (splitter.TryMoveNext(ref span, out var word))
                {
                    formatter.Write(word, ref buffer);
                }
            }
        }
コード例 #15
0
ファイル: QueryBuilder.cs プロジェクト: dvyu/MyNoSqlServer
        private static string ReadNextString(this StringSpan stringSpan)
        {
            stringSpan.MoveToTheNextStartOfString();

            var isString = stringSpan.CurrentChar == CharToEscape;

            if (isString)
            {
                stringSpan.MoveEndPosition(EscapeSequence, c => c == CharToEscape, 1);
                stringSpan.MoveEndPosition(1);
                return(stringSpan.GetCurrentValue(EscapeSequence, StringToEscape));
            }

            stringSpan.MoveEndPosition(EscapeSequence, c => c <= ' ');
            return(stringSpan.GetCurrentValue());
        }
コード例 #16
0
ファイル: Storage.cs プロジェクト: daxiang758/WInterop
        /// <summary>
        /// Get a stream for the specified file.
        /// </summary>
        public static System.IO.Stream CreateFileStream(
            StringSpan path,
            DesiredAccess desiredAccess,
            ShareModes shareMode,
            CreationDisposition creationDisposition,
            FileAttributes fileAttributes     = FileAttributes.None,
            FileFlags fileFlags               = FileFlags.None,
            SecurityQosFlags securityQosFlags = SecurityQosFlags.None)
        {
            var fileHandle = CreateFile(path, creationDisposition, desiredAccess, shareMode, fileAttributes, fileFlags, securityQosFlags);

            // FileStream will own the lifetime of the handle
            return(new System.IO.FileStream(
                       handle: fileHandle,
                       access: Conversion.DesiredAccessToFileAccess(desiredAccess),
                       bufferSize: 4096,
                       isAsync: (fileFlags & FileFlags.Overlapped) != 0));
        }
コード例 #17
0
ファイル: Storage.cs プロジェクト: daxiang758/WInterop
 /// <summary>
 /// Wrapper that allows using System.IO defines where available. Calls CreateFile2 if available.
 /// </summary>
 public static SafeFileHandle CreateFileSystemIo(
     StringSpan path,
     System.IO.FileAccess fileAccess,
     System.IO.FileShare fileShare,
     System.IO.FileMode fileMode,
     System.IO.FileAttributes fileAttributes = 0,
     FileFlags fileFlags            = FileFlags.None,
     SecurityQosFlags securityFlags = SecurityQosFlags.None)
 {
     return(CreateFile(
                path: path,
                desiredAccess: Conversion.FileAccessToDesiredAccess(fileAccess),
                shareMode: Conversion.FileShareToShareMode(fileShare),
                creationDisposition: Conversion.FileModeToCreationDisposition(fileMode),
                fileAttributes: (FileAttributes)fileAttributes,
                fileFlags: fileFlags,
                securityQosFlags: securityFlags));
 }
コード例 #18
0
ファイル: QueryBuilder.cs プロジェクト: dvyu/MyNoSqlServer
        private static IEnumerable <string> ReadInValues(this StringSpan stringSpan)
        {
            stringSpan.MoveToTheNextStartOfString();

            var arrayIsOpened = stringSpan.CurrentChar == '[';

            if (!arrayIsOpened)
            {
                throw new Exception("Invalid int operation at position: " + stringSpan.PositionStart);
            }

            stringSpan.MoveStartPosition(1);
            stringSpan.SyncEndWithStart();

            while (!stringSpan.Eof)
            {
                var value = stringSpan.ReadNextStringFromArray();
                yield return(value);

                stringSpan.SyncStartWithEnd();

                if (stringSpan.CurrentChar <= ' ')
                {
                    stringSpan.MoveToTheNextStartOfString();
                    stringSpan.SyncEndWithStart();
                }

                if (stringSpan.CurrentChar == ']')
                {
                    stringSpan.MoveStartPosition(1);
                    stringSpan.SyncEndWithStart();
                    break;
                }

                if (stringSpan.CurrentChar != ',')
                {
                    stringSpan.MoveStartPosition(EscapeSequence, c => c == ',' || c == ']');
                }

                stringSpan.MoveStartPosition(1);
                stringSpan.SyncEndWithStart();
            }
        }
コード例 #19
0
        /// <summary>
        /// Trims the path by removing unecessary '..' and '.' path items.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="currentPath">The current path.</param>
        /// <param name="paths">The paths.</param>
        /// <param name="isLastTrim">if set to <c>true</c> is last trim to occur.</param>
        /// <returns><c>true</c> if trim has been done, <c>false</c> otherwise.</returns>
        private static unsafe bool TrimParentAndSelfPath(StringBuilder builder, ref int currentPath, StringSpan *paths, bool isLastTrim)
        {
            var path = paths[currentPath];

            if (currentPath > 0 && IsParentPath(builder, path))
            {
                // If previous path is already a relative path, then we probably can popup
                var previousPath = paths[currentPath - 1];
                if (IsParentPath(builder, previousPath))
                {
                    return(false);
                }

                // Note: the drive path has a negative Length at that moment so it will also be considered invalid (which is what we want)
                if (!previousPath.IsValid)
                {
                    // Swallow the parent path if we reached some root level
                    paths[currentPath].Length = 0;
                    builder.Length            = paths[currentPath].Start;
                    return(true);
                }

                // We can popup the previous path
                paths[currentPath] = new StringSpan();
                currentPath--;
                paths[currentPath].Length = 0;
                builder.Length            = paths[currentPath].Start;
                return(true);
            }

            var isRelativeCurrentPath = IsRelativeCurrentPath(builder, path);

            if (!(isLastTrim && currentPath == 0 && isRelativeCurrentPath) && isRelativeCurrentPath)
            {
                // We can popup the previous path
                paths[currentPath].Length = 0;
                builder.Length            = paths[currentPath].Start;
                return(true);
            }
            return(false);
        }
コード例 #20
0
        private static MetadataTypeReference ReadGenericArgument(ref StringSpan remaining)
        {
            var isBracketed = TryRead(ref remaining, '[');

            var(typeName, genericArguments, nestedArrayRanks) = ReadTypeParts(ref remaining);

            var assemblyName = default(StringSpan);

            if (isBracketed)
            {
                var endingBracket = remaining.IndexOf(']');
                if (endingBracket == -1)
                {
                    throw new FormatException("Expected ']'");
                }
                assemblyName = TryReadAssemblyName(remaining.Slice(0, endingBracket));
                remaining    = remaining.Slice(endingBracket + 1);
            }

            return(CreateType(typeName, assemblyName, genericArguments, nestedArrayRanks));
        }
コード例 #21
0
ファイル: Storage.cs プロジェクト: daxiang758/WInterop
        /// <summary>
        /// Gets a canonical version of the given file's path.
        /// </summary>
        /// <param name="resolveLinks">True to get the destination of links rather than the link itself.</param>
        public static string GetFinalPathName(StringSpan path, GetFinalPathNameByHandleFlags finalPathFlags, bool resolveLinks)
        {
            if (path.IsEmpty)
            {
                return(null);
            }

            // BackupSemantics is needed to get directory handles
            FileFlags flags = FileFlags.BackupSemantics;

            if (!resolveLinks)
            {
                flags |= FileFlags.OpenReparsePoint;
            }

            using (SafeFileHandle fileHandle = CreateFile(path, CreationDisposition.OpenExisting, 0, ShareModes.ReadWrite,
                                                          FileAttributes.None, flags))
            {
                return(GetFinalPathNameByHandle(fileHandle, finalPathFlags));
            }
        }
コード例 #22
0
ファイル: UPath.cs プロジェクト: zerodowned/paradox
        /// <summary>
        /// Trims the path by removing unecessary '..' and '.' path items.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="currentPath">The current path.</param>
        /// <param name="paths">The paths.</param>
        /// <param name="isLastTrim">if set to <c>true</c> is last trim to occur.</param>
        /// <returns><c>true</c> if trim has been done, <c>false</c> otherwise.</returns>
        private unsafe static bool TrimParentAndSelfPath(StringBuilder builder, ref int currentPath, StringSpan *paths, bool isLastTrim)
        {
            var path = paths[currentPath];

            if (currentPath > 0 && IsParentPath(builder, path))
            {
                // If the root path is a drive, and we are going to back slash, just don't
                if (IsInvalidRelativeBacktrackOnDrive(currentPath, paths))
                {
                    return(false);
                }

                // If previous path is already a relative path, then we probably can popup
                var previousPath = paths[currentPath - 1];
                if (IsParentPath(builder, previousPath))
                {
                    return(false);
                }

                // We can popup the previous path
                paths[currentPath] = new StringSpan();
                currentPath--;
                paths[currentPath].Length = 0;
                builder.Length            = paths[currentPath].Start;
                return(true);
            }

            var isRelativeCurrentPath = IsRelativeCurrentPath(builder, path);

            if (!(isLastTrim && currentPath == 0 && isRelativeCurrentPath) && isRelativeCurrentPath)
            {
                // We can popup the previous path
                paths[currentPath].Length = 0;
                builder.Length            = paths[currentPath].Start;
                return(true);
            }
            return(false);
        }
コード例 #23
0
        public unsafe bool TryMoveNext(ref StringSpan state, out StringSpan word)
        {
            var p   = state.Pointer;
            var end = p + state.Length;

            if (p >= end)
            {
                word = default;
                return(false);
            }

            while (++p < end && !char.IsUpper(*p))
            {
                ;
            }

            var len = (int)(p - state.Pointer);

            word  = state.Slice(0, len);
            state = state.Slice(len);

            return(true);
        }
コード例 #24
0
        private static int ReadArrayRank(ref StringSpan remaining)
        {
            var rank = 1;

            for (;;)
            {
                switch (TryRead(ref remaining))
                {
                case ',':
                    rank++;
                    break;

                case ' ':
                    break;

                case ']':
                    return(rank);

                default:
                    throw new FormatException("Expected ' ', ',', or ']'");
                }
            }
        }
コード例 #25
0
ファイル: Lexer.cs プロジェクト: GlaireDaggers/cozi-lang
 public StringSpan?Match(Document context, StringSpan text, List <CompileError> outErrors)
 {
     return(Func(context, text, outErrors));
 }
コード例 #26
0
        private static string Decode(string pathToNormalize, bool isPathDirectory, out StringSpan drive, out StringSpan directory, out StringSpan fileName, out StringSpan fileExtension)
        {
            drive         = new StringSpan();
            directory     = new StringSpan();
            fileName      = new StringSpan();
            fileExtension = new StringSpan();

            if (string.IsNullOrWhiteSpace(pathToNormalize))
            {
                return(string.Empty);
            }

            // Normalize path
            // TODO handle network path/http/file path
            string error;
            var    path = Normalize(pathToNormalize, out drive, out directory, out fileName, out error);

            if (error != null)
            {
                throw new ArgumentException(error);
            }

            if (isPathDirectory)
            {
                // If we are expecting a directory, merge the fileName with the directory
                if (fileName.IsValid)
                {
                    if (directory.IsValid)
                    {
                        // Case of '../file'
                        directory.Length += fileName.Length;
                    }
                    else if (drive.IsValid)
                    {
                        // case of 'C:/file'
                        directory.Start  = drive.Next;
                        directory.Length = fileName.Length + 1;
                    }
                    else
                    {
                        // Case of just a file 'file', make sure to include the leading '/' if there is one,
                        // which is why we don't just do 'directory = fileName'.
                        directory.Start  = 0;
                        directory.Length = fileName.Next;
                    }
                    fileName = new StringSpan();
                }
                else if (drive.IsValid && !directory.IsValid)
                {
                    // Case of just C:, we need to add a '/' to be a valid directory
                    path.Append(DirectorySeparatorChar);
                    directory.Start  = drive.Next;
                    directory.Length = 1;
                }
            }
            else
            {
                // In case this is only a directory name and we are expecting a filename, gets the directory name as a filename
                if (directory.IsValid && !fileName.IsValid)
                {
                    fileName  = directory;
                    directory = new StringSpan();
                }

                if (fileName.IsValid)
                {
                    var extensionIndex = path.LastIndexOf('.', fileName.Start);
                    if (extensionIndex >= 0)
                    {
                        fileName.Length      = extensionIndex - fileName.Start;
                        fileExtension.Start  = extensionIndex;
                        fileExtension.Length = path.Length - extensionIndex;
                    }
                }
            }

            return(path.ToString());
        }
コード例 #27
0
        /// <summary>
        /// Normalize a path by replacing '\' by '/' and transforming relative '..' or current path '.' to an absolute path. See remarks.
        /// </summary>
        /// <param name="pathToNormalize">The path automatic normalize.</param>
        /// <param name="drive">The drive character region.</param>
        /// <param name="directoryOrFileName">The directory.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="error">The error or null if no errors.</param>
        /// <returns>A normalized path or null if there is an error.</returns>
        /// <remarks>Unlike <see cref="System.IO.Path" /> , this doesn't make a path absolute to the actual file system.</remarks>
        public static unsafe StringBuilder Normalize(string pathToNormalize, out StringSpan drive, out StringSpan directoryOrFileName, out StringSpan fileName, out string error)
        {
            drive = new StringSpan();
            directoryOrFileName = new StringSpan();
            fileName            = new StringSpan();
            error = null;
            string path = pathToNormalize;

            if (path == null)
            {
                return(null);
            }
            int countDirectories = pathToNormalize.Count(pathItem => pathItem == DirectorySeparatorChar ||
                                                         pathItem == DirectorySeparatorCharAlt ||
                                                         pathItem == Path.VolumeSeparatorChar);

            // Safeguard if count directories is going wild
            if (countDirectories > 1024)
            {
                error = "Path contains too many directory '/' separator or ':'";
                return(null);
            }

            // Optimize the code by using stack alloc in order to avoid allocation of a List<StringSpan>()
            int currentPath          = -1;
            NormalizationState state = NormalizationState.StartComponent;
            bool hasDriveSpan        = false;
            var  paths   = stackalloc StringSpan[countDirectories + 1];
            var  builder = new StringBuilder(pathToNormalize.Length);

            // Iterate on all chars on original path
            foreach (var pathItem in pathToNormalize)
            {
                // Check if we have a directory separator
                if (pathItem == DirectorySeparatorChar || pathItem == DirectorySeparatorCharAlt)
                {
                    // Add only non consecutive '/'
                    if (state != NormalizationState.DirectorySeparator)
                    {
                        // Special case where path is starting with "/" or with "X:/", we will create
                        // an entry just for the "/".
                        if ((state == NormalizationState.StartComponent) || (state == NormalizationState.VolumeSeparator))
                        {
                            currentPath++;
                            paths[currentPath] = new StringSpan(builder.Length, 1);
                        }
                        else
                        {
                            paths[currentPath].Length++;
                        }
                        builder.Append(DirectorySeparatorChar);

                        // We are either reading more directory separator or reading a new component.
                        state = NormalizationState.DirectorySeparator;
                    }
                }
                else if (pathItem == Path.VolumeSeparatorChar)
                {
                    // Check in case of volume separator ':'
                    if (hasDriveSpan)
                    {
                        error = "Path contains more than one drive ':' separator";
                        return(null);
                    }

                    if (state == NormalizationState.DirectorySeparator)
                    {
                        error = "Path cannot contain a drive ':' separator after a backslash";
                        return(null);
                    }

                    if (state == NormalizationState.StartComponent)
                    {
                        error = "Path cannot start with a drive ':' separator";
                        return(null);
                    }

                    // Append the volume ':'
                    builder.Append(pathItem);
                    paths[currentPath].Length++;
                    hasDriveSpan = true;

                    state = NormalizationState.VolumeSeparator; // We are expecting to read a directory separator now
                }
                else if (!InvalidFileNameChars.Contains(pathItem))
                {
                    if (state == NormalizationState.VolumeSeparator)
                    {
                        error = @"Path must contain a separator '/' or '\' after the volume separator ':'";
                        return(null);
                    }
                    else if ((state == NormalizationState.StartComponent) || (state == NormalizationState.DirectorySeparator))
                    {
                        // We are starting a new component. Check if previous one is either '..' or '.', in which case
                        // we can simplify
                        TrimParentAndSelfPath(builder, ref currentPath, paths, hasDriveSpan, false);
                        currentPath++;
                        paths[currentPath] = new StringSpan(builder.Length, 0);
                    }
                    builder.Append(pathItem);
                    paths[currentPath].Length++;
                    state = NormalizationState.InComponent; // We are expecting to read either a character, a separator or a volume separator;
                }
                else
                {
                    // Else the character is invalid
                    error = "Invalid character [{0}] found in path [{1}]".ToFormat(pathItem, pathToNormalize);
                    return(null);
                }
            }

            // Remove trailing '..' or '.'
            TrimParentAndSelfPath(builder, ref currentPath, paths, hasDriveSpan, true);
            // Remove trailing if and only if the path content is not "/" or "c:/".
            if ((builder.Length > (hasDriveSpan ? paths[0].Next + 1 : 1)) && (builder[builder.Length - 1] == DirectorySeparatorChar))
            {
                builder.Length = builder.Length - 1;
                paths[currentPath].Length--;
            }

            // Go back to upper path if current is not vaid
            if (currentPath > 0 && !paths[currentPath].IsValid)
            {
                currentPath--;
            }

            // Copy the drive, directory, filename information to the output
            int startDirectory = 0;

            if (hasDriveSpan)
            {
                drive          = paths[0];
                startDirectory = 1;
            }

            // If there is any directory information, process it
            if (startDirectory <= currentPath)
            {
                directoryOrFileName.Start = paths[startDirectory].Start;
                if (currentPath == startDirectory)
                {
                    directoryOrFileName.Length = paths[startDirectory].Length;
                }
                else
                {
                    directoryOrFileName.Length = paths[currentPath - 1].Next - directoryOrFileName.Start;

                    if (paths[currentPath].IsValid)
                    {
                        // In case last path is a parent '..' don't include it in fileName
                        if (IsParentComponentPath(builder, paths[currentPath]))
                        {
                            directoryOrFileName.Length += paths[currentPath].Length;
                        }
                        else
                        {
                            fileName.Start  = paths[currentPath].Start;
                            fileName.Length = builder.Length - fileName.Start;
                        }
                    }
                }
            }

            return(builder);
        }
コード例 #28
0
ファイル: Program.cs プロジェクト: Serg-Norseman/BSLib
 public static string GetSubStrSpan(StringSpan strSpan)
 {
     return(strSpan.Slice(11, 12).ToString());
 }
コード例 #29
0
ファイル: Program.cs プロジェクト: Serg-Norseman/BSLib
        public static void Main(string[] args)
        {
            const string TestStr = "aaaaaaaaaa bbbbbbbbbbbb cccccccccccc dddddddddddd eeeeeeeeee ffffffffff gggggggggg";

            long y = 0;

            for (int k = 0; k < IterNum; k++)
            {
                y += EnumPureString(TestStr);
            }

            StringSpan strSpan = TestStr;

            for (int k = 0; k < IterNum; k++)
            {
                y += EnumStringSpan(strSpan);
            }

            char[] charArr = TestStr.ToCharArray();

            for (int k = 0; k < IterNum; k++)
            {
                y += EnumPureCharArr(charArr);
            }

            ArraySpan <char> arrSpan = charArr;

            for (int k = 0; k < IterNum; k++)
            {
                y += EnumArraySpan(arrSpan);
            }

            for (int k = 0; k < IterNum; k++)
            {
                var str1 = GetSubPureStr(TestStr);
                if (str1 != "bbbbbbbbbbbb")
                {
                    throw new ArgumentException("str1");
                }
                Hole(ref str1);
            }

            for (int k = 0; k < IterNum; k++)
            {
                var str2 = GetSubStrSpan(strSpan);
                if (str2 != "bbbbbbbbbbbb")
                {
                    throw new ArgumentException("str2");
                }
                Hole(ref str2);
            }

            for (int k = 0; k < IterNum; k++)
            {
                var str2 = GetSubPureCharArr(charArr);
                if (str2 != "bbbbbbbbbbbb")
                {
                    throw new ArgumentException("str2");
                }
                Hole(ref str2);
            }

            for (int k = 0; k < IterNum; k++)
            {
                var str2 = GetSubArraySpan(arrSpan);
                if (str2 != "bbbbbbbbbbbb")
                {
                    throw new ArgumentException("str2");
                }
                Hole(ref str2);
            }

            Console.WriteLine(y);
        }
コード例 #30
0
 internal UDirectory([NotNull] string fullPath, StringSpan driveSpan, StringSpan directorySpan) : base(fullPath, driveSpan, directorySpan)
 {
 }
コード例 #31
0
 public int GetChildIndex(StringSpan nameSpan) => Children.IndexOf(nameSpan, NameEquals);
コード例 #32
0
 internal UDirectory(string fullPath, StringSpan driveSpan, StringSpan directorySpan) : base(fullPath, driveSpan, directorySpan)
 {
 }
コード例 #33
0
ファイル: StringSpanExtensions.cs プロジェクト: cg123/xenko
 /// <summary>
 /// Gets the substring with the specified span. If the span is invalid, return null.
 /// </summary>
 /// <param name="str">The string.</param>
 /// <param name="span">The span.</param>
 /// <returns>A substring with the specified span or null if span is empty.</returns>
 public static string Substring(this string str, StringSpan span)
 {
     return span.IsValid ? str.Substring(span.Start, span.Length) : null;
 }