Пример #1
0
        public void String8Block_Basics()
        {
            String8Block block = new String8Block();

            byte[]  buffer = new byte[4096];
            String8 value  = String8.Convert("hello", buffer);

            // Verify copies are persistent when the original buffer is overwritten
            String8 valueCopy = block.GetCopy(value);

            String8.Convert("there", buffer);
            Assert.AreEqual("there", value.ToString());
            Assert.AreEqual("hello", valueCopy.ToString());

            // Verify copy of String8.Empty works
            String8 emptyCopy = block.GetCopy(String8.Empty);

            Assert.IsTrue(emptyCopy.IsEmpty());

            // Verify large strings are copied correctly (stored individually)
            value     = String8.Convert(new string('A', 4096), buffer);
            valueCopy = block.GetCopy(value);
            Assert.IsTrue(value.Equals(valueCopy));
            String8.Convert(new string('B', 4096), buffer);
            Assert.IsFalse(value.Equals(valueCopy));

            // Verify storage uses multiple blocks correctly
            for (int i = 0; i < 1000; ++i)
            {
                value     = String8.Convert(new string((char)('0' + (i % 10)), 100), buffer);
                valueCopy = block.GetCopy(value);
                Assert.IsTrue(value.Equals(valueCopy));
            }

            // Verify conversion of strings
            String8 directConversion = block.GetCopy("Regular String");

            Assert.AreEqual("Regular String", directConversion.ToString());

            // Verify null/empty string conversion
            directConversion = block.GetCopy((string)null);
            Assert.IsTrue(directConversion.IsEmpty());

            directConversion = block.GetCopy(String.Empty);
            Assert.IsTrue(directConversion.IsEmpty());

            // Verify clear works (doesn't throw, GetCopy works afterward)
            block.Clear();
            valueCopy = block.GetCopy("Third");
            Assert.AreEqual("Third", valueCopy.ToString());
        }
Пример #2
0
        public void String8_ToUpperToLower()
        {
            // Verify no exception
            String8.Empty.ToUpperInvariant();
            String8.Empty.ToLowerInvariant();

            String8 sample = "abcABC@[`{".TestConvert();

            sample.ToUpperInvariant();
            Assert.AreEqual("ABCABC@[`{", sample.ToString());

            sample = "abcABC@[`{".TestConvert();
            sample.ToLowerInvariant();
            Assert.AreEqual("abcabc@[`{", sample.ToString());
        }
Пример #3
0
        public void String8_ShiftBack()
        {
            String8Block block = new String8Block();

            // Goal: Split on semi-colon, collapse semi-colon and spaces in-place
            String8 shiftable  = "One; Two;Three; Four".TestConvert();
            int     totalShift = 0;

            String8Set parts = shiftable.Split(UTF8.Semicolon, new PartialArray <int>(5, false));

            for (int i = 0; i < parts.Count; ++i)
            {
                String8 part = parts[i];

                totalShift++;
                if (part.StartsWith(UTF8.Space))
                {
                    part = part.Substring(1);
                    totalShift++;
                }

                String8 beforeShift = block.GetCopy(part);
                String8 shifted     = part.ShiftBack(totalShift);
                Assert.AreEqual(beforeShift, shifted);
            }

            String8 result = shiftable.Substring(0, shiftable.Length - totalShift);

            Assert.AreNotEqual("OneTwoThreeFour", result.ToString());
        }
Пример #4
0
        private void ReadColumnLine(String8 line)
        {
            // Skip empty lines
            if (line.Length == 0)
            {
                return;
            }

            // Skip record separator, continuation lines, comments, and grouping lines
            byte first = line[0];

            if (first == UTF8.CR || first == UTF8.Space || first == UTF8.Pound || first == UTF8.Dash)
            {
                return;
            }

            // Find the column name part of the line
            String8 columnName = line.BeforeFirst(UTF8.Colon);

            // If we haven't seen this column name before, add it to our collection
            if (!columnName.IsEmpty() && !_columnIndices8.ContainsKey(columnName))
            {
                int columnIndex = _columnIndices8.Count;
                _columnIndices8[_columnNamesBlock.GetCopy(columnName)] = columnIndex;

                string columnNameString = columnName.ToString();
                _columnNames.Add(columnNameString);
                _columnIndices[columnNameString] = columnIndex;
            }
        }
