/// <summary> /// Parse an ItemId's Id from a base64 string to a ItemIdId object according to the defined format /// </summary> /// <param name="itemId">An ItemIdType object</param> /// <returns>An ItemIdId object as the result of parsing</returns> public ItemIdId ParseItemId(ItemIdType itemId) { Site.Assert.IsNotNull(itemId, "The input itemId should not be null."); ItemIdId parsedId = new ItemIdId(); byte[] id = Convert.FromBase64String(itemId.Id); int currentIndex = 0; // [Byte] Compression Type parsedId.CompressionByte = id[currentIndex]; if (parsedId.CompressionByte == 1) { // The max length of Base64-encoded Id is 512, which is 512*3/4=384 after decoding // Then minus 1 (Compress Byte),which is 383 id = this.Decompress(id, 383).ToArray(); } else { currentIndex++; } // [Byte] Id Storage Type Site.Assert.IsTrue( Enum.IsDefined(typeof(IdStorageType), id[currentIndex]), "The id storage type should be valid. Actually the value is '{0}'.", id[currentIndex]); parsedId.StorageType = (IdStorageType)id[currentIndex]; currentIndex++; switch (parsedId.StorageType) { case IdStorageType.MailboxItemSmtpAddressBased: case IdStorageType.MailboxItemMailboxGuidBased: case IdStorageType.ConversationIdMailboxGuidBased: { parsedId.MonikerLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.MonikerBytes = new byte[(int)parsedId.MonikerLength]; Array.Copy(id, currentIndex, parsedId.MonikerBytes, 0, (int)parsedId.MonikerLength); currentIndex += (int)parsedId.MonikerLength; if (Enum.IsDefined(typeof(IdProcessingInstructionType), id[currentIndex])) { parsedId.IdProcessingInstruction = (IdProcessingInstructionType)id[currentIndex]; currentIndex++; } else { Site.Assert.Fail("Undefined Id Processing Instruction Type value {0}", id[currentIndex]); } parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.StoreId = new byte[parsedId.StoreIdLength]; Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength); currentIndex += parsedId.StoreIdLength; break; } case IdStorageType.PublicFolder: case IdStorageType.ActiveDirectoryObject: { parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.StoreId = new byte[parsedId.StoreIdLength]; Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength); currentIndex += parsedId.StoreIdLength; break; } case IdStorageType.PublicFolderItem: { if (Enum.IsDefined(typeof(IdProcessingInstructionType), id[currentIndex])) { parsedId.IdProcessingInstruction = (IdProcessingInstructionType)id[currentIndex]; currentIndex++; } else { Site.Assert.Fail("Undefined Id Processing Instruction Type value {0}", id[currentIndex]); } parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.StoreId = new byte[parsedId.StoreIdLength]; Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength); currentIndex += parsedId.StoreIdLength; parsedId.FolderIdLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.FolderId = new byte[(int)parsedId.FolderIdLength]; Array.Copy(id, currentIndex, parsedId.FolderId, 0, (int)parsedId.FolderIdLength); currentIndex += (int)parsedId.FolderIdLength; break; } default: { Site.Assert.Fail("No format defined for Id Storage Type {0}", parsedId.StorageType.ToString("g")); break; } } if (currentIndex < id.Length) { parsedId.AttachmentIdCount = id[currentIndex]; currentIndex++; short attachmentIdCount = Convert.ToInt16(parsedId.AttachmentIdCount); parsedId.AttachmentIds = new AttachmentId[attachmentIdCount]; for (int i = 0; i < attachmentIdCount; i++) { parsedId.AttachmentIds[i].AttachmentIdLength = BitConverter.ToInt16(id, currentIndex); currentIndex += 2; parsedId.AttachmentIds[i].Id = new byte[parsedId.AttachmentIds[i].AttachmentIdLength]; Array.Copy(id, currentIndex, parsedId.AttachmentIds[i].Id, 0, parsedId.AttachmentIds[i].AttachmentIdLength); currentIndex += parsedId.AttachmentIds[i].AttachmentIdLength; } } Site.Assert.AreEqual<int>(id.Length, currentIndex, "There should be no bytes left after parsing item id!"); return parsedId; }