www.pudn.com > Proximity-sample.zip > CppSamplesUtils.h, change:2012-06-01,size:11845b


//********************************************************* 
// 
// Copyright (c) Microsoft. All rights reserved. 
// This code is licensed under the Microsoft Public License. 
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 
// 
//********************************************************* 
 
#pragma once 
 
#include <string> 
#include <sstream> 
#include <algorithm> 
#include <collection.h> 
#include <ppltasks.h> 
 
namespace CppSamplesUtils 
{ 
    namespace Details 
    { 
        static Windows::Foundation::Collections::PropertySet^ sessionState = nullptr; 
        static Platform::String^ sessionStateFileName = ref new Platform::String(L"_cppSessionState.xml"); 
 
        concurrency::task<void> SerializeSessionState(Windows::Storage::IStorageFile^ file); 
        concurrency::task<void> DeserializeSessionState(Windows::Storage::IStorageFile^ file); 
    } 
 
    class SuspensionManager 
    { 
    public: 
        static Windows::Foundation::Collections::PropertySet^ SessionState() 
        { 
            using namespace Windows::Foundation::Collections; 
            using namespace Details; 
 
            if (sessionState == nullptr) 
            { 
                sessionState = ref new PropertySet(); 
            } 
            return sessionState; 
        } 
 
        static concurrency::task<void> StartRestoreTask() 
        { 
            using namespace Windows::Foundation; 
            using namespace Windows::Storage; 
            using namespace Windows::Storage::Streams; 
            using namespace Details; 
 
            auto state = SessionState(); 
            state->Clear(); 
 
            concurrency::task<StorageFile^> getFileTask(ApplicationData::Current->LocalFolder->GetFileAsync(sessionStateFileName)); 
            return getFileTask.then([=](StorageFile^ file) 
            { 
                return DeserializeSessionState(file); 
            }); 
        } 
 
        static concurrency::task<void> StartSaveTask() 
        { 
            using namespace Windows::Foundation; 
            using namespace Windows::Storage; 
            using namespace Windows::Storage::Streams; 
            using namespace Details; 
 
            concurrency::task<StorageFile^> createFileTask(ApplicationData::Current->LocalFolder->CreateFileAsync(sessionStateFileName, CreationCollisionOption::ReplaceExisting)); 
            return createFileTask.then([=](StorageFile^ file) 
            { 
                return SerializeSessionState(file); 
            }); 
        } 
    }; 
 
    namespace Details 
    { 
        template <class T> 
        inline Platform::String^ ToString(T value) 
        { 
            std::wstringstream wss; 
            wss << value; 
            return ref new Platform::String(wss.str().c_str()); 
        } 
 
        template <class T> 
        inline T FromStringTo(Platform::String^ str) 
        { 
            std::wistringstream wiss(str->Data()); 
            T value = 0; 
            wiss >> value; 
            return value; 
        } 
 
        template <class T> 
        inline T FromHexStringTo(Platform::String^ str) 
        { 
            std::wistringstream wiss(str->Data()); 
            T value = 0; 
            wiss >> std::hex >> value; 
            return value; 
        } 
 
        template <> 
        inline Platform::Guid FromStringTo<Platform::Guid>(Platform::String^ str) 
        { 
            using namespace Platform; 
 
            if (str->Length() != 38) 
            { 
                throw ref new InvalidArgumentException; 
            } 
            std::wstring ws(str->Data()); 
            if (ws[0] != L'{' || ws[37] != L'}' || ws[9] != L'-' || ws[14] != L'-' || ws[19] != L'-' || ws[24] != L'-') 
            { 
                throw ref new InvalidArgumentException; 
            } 
            ws[0] = ws[37] = ws[9] = ws[14] = ws[19] =ws[24] = L' '; 
            std::wistringstream wiss(ws); 
            unsigned int a = 0; 
            unsigned short b = 0; 
            unsigned short c = 0; 
            unsigned short d = 0; 
            unsigned long long e = 0; 
            static_assert(sizeof(d) == sizeof(char) * 2, "sizeof(d) == sizeof(char) * 2"); 
            static_assert(sizeof(e) == sizeof(char) * 8, "sizeof(e) == sizeof(char) * 8"); 
            wiss >> std::hex >> a >> b >> c >> d >> e; 
            unsigned char *ad = (unsigned char*)(&d); 
            unsigned char *ae = (unsigned char*)(&e); 
            return Platform::Guid(a, b, c, ad[1], ad[0], ae[5], ae[4], ae[3], ae[2], ae[1], ae[0]); 
        } 
 
        inline Platform::Object^ ConvertStringToObject(Windows::Foundation::PropertyType type, Platform::String^ str) 
        { 
            using namespace Platform; 
            using namespace Windows::Foundation; 
 
            if (type == PropertyType::String) 
            { 
                return PropertyValue::CreateString(str); 
            } 
 
            switch (type) 
            { 
            case PropertyType::UInt8: 
                return PropertyValue::CreateUInt8((unsigned char)FromStringTo<unsigned short>(str)); 
            case PropertyType::UInt16: 
                return PropertyValue::CreateUInt16(FromStringTo<unsigned short>(str)); 
            case PropertyType::UInt32: 
                return PropertyValue::CreateUInt32(FromStringTo<unsigned int>(str)); 
            case PropertyType::UInt64: 
                return PropertyValue::CreateUInt64(FromStringTo<unsigned long long>(str)); 
            case PropertyType::Int16: 
                return PropertyValue::CreateInt16(FromStringTo<short>(str)); 
            case PropertyType::Int32: 
                return PropertyValue::CreateInt32(FromStringTo<int>(str)); 
            case PropertyType::Int64: 
                return PropertyValue::CreateInt64(FromStringTo<long long>(str)); 
            case PropertyType::Single: 
                return PropertyValue::CreateSingle(FromStringTo<float>(str)); 
            case PropertyType::Double: 
                return PropertyValue::CreateDouble(FromStringTo<double>(str)); 
            case PropertyType::Boolean: 
                return PropertyValue::CreateBoolean(FromStringTo<bool>(str)); 
            case PropertyType::Char16: 
                return PropertyValue::CreateChar16(str->Data()[0]); 
            case PropertyType::Guid: 
                return PropertyValue::CreateGuid(FromStringTo<Guid>(str)); 
            default: 
                throw ref new Platform::InvalidCastException; 
            } 
        } 
 