Пример #5
0
        private string CsvSplitAndJoin(string value)
        {
            String8    value8  = String8.Convert(value, new byte[String8.GetLength(value)]);
            String8Set set     = value8.SplitAndDecodeCsvCells(new PartialArray <int>());
            String8    joined8 = set.Join(UTF8.Pipe, new byte[set.Value.Length]);

            return(joined8.ToString());
        }
Пример #6
0
        private string SplitOutsideQuotesAndJoin(string value, byte delimiter)
        {
            String8    value8  = String8.Convert(value, new byte[String8.GetLength(value)]);
            String8Set set     = value8.SplitOutsideQuotes(delimiter, new PartialArray <int>());
            String8    joined8 = set.Join(UTF8.Pipe, new byte[set.Value.Length]);

            return(joined8.ToString());
        }
Пример #7
0
        public void String8_TrimEnd()
        {
            String8 sample = "Interesting   ".TestConvert();

            Assert.AreEqual("Interesting", sample.TrimEnd(UTF8.Space).ToString());
            Assert.AreEqual(sample.ToString(), sample.TrimEnd(UTF8.Tab).ToString());
            Assert.AreEqual(string.Empty, String8.Empty.TrimEnd(UTF8.Space).ToString());
            Assert.AreEqual(string.Empty, "   ".TestConvert().TrimEnd(UTF8.Space).ToString());
            Assert.AreEqual("A", "A   ".TestConvert().TrimEnd(UTF8.Space).ToString());
        }
Пример #8
0
        public void String8_ToUpper()
        {
            // Verify no exception
            String8.Empty.ToUpperInvariant();

            String8 sample = String8.Convert("abcABC", new byte[6]);

            sample.ToUpperInvariant();
            Assert.AreEqual("ABCABC", sample.ToString());
        }
Пример #9
0
        public void String8Block_Concatenate()
        {
            String8Block block     = new String8Block();
            String8      delimiter = block.GetCopy("; ");
            String8      one       = block.GetCopy("One");
            String8      two       = block.GetCopy("Two");
            String8      three     = block.GetCopy("Three");

            // Verify Concatenate returns only one side if the other is empty
            Assert.AreEqual(String8.Empty, block.Concatenate(String8.Empty, delimiter, String8.Empty));
            Assert.AreEqual(two, block.Concatenate(String8.Empty, delimiter, two));
            Assert.AreEqual(two, block.Concatenate(two, delimiter, String8.Empty));

            // Verify a regular concatenation
            String8 oneTwo = block.Concatenate(one, delimiter, two);

            Assert.AreEqual("One; Two", oneTwo.ToString());

            // Verify re-concatenating the last item re-uses memory and doesn't mess up previous item
            String8 oneTwoThree = block.Concatenate(oneTwo, delimiter, three);

            Assert.AreEqual(oneTwo._buffer, oneTwoThree._buffer);
            Assert.AreEqual(oneTwo._index, oneTwoThree._index);

            Assert.AreEqual("One; Two", oneTwo.ToString());
            Assert.AreEqual("One; Two; Three", oneTwoThree.ToString());

            // Verify re-concatenating doesn't overwrite a following item
            String8 four            = block.GetCopy("Four");
            String8 oneTwoThreeFour = block.Concatenate(oneTwoThree, delimiter, four);

            Assert.AreEqual("One; Two; Three", oneTwoThree.ToString());
            Assert.AreEqual("One; Two; Three; Four", oneTwoThreeFour.ToString());

            // Concatenate over the 64K limit and ensure reasonable behavior
            String8 eight    = block.GetCopy("12345678");
            String8 eightSet = String8.Empty;

            for (int i = 0; i < 10000; ++i)
            {
                eightSet = block.Concatenate(eightSet, delimiter, eight);
            }
        }
Пример #10
0
        /// <summary>
        ///  Translate a single literal value to the sanitized form, given the value
        ///  and which column it is from. Uses the mapper configured for the column in
        ///  the spec file.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <param name="columnName">ColumnName value is from</param>
        /// <returns>Sanitized version of value</returns>
        public string Translate(string value, string columnName)
        {
            IColumnHandler handler;

            // If there's no handler, there's no re-mapping
            if (!this.HandlersByColumn.TryGetValue(columnName, out handler))
            {
                handler = new KeepColumnHandler();
            }

            // Convert and return the value
            String8 value8      = String8.Convert(value, new byte[String8.GetLength(value)]);
            String8 replacement = this.HandlersByColumn[columnName].Sanitize(value8);

            return(replacement.ToString());
        }
