/// <summary> /// Creates this object and sets all it's needed properties /// </summary> /// <param name="nameIdentifierOrStringOffset"><see cref="NameIdentifierOrStringOffset"/></param> /// <param name="indexAndKindInformation"><see cref="IndexAndKindInformation"/></param> internal EntryStreamItem(ushort nameIdentifierOrStringOffset, IndexAndKindInformation indexAndKindInformation) { NameIdentifierOrStringOffset = nameIdentifierOrStringOffset; NameIdentifierOrStringOffsetHex = $"{nameIdentifierOrStringOffset:X}"; IndexAndKindInformation = indexAndKindInformation; }
/// <summary> /// Creates this object and sets all it's needed properties /// </summary> /// <param name="nameIdentifierOrStringOffset"><see cref="NameIdentifierOrStringOffset"/></param> /// <param name="indexAndKindInformation"><see cref="IndexAndKindInformation"/></param> internal EntryStreamItem(ushort nameIdentifierOrStringOffset, IndexAndKindInformation indexAndKindInformation) { NameIdentifierOrStringOffset = nameIdentifierOrStringOffset; NameIdentifierOrStringOffsetHex = string.Format("{0:X}", nameIdentifierOrStringOffset); IndexAndKindInformation = indexAndKindInformation; }
/// <summary> /// Writes the properties to the <see cref="CFStorage" /> /// </summary> /// <param name="storage"></param> /// <param name="messageSize"></param> /// <remarks> /// Unfortunately this is going to have to be used after we already written the top level properties. /// </remarks> internal void WriteProperties(CFStorage storage, long messageSize = 0) { // Grab the nameIdStorage, 3.1 on the SPEC storage = storage.GetStorage(PropertyTags.NameIdStorage); var entryStream = new EntryStream(storage); var stringStream = new StringStream(storage); var guidStream = new GuidStream(storage); var nameIdMappingStream = new EntryStream(storage); ushort propertyIndex = 0; foreach (var guid in Guids.Where(g => g != PropertySets.PS_MAPI && g != PropertySets.PS_PUBLIC_STRINGS)) { guidStream.Add(guid); } foreach (var namedProperty in this) { var guidIndex = GetGuidIndex(namedProperty); var indexAndKind = new IndexAndKindInformation(propertyIndex, guidIndex, namedProperty.Kind); if (namedProperty.Kind == PropertyKind.Name) { var stringStreamItem = new StringStreamItem(namedProperty.Name); stringStream.Add(stringStreamItem); entryStream.Add(new EntryStreamItem(stringStream.GetItemByteOffset(stringStreamItem), indexAndKind)); } else { entryStream.Add(new EntryStreamItem(namedProperty.NameIdentifier, indexAndKind)); } nameIdMappingStream.Add(new EntryStreamItem(GenerateNameIdentifier(namedProperty), indexAndKind)); nameIdMappingStream.Write(storage, GenerateStreamName(namedProperty)); // Dependign on the property type. This is doing name. //entryStream.Add(new EntryStreamItem(namedProperty.NameIdentifier, new IndexAndKindInformation(propertyIndex, guidIndex, PropertyKind.Lid))); //+3 as per spec. //entryStream2.Add(new EntryStreamItem(namedProperty.NameIdentifier, new IndexAndKindInformation(propertyIndex, guidIndex, PropertyKind.Lid))); // 3.2.2 of the SPEC Needs to be written, because the stream changes as per named object. nameIdMappingStream.Clear(); propertyIndex++; } guidStream.Write(storage); entryStream.Write(storage); stringStream.Write(storage); }
/// <summary> /// Creates this object and reads all the properties from the given <paramref name="binaryReader" /> /// </summary> /// <param name="binaryReader">The <see cref="BinaryReader"/></param> internal EntryStreamItem(BinaryReader binaryReader) { NameIdentifierOrStringOffset = binaryReader.ReadUInt16(); NameIdentifierOrStringOffsetHex = $"{NameIdentifierOrStringOffset:X}"; IndexAndKindInformation = new IndexAndKindInformation(binaryReader); }