        inline Platform::String^ ConvertPropertyValueToString(Windows::Foundation::IPropertyValue^ pv) 
        { 
            using namespace Platform; 
            using namespace Windows::Foundation; 
 
            String^ valueString; 
 
            switch (pv->Type) 
            { 
            case PropertyType::String: 
                valueString = pv->GetString(); 
                break; 
 
            case PropertyType::UInt8: 
            case PropertyType::UInt16: 
            case PropertyType::UInt32: 
            case PropertyType::UInt64: 
                valueString = ToString(pv->GetUInt64()); 
                break; 
 
            case PropertyType::Int16: 
            case PropertyType::Int32: 
            case PropertyType::Int64: 
                valueString = ToString(pv->GetInt64()); 
                break; 
 
            case PropertyType::Single: 
                valueString = ToString(pv->GetSingle()); 
                break; 
 
            case PropertyType::Double: 
                valueString = ToString(pv->GetDouble()); 
                break; 
 
            case PropertyType::Boolean: 
                valueString = ToString(pv->GetBoolean()); 
                break; 
 
            case PropertyType::Char16: 
                wchar_t buffer[2]; 
                buffer[0] = pv->GetChar16(); 
                buffer[1] = 0; 
                valueString = ref new String(buffer); 
                break; 
 
            case PropertyType::Guid: 
                valueString = pv->GetGuid().ToString(); 
                break; 
 
            default: 
                throw ref new InvalidCastException; 
            } 
 
            return valueString; 
        } 
 
        inline Windows::Data::Xml::Dom::XmlElement^ CreateXmlElementFromObject(Windows::Data::Xml::Dom::XmlDocument^ doc, Platform::String^ name, Platform::Object^ value) 
        { 
            using namespace Platform; 
            using namespace Windows::Foundation; 
            using namespace Windows::Data::Xml::Dom; 
 
            XmlElement^ element = doc->CreateElement("item"); 
            element->SetAttribute("name", name); 
 
            IPropertyValue^ pv = (IPropertyValue^)value; 
            element->SetAttribute("type", ToString((int)pv->Type)); 
            element->SetAttribute("value", ConvertPropertyValueToString(pv)); 
 
            return element; 
        } 
 
        inline concurrency::task<void> SerializeSessionState(Windows::Storage::IStorageFile^ file) 
        { 
            using namespace Windows::Data::Xml::Dom; 
            using namespace Windows::Foundation; 
            namespace WFC = Windows::Foundation::Collections; 
            typedef Windows::Foundation::Collections::IKeyValuePair<Platform::String^, Platform::Object^> KVPair; 
 
            XmlDocument^ doc = ref new XmlDocument; 
            doc->AppendChild(doc->CreateElement("items")); 
            auto sessionState = SuspensionManager::SessionState(); 
 
            std::for_each(WFC::begin(sessionState), WFC::end(sessionState), [doc](KVPair^ item) 
            { 
                doc->DocumentElement->AppendChild(CreateXmlElementFromObject(doc, item->Key, item->Value)); 
            }); 
 
            return concurrency::task<void>(doc->SaveToFileAsync(file)); 
        } 
 
        inline Windows::Foundation::PropertyType PropertyTypeFromString(Platform::String^ str) 
        { 
            int value = FromStringTo<int>(str); 
            return (Windows::Foundation::PropertyType)value; 
        } 
 
        inline concurrency::task<void> DeserializeSessionState(Windows::Storage::IStorageFile^ file) 
        { 
            using namespace Platform; 
            using namespace Windows::Foundation; 
            using namespace Windows::Data::Xml::Dom; 
            namespace WFC = Windows::Foundation::Collections; 
 
            concurrency::task<XmlDocument^> loadFileTask(XmlDocument::LoadFromFileAsync(file)); 
            return loadFileTask.then([=](concurrency::task<XmlDocument^> docTask) 
            { 
                try 
                { 
                    auto doc = docTask.get(); 
                    auto items = doc->SelectNodes("/items/item"); 
                    auto sessionState = SuspensionManager::SessionState(); 
 
                    std::for_each(WFC::begin(items), WFC::end(items), [sessionState](IXmlNode^ node) 
                    { 
                        auto element = (IXmlElement^)node; 
                        String^ name = element->GetAttribute("name"); 
                        String^ value = element->GetAttribute("value"); 
                        PropertyType type = PropertyTypeFromString(element->GetAttribute("type")); 
 
                        Object^ valueObject = ConvertStringToObject(type, value); 
                        sessionState->Insert(name, valueObject); 
                    }); 
 
                } 
                catch (Platform::Exception^) 
                { 
                    // Restoring is best effort 
                } 
            }); 
        } 
    } // namespace Details 
} // namespace CppSamplesUtils