Пример #11
0
        private static string SplitAndJoin(string content)
        {
            StringBuilder result = new StringBuilder();

            byte[] buffer = new byte[content.Length];
            using (BufferedReader reader = BufferedReader.FromString(content, ref buffer))
            {
                bool isWord = WordSplitter.IsLetterOrDigit(reader.Buffer[reader.Index]);
                int  length = 0;
                while (!reader.EndOfStream)
                {
                    // Read the next word
                    length = WordSplitter.NextWordLength(reader, isWord);
                    String8 word = String8.Reference(reader.Buffer, reader.Index, length);

                    // Set state to read next word
                    reader.Index += length;
                    isWord        = !isWord;

                    if (reader.Index < reader.Length || reader.EndOfStream)
                    {
                        // If this is word is definitely complete, write it
                        if (result.Length > 0)
                        {
                            result.Append("|");
                        }
                        result.Append(word.ToString());
                    }
                    else if (!reader.EndOfStream)
                    {
                        // Reset state to re-read this word
                        reader.Index -= length;
                        isWord        = !isWord;

                        // If end of buffer but not stream, request more
                        reader.EnsureSpace(length * 2);
                    }
                }
            }

            return(result.ToString());
        }
Пример #12
0
        public String8 Sanitize(String8 value8)
        {
            this.Block.Clear();
            StringBuilder result = new StringBuilder();

            string value            = value8.ToString();
            int    nextIndexToWrite = 0;

            foreach (Match m in this.Regex.Matches(value))
            {
                // Replace the whole expression if no groups, otherwise the first parenthesized group
                Group g = m.Groups[0];
                if (m.Groups.Count > 1)
                {
                    g = m.Groups[1];
                }

                // Write content before this match
                result.Append(value.Substring(nextIndexToWrite, g.Index - nextIndexToWrite));

                // Convert and write the match
                String8 part = this.Inner.Sanitize(this.Block.GetCopy(g.Value));
                result.Append(part.ToString());

                // Set the next non-match we need to write
                nextIndexToWrite = g.Index + g.Length;
            }

            // Write anything after the last match
            if (nextIndexToWrite < value.Length)
            {
                result.Append(value.Substring(nextIndexToWrite));
            }

            return(this.Block.GetCopy(result.ToString()));
        }
