Helper class that holds the internal state used to parse tuples from slices
                public override FdbTuple <T1, T2> DecodeComposite(Slice encoded, int count)
                {
                    Contract.Requires(count > 0);

                    var reader = new SliceReader(encoded);
                    T1  key1   = default(T1);
                    T2  key2   = default(T2);

                    if (count >= 1)
                    {
                        key1 = m_codec1.DecodeOrderedSelfTerm(ref reader);
                    }
                    if (count >= 2)
                    {
                        key2 = m_codec2.DecodeOrderedSelfTerm(ref reader);
                    }
                    if (reader.HasMore)
                    {
                        throw new InvalidOperationException(String.Format("Unexpected data at the end of composite key after {0} items", count));
                    }
                    return(FdbTuple.Create <T1, T2>(key1, key2));
                }
		public void Test_Simple_SelfTerms_Codecs()
		{
			// encodes a key using 3 parts: (x, y, z) => ordered_key

			string x = "abc";
			long y = 123;
			Guid z = Guid.NewGuid();

			var first = FdbTupleCodec<string>.Default;
			var second = FdbTupleCodec<long>.Default;
			var third = FdbTupleCodec<Guid>.Default;

			var writer = SliceWriter.Empty;
			first.EncodeOrderedSelfTerm(ref writer, x);
			second.EncodeOrderedSelfTerm(ref writer, y);
			third.EncodeOrderedSelfTerm(ref writer, z);
			var data = writer.ToSlice();
			Assert.That(data, Is.EqualTo(FdbTuple.EncodeKey(x, y, z)));

			var reader = new SliceReader(data);
			Assert.That(first.DecodeOrderedSelfTerm(ref reader), Is.EqualTo(x));
			Assert.That(second.DecodeOrderedSelfTerm(ref reader), Is.EqualTo(y));
			Assert.That(third.DecodeOrderedSelfTerm(ref reader), Is.EqualTo(z));
			Assert.That(reader.HasMore, Is.False);
		}
Пример #3
0
		/// <summary>Outputs a debug version of a compressed segment</summary>
		public static StringBuilder DumpCompressed(Slice compressed, StringBuilder output = null)
		{
			if (output == null) output = new StringBuilder();

			if (compressed.Count == 0)
			{
				output.Append("Empty bitmap [0 bytes]");
				return output;
			}

			var reader = new SliceReader(compressed);

			output.Append(String.Format("Compressed [{0} bytes]:", compressed.Count));

			uint header = reader.ReadFixed32();
			int highestBit = (int)header;
			output.Append(String.Format(" {0} words", (compressed.Count >> 2) - 1));

			uint p = 0;
			int i = 0;
			while(reader.Remaining >= 4)
			{
				uint word = reader.ReadFixed32();
				if ((word & TYPE_MASK) == BIT_TYPE_LITERAL)
				{
					output.AppendFormat(", ({0}:{1}) 0x{2:X8}", i, p, word);
					p += 31;
				}
				else
				{
					uint len = (word & LENGTH_MASK) + 1;
					output.AppendFormat(", ({0}:{1}) {2} x {3}", i, p, ((word & FILL_MASK) >> FILL_SHIFT) == 0 ? "zero" : "one", len);
					p += len * 31;
				}
				i++;
			}
			output.Append(", MSB ").Append(highestBit);
			if (reader.Remaining > 0)
			{
				output.AppendLine(String.Format(", ERROR: {0} trailing byte(s)", reader.Remaining));
			}
			return output;
		}
        public virtual T DecodeUnordered(Slice input)
        {
            var reader = new SliceReader(input);

            return(DecodeUnorderedSelfTerm(ref reader));
        }
		private static void CheckVersion(Slice value, bool writeAccess)
		{
			// the version is stored as 3 x 32-bit unsigned ints, so (1, 0, 0) will be "<01><00><00><00> <00><00><00><00> <00><00><00><00>"
			var reader = new SliceReader(value);
			var major = reader.ReadFixed32();
			var minor = reader.ReadFixed32();
			var upgrade = reader.ReadFixed32();

			if (major > LayerVersion.Major) throw new InvalidOperationException(String.Format("Cannot load directory with version {0}.{1}.{2} using directory layer {3}", major, minor, upgrade, LayerVersion));
			if (writeAccess && minor > LayerVersion.Minor) throw new InvalidOperationException(String.Format("Directory with version {0}.{1}.{2} is read-only when opened using directory layer {3}", major, minor, upgrade, LayerVersion));
		}
 public virtual T DecodeUnorderedSelfTerm(ref SliceReader input)
 {
     return(DecodeOrderedSelfTerm(ref input));
 }
 public abstract T DecodeOrderedSelfTerm(ref SliceReader input);
		public TupleReader(SliceReader input)
		{
			this.Input = input;
			this.Depth = 0;
		}
		public TupleReader(Slice buffer)
		{
			this.Input = new SliceReader(buffer);
			this.Depth = 0;
		}
		/// <summary>Decode the next token from a packed tuple</summary>
		/// <param name="reader">Parser from wich to read the next token</param>
		/// <returns>Token decoded, or Slice.Nil if there was no more data in the buffer</returns>
		public static Slice ParseNext(ref SliceReader reader)
		{
			int type = reader.PeekByte();
			switch (type)
			{
				case -1:
				{ // End of Stream
					return Slice.Nil;
				}

				case FdbTupleTypes.Nil:
				{ // <00> => null
					reader.Skip(1);
					return Slice.Empty;
				}

				case FdbTupleTypes.Bytes:
				{ // <01>(bytes)<00>
					return reader.ReadByteString();
				}

				case FdbTupleTypes.Utf8:
				{ // <02>(utf8 bytes)<00>
					return reader.ReadByteString();
				}

				case FdbTupleTypes.Single:
				{ // <20>(4 bytes)
					return reader.ReadBytes(5);
				}

				case FdbTupleTypes.Double:
				{ // <21>(8 bytes)
					return reader.ReadBytes(9);
				}

				case FdbTupleTypes.Uuid128:
				{ // <30>(16 bytes)
					return reader.ReadBytes(17);
				}

				case FdbTupleTypes.Uuid64:
				{ // <31>(8 bytes)
					return reader.ReadBytes(9);
				}

				case FdbTupleTypes.AliasDirectory:
				case FdbTupleTypes.AliasSystem:
				{ // <FE> or <FF>
					return reader.ReadBytes(1);
				}
			}

			if (type <= FdbTupleTypes.IntPos8 && type >= FdbTupleTypes.IntNeg8)
			{
				int bytes = type - FdbTupleTypes.IntZero;
				if (bytes < 0) bytes = -bytes;

				return reader.ReadBytes(1 + bytes);
			}

			throw new FormatException(String.Format("Invalid tuple type byte {0} at index {1}/{2}", type, reader.Position, reader.Buffer.Count));
		}