/// <summary>
/// The sample function demonstrating how to get WPD data from items uploaded to HealthVault
/// by v1.x (old behavior) and by v 2.x client (new behavior).
/// It accesses first self-record in the account associated with the AuthenticatedConnection object,
/// retrieves all items of weight type and retrieves WPD data if exist
/// </summary>
/// <param name="authenticatedConnection"></param>
private void SampleWorkingWithWpdData(AuthenticatedConnection authenticatedConnection)
{
// getting a first self-record ID
Guid recordId = authenticatedConnection.GetPersonInfo().GetSelfRecord().Id;
HealthRecordAccessor healthRecordAccessor = new HealthRecordAccessor(authenticatedConnection, recordId);
// retrieve all items of the weight type for this record
HealthRecordItemCollection healthRecordItemCollection = healthRecordAccessor.GetItemsByType(Health.ItemTypes.Weight.TypeId, HealthRecordItemSections.Xml);
// loop through each healthRecordItem
foreach (HealthRecordItem healthRecordItem in healthRecordItemCollection)
{
string itemXml = healthRecordItem.GetItemXml();
if (healthRecordItem.CommonData != null &&
healthRecordItem.CommonData.Extensions != null)
{
// create variable to contain WPD data
string dataWpd = string.Empty;
// going through each Extension in HealthRecordItem and proceed if it has WPD data
foreach (HealthRecordItemExtension healthRecordItemExtension in healthRecordItem.CommonData.Extensions)
{
if (string.Compare(healthRecordItemExtension.Source, "WPD", true) == 0) // the item has WPD extension
{
// old behavior:WPD data contained in healthRecordItemExtension.ExtensionData.
if (healthRecordItemExtension.ExtensionData != null)
{
dataWpd = healthRecordItemExtension.ExtensionData.CreateNavigator().InnerXml;
}
// Now if the healthRecordItemExtension.ExtensionData is missing, it's a new data model where
//we retrieve WPD compressed data from OtherData:
else
{
HealthRecordItem healthRecordItemDataOther = healthRecordAccessor.GetItem(healthRecordItem.Key.Id, HealthRecordItemSections.OtherData);
if (string.Compare(healthRecordItemDataOther.OtherData.ContentEncoding, "base64", true) == 0 ||
string.Compare(healthRecordItemDataOther.OtherData.ContentEncoding, "base-64", true) == 0)
{
// converting base64 zipped items to string
dataWpd = Base64GZipTextToString(healthRecordItemDataOther.OtherData.Data);
}
}
break;
}
}
if(!string.IsNullOrEmpty(dataWpd))
{
// do something with WPD data
}
}
}
}
/// <summary>
/// Decodes string from base 64 and decodes it using GZip decompression
/// </summary>
/// <param name="source"></param>
/// <returns>Decoded from base-64 and decompressed string</returns>
private string Base64GZipTextToString(string source)
{
// verify argument
if (string.IsNullOrEmpty(source))
{
throw new ArgumentNullException("source","Parameter cannot be null or empty");
}
// convert the string to Unicode bytes
byte[] srcBuffer = Convert.FromBase64String(source);
_compressedBufferSize = srcBuffer.Length;
using(MemoryStream memoryStream = new MemoryStream())
{
// compress the buffer
memoryStream.Write(
srcBuffer,
0,
srcBuffer.Length);
// reset the memory stream to read the decompressed data
memoryStream.Position = 0;
System.IO.Compression.GZipStream decompression =
new System.IO.Compression.GZipStream(
memoryStream,
System.IO.Compression.CompressionMode.Decompress);
byte[] decompressedBytes = ReadAllBytesFromStream(decompression);
_decompressedBufferSize = decompressedBytes.Length;
// reading compressed buffer back
//decompression.Read(decompressedBytes, 0, decompressedBytes.Length);
decompression.Close();
return System.Text.Encoding.UTF8.GetString(decompressedBytes);
}
}
private const int buffer_size = 100;
private static byte[] ReadAllBytesFromStream(System.IO.Compression.GZipStream stream)
{
// Use this method is used to read all bytes from a stream.
int buffer_size = 100;
byte[] buffer = new byte[buffer_size];
using (MemoryStream memoryStream = new MemoryStream())
{
while (true)
{
int bytesRead = stream.Read(buffer, 0, buffer_size);
if (bytesRead == 0)
{
break;
}
memoryStream.Write(buffer, 0, bytesRead);
}
// reset the buffer to read the data
memoryStream.Position = 0;
byte[] newbuffer = new byte[memoryStream.Length];
memoryStream.Read(newbuffer,0,newbuffer.Length);
return newbuffer;
}
}