Пример #13
0
        private bool AddUniqueMembers(
            PackageDatabase source,
            int sourceMemberIndex,
            int targetMemberIndex,
            DatabaseAddResult result,
            ArdbVersion version)
        {
            int           pathLength              = result.CurrentPath.Length;
            SymbolDetails memberDetails           = source.DeclaredMemberDetails[sourceMemberIndex];
            bool          hasUniqueDescendants    = false;
            int           indexToAddChildrenUnder = targetMemberIndex;

            // Add public types and namespaces which contain either
            bool addMember = false;

            if (memberDetails.Type == SymbolType.FrameworkTarget)
            {
                String8 encodedFrameworkNames = source.StringStore[source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex)];
                result.CurrentFrameworkNames = new HashSet <string>(encodedFrameworkNames.ToString().ToFrameworkNames());
            }
            else if (memberDetails.Type == SymbolType.Namespace)
            {
                addMember = ContainsPublics(source, sourceMemberIndex);
            }
            else if (memberDetails.Type == SymbolType.Assembly)
            {
                if (result.CurrentFrameworkNames != null)
                {
                    result.CurrentFrameworkNames.Clear();
                }
            }
            else if (memberDetails.Type.IsType())
            {
                addMember = memberDetails.Modifiers.HasFlag(SymbolModifier.Public);
            }

            // Add the member if it is a public type or contains them [and set 'indexInTarget' to the added member]
            if (addMember)
            {
                result.PublicTypeCount++;

                // Remap name for target StringStore [all unique names will be added anyway]
                int     memberName     = source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex);
                String8 memberNameText = source.StringStore[memberName];
                result.CurrentPath.Append((result.CurrentPath.Length > 0 ? "." : "") + memberNameText.ToString());
                memberName = this.StringStore.FindOrAddString(memberNameText);

                string           fullTypeName;
                HashSet <string> frameworkTargets;

                // See if this name is already found in the merged namespace tree
                if (!this.MergedMembers.TryFindChildByName(targetMemberIndex, memberName, out indexToAddChildrenUnder))
                {
                    // If not, add it, and the tree is unique because this name is
                    indexToAddChildrenUnder = this.MergedMembers.Add(targetMemberIndex, memberName);

                    // Identify the package which added it
                    int packageNameIdentifier = this.StringStore.FindOrAddString(source.Identity.PackageName);
                    this.MergedMemberSourcePackageIdentifier.Add(packageNameIdentifier);
                    this.MergedMemberDuplicateCount.Add(1);

                    hasUniqueDescendants = true;
                    result.MergedTypeCount++;

                    if (version != ArdbVersion.V1 && memberDetails.Type.IsType())
                    {
                        // We have encountered a fully-qualified type name for the
                        // very first time. We will associate this name with the
                        // current framework target. We will also remember this
                        // sourceMemberIndex, in order to use it as the item
                        // to add when populating the ARDB.
                        fullTypeName = result.CurrentPath.ToString();
                        result.TypeToFrameworkTargetsMap.Add(fullTypeName, new HashSet <string>());

                        if (result.CurrentFrameworkNames != null)
                        {
                            result.TypeToFrameworkTargetsMap[fullTypeName].UnionWith(result.CurrentFrameworkNames);
                        }

                        result.TypeNameToTypeIndexMap.Add(fullTypeName, sourceMemberIndex);
                    }
                }
                else
                {
                    // Otherwise, if this is a duplicate with another entry in the same package, still include it (different framework targets)
                    String8 sourcePackage = this.StringStore[this.MergedMemberSourcePackageIdentifier[indexToAddChildrenUnder]];
                    if (version != ArdbVersion.V1 &&
                        result.CurrentFrameworkNames != null &&
                        sourcePackage.Equals(source.Identity.PackageName))
                    {
                        hasUniqueDescendants = true;
                        result.MergedTypeCount++;

                        if (version != ArdbVersion.V1 && memberDetails.Type.IsType())
                        {
                            // We have encountered a fully-qualified type name that we've seen
                            // before. We will record the current framework target but
                            // will already have a source member index to use to add
                            // to the ARDB later.
                            fullTypeName     = result.CurrentPath.ToString();
                            frameworkTargets = result.TypeToFrameworkTargetsMap[fullTypeName];
                            frameworkTargets.UnionWith(result.CurrentFrameworkNames);
                            Debug.Assert(result.TypeNameToTypeIndexMap.ContainsKey(fullTypeName));
                        }
                    }
                    else
                    {
                        // If this isn't unique, increment the count of copies
                        this.MergedMemberDuplicateCount[indexToAddChildrenUnder] += 1;
                    }
                }
            }

            if (!memberDetails.Type.IsType())
            {
                int childIndex = source.DeclaredMembers.GetFirstChild(sourceMemberIndex);
                while (childIndex > 0)
                {
                    hasUniqueDescendants |= AddUniqueMembers(source, childIndex, indexToAddChildrenUnder, result, version);
                    childIndex            = source.DeclaredMembers.GetNextSibling(childIndex);
                }
            }

            // Add the package which had this member to results if it wasn't unique
            if (hasUniqueDescendants == false)
            {
                result.SourcePackageNames[sourceMemberIndex] = this.StringStore[this.MergedMemberSourcePackageIdentifier[indexToAddChildrenUnder]];
            }

            // Record whether this member was unique (and added)
            result.WasMemberAdded[sourceMemberIndex] = hasUniqueDescendants;
            result.CurrentPath.Length = pathLength;
            return(hasUniqueDescendants);
        }
Пример #14
0
 public override string ToString()
 {
     return(_value.ToString());
 }
Пример #15
0
 private String8 DecodeBase64(String8 value)
 {
     // Horrible
     byte[] decoded = Convert.FromBase64String(value.ToString());
     return(_currentRowBlock.GetCopy(new String8(decoded, 0, decoded.Length)));
 }