Click here to Skip to main content
15,880,972 members
Articles / Desktop Programming / Win32

Windows Development in C++, Working with Menus

Rate me:
Please Sign up or sign in to vote.
4.96/5 (60 votes)
3 Jan 2015CPOL19 min read 171.5K   4.1K   163  
Windows API, menus, C++ lambda expressions, std::enable_shared_from_this
#pragma once
#ifndef __HWINBINARYWRITER_H__
#define __HWINBINARYWRITER_H__

#include "hwinDef.h"
#include "hwinException.h"
#include "hwinString.h"
#include "hwinDateTime.h"
#include "hwinGuid.h"
#include "hwinIO.h"
#include "hwinNullable.h"

#ifdef _MANAGED
#pragma managed(push,off)
#endif

#pragma pack(push,8)
namespace harlinn
{
    namespace windows
    {

        class BinaryWriter : public std::enable_shared_from_this < BinaryWriter >
        {
        protected:
            std::shared_ptr<StreamBase> OutStream;
        public:
            BinaryWriter( )
                : OutStream( std::make_shared<MemoryStream>( ) )
            {
            }

            BinaryWriter( const std::shared_ptr<StreamBase>& output )
                : OutStream( output )
            {
            }

            // Clears all buffers for this writer and causes any buffered data to be
            // written to the underlying device. 
            virtual void Flush( )
            {
                OutStream->Flush( );
            }

            /*
            * Returns the stream associate with the writer. It flushes all pending
            * writes before returning. All subclasses should override Flush to
            * ensure that all buffered data is sent to the stream.
            */
            virtual std::shared_ptr<StreamBase> BaseStream( )
            {
                Flush( );
                return OutStream;
            }

            virtual long long Seek( int offset, SeekOrigin origin )
            {
                return OutStream->Seek( offset, origin );
            }

            // Writes a boolean to this stream. A single byte is written to the stream 
            // with the value 0 representing false or the value 1 representing true. 
            virtual void Write( bool value )
            {
                byte buffer = ( byte )( value ? 1 : 0 );
                OutStream->Write( &buffer, 1 );
            }

            virtual void Write( const Nullable<bool>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a byte to this stream. The current position of the stream is
            // advanced by one. 
            virtual void Write( byte value )
            {
                OutStream->Write( &value, 1 );
            }

            virtual void Write( const Nullable<byte>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a signed byte to this stream. The current position of the stream 
            // is advanced by one.
            virtual void Write( char value )
            {
                OutStream->Write( &value, 1 );
            }

            virtual void Write( const Nullable<char>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a byte vector to this stream. 
            //
            // This default implementation calls the Write(Object, int, int) 
            // method to write the byte array.
            //
            virtual void Write( const std::vector<byte>& buffer )
            {
                OutStream->Write( buffer.data( ), buffer.size( ) );
            }

            virtual void Write( const Nullable<std::vector<byte>>& buffer )
            {
                bool hasValue = buffer.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( buffer.Value( ) );
                }
            }

            virtual void Write( const std::shared_ptr<std::vector<byte>>& buffer )
            {
                if ( buffer )
                {
                    Write( true );
                    Write( *buffer.get( ) );
                }
                else
                {
                    Write( false );
                }
            }



            // Writes a section of a byte vector to this stream.
            //
            // This default implementation calls the Write(Object, int, int)
            // method to write the byte array. 
            //
            virtual void Write( const std::vector<byte>& buffer, size_t index, size_t count )
            {
                auto ptr = buffer.data( );
                OutStream->Write( &ptr[index], count );
            }


            // Writes a wide character to this stream. The current position of the stream is
            // advanced by two.
            // Note this method cannot handle surrogates properly in UTF-8. 
            //
            virtual void Write( wchar_t ch )
            {
                OutStream->Write( &ch, 2 );
            }

            virtual void Write( const Nullable<wchar_t>& ch )
            {
                bool hasValue = ch.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( ch.Value( ) );
                }
            }

            // Writes a character array to this stream.
            //
            // This default implementation calls the Write(Object, int) 
            // method to write the character array.
            // 
            virtual void Write( const std::vector<wchar_t>& chars )
            {
                OutStream->Write( chars.data( ), chars.size( )*sizeof( wchar_t ) );
            }




            // Writes a section of a character array to this stream.
            // 
            // This default implementation calls the Write(Object, int, int)
            // method to write the character array.
            //
            virtual void Write( const std::vector<wchar_t>& chars, int index, int count )
            {
                auto ptr = chars.data( );
                OutStream->Write( &ptr[index], chars.size( )*sizeof( wchar_t ) );
            }




            // Writes a two-byte signed integer to this stream. The current position of
            // the stream is advanced by two. 
            virtual void Write( short value )
            {
                byte buffer[2];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                OutStream->Write( buffer, 2 );
            }

            virtual void Write( const Nullable<short>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a two-byte unsigned integer to this stream. The current position 
            // of the stream is advanced by two.
            virtual void Write( unsigned short value )
            {
                byte buffer[2];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                OutStream->Write( buffer, 2 );
            }


            virtual void Write( const Nullable<unsigned short>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }


            // Writes a four-byte signed integer to this stream. The current position
            // of the stream is advanced by four.
            // 
            virtual void Write( int value )
            {
                byte buffer[4];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                buffer[2] = ( byte )( value >> 16 );
                buffer[3] = ( byte )( value >> 24 );
                OutStream->Write( buffer, 4 );
            }

            virtual void Write( const Nullable<int>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a four-byte unsigned integer to this stream. The current position
            // of the stream is advanced by four. 
            virtual void Write( unsigned int value )
            {
                byte buffer[4];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                buffer[2] = ( byte )( value >> 16 );
                buffer[3] = ( byte )( value >> 24 );
                OutStream->Write( buffer, 4 );
            }


            virtual void Write( const Nullable<unsigned int>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes an eight-byte signed integer to this stream. The current position 
            // of the stream is advanced by eight.
            virtual void Write( long long value )
            {
                byte buffer[8];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                buffer[2] = ( byte )( value >> 16 );
                buffer[3] = ( byte )( value >> 24 );
                buffer[4] = ( byte )( value >> 32 );
                buffer[5] = ( byte )( value >> 40 );
                buffer[6] = ( byte )( value >> 48 );
                buffer[7] = ( byte )( value >> 56 );
                OutStream->Write( buffer, 8 );
            }


            virtual void Write( const Nullable<long long>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes an eight-byte unsigned integer to this stream. The current 
            // position of the stream is advanced by eight.
            virtual void Write( unsigned long long value )
            {
                byte buffer[8];
                buffer[0] = ( byte )value;
                buffer[1] = ( byte )( value >> 8 );
                buffer[2] = ( byte )( value >> 16 );
                buffer[3] = ( byte )( value >> 24 );
                buffer[4] = ( byte )( value >> 32 );
                buffer[5] = ( byte )( value >> 40 );
                buffer[6] = ( byte )( value >> 48 );
                buffer[7] = ( byte )( value >> 56 );
                OutStream->Write( buffer, 8 );
            }

            virtual void Write( const Nullable<unsigned long long>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a float to this stream. The current position of the stream is 
            // advanced by four. 
            virtual void Write( float value )
            {
                uint TmpValue = *( uint * )&value;
                byte buffer[4];
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                OutStream->Write( buffer, 4 );
            }

            virtual void Write( const Nullable<float>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }


            virtual void Write( const std::complex<float>& value )
            {
                auto real = value.real( );
                auto imag = value.imag( );
                uint TmpValue = *( uint * )&real;
                byte buffer[4];
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                OutStream->Write( buffer, 4 );

                TmpValue = *( uint * )&imag;
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                OutStream->Write( buffer, 4 );
            }

            virtual void Write( const Nullable<std::complex<float> >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }


            // Writes a double to this stream. The current position of the stream is
            // advanced by eight.
            virtual void Write( double value )
            {
                unsigned long long TmpValue = *( unsigned long long * ) &value;
                byte buffer[8];
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                buffer[4] = ( byte )( TmpValue >> 32 );
                buffer[5] = ( byte )( TmpValue >> 40 );
                buffer[6] = ( byte )( TmpValue >> 48 );
                buffer[7] = ( byte )( TmpValue >> 56 );
                OutStream->Write( &buffer, 8 );
            }

            virtual void Write( const Nullable< double >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            virtual void Write( std::complex<double> value )
            {
                auto real = value.real( );
                auto imag = value.imag( );

                unsigned long long TmpValue = *( unsigned long long * ) &real;
                byte buffer[8];
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                buffer[4] = ( byte )( TmpValue >> 32 );
                buffer[5] = ( byte )( TmpValue >> 40 );
                buffer[6] = ( byte )( TmpValue >> 48 );
                buffer[7] = ( byte )( TmpValue >> 56 );
                OutStream->Write( &buffer, 8 );

                TmpValue = *( unsigned long long * ) &imag;
                buffer[0] = ( byte )TmpValue;
                buffer[1] = ( byte )( TmpValue >> 8 );
                buffer[2] = ( byte )( TmpValue >> 16 );
                buffer[3] = ( byte )( TmpValue >> 24 );
                buffer[4] = ( byte )( TmpValue >> 32 );
                buffer[5] = ( byte )( TmpValue >> 40 );
                buffer[6] = ( byte )( TmpValue >> 48 );
                buffer[7] = ( byte )( TmpValue >> 56 );
                OutStream->Write( &buffer, 8 );
            }

            virtual void Write( const Nullable<std::complex<double> >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a Guid to this stream. The current position of the stream is 
            // advanced by sixteen. 
            virtual void Write( const Guid& value )
            {
                auto bytes = value.ToBytes( );
                OutStream->Write( bytes.data( ), 16 );
            }

            virtual void Write( const Nullable< Guid >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            // Writes a DateTime to this stream. The current position of the stream is 
            // advanced by eight. 
            virtual void Write( const DateTime& value )
            {
                auto ticks = value.Ticks( );

                byte buffer[8];
                buffer[0] = ( byte )ticks;
                buffer[1] = ( byte )( ticks >> 8 );
                buffer[2] = ( byte )( ticks >> 16 );
                buffer[3] = ( byte )( ticks >> 24 );
                buffer[4] = ( byte )( ticks >> 32 );
                buffer[5] = ( byte )( ticks >> 40 );
                buffer[6] = ( byte )( ticks >> 48 );
                buffer[7] = ( byte )( ticks >> 56 );
                OutStream->Write( buffer, 8 );
            }

            virtual void Write( const Nullable< DateTime >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }


            // Writes a TimeSpan to this stream. The current position of the stream is 
            // advanced by eight. 
            virtual void Write( const TimeSpan& value )
            {
                auto ticks = value.Ticks( );

                byte buffer[8];
                buffer[0] = ( byte )ticks;
                buffer[1] = ( byte )( ticks >> 8 );
                buffer[2] = ( byte )( ticks >> 16 );
                buffer[3] = ( byte )( ticks >> 24 );
                buffer[4] = ( byte )( ticks >> 32 );
                buffer[5] = ( byte )( ticks >> 40 );
                buffer[6] = ( byte )( ticks >> 48 );
                buffer[7] = ( byte )( ticks >> 56 );
                OutStream->Write( buffer, 8 );
            }

            virtual void Write( const Nullable< TimeSpan >& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }


        protected:
            // Write out an int 7 bits at a time.  The high bit of the byte,
            // when on, tells reader to continue reading more bytes. 
            void Write7BitEncodedInt( int value )
            {
                // support negative numbers
                uint v = ( uint )value;
                while ( v >= 0x80 )
                {
                    Write( ( byte )( v | 0x80 ) );
                    v >>= 7;
                }
                Write( ( byte )v );
            }
        public:
            // Writes a length-prefixed string to this stream in the BinaryWriter's
            // current Encoding. This method first writes the length of the string as 
            // a four-byte unsigned integer, and then writes that many characters
            // to the stream. 
            virtual void Write( const AnsiString& value )
            {
                int len = static_cast< int >( value.Length( ) );
                Write7BitEncodedInt( len );
                if ( len )
                {
                    OutStream->Write( value.c_str( ), size_t( len ) );
                }
            }

            // Writes a length-prefixed string to this stream in the BinaryWriter's
            // current Encoding. This method first writes the length of the string as 
            // a four-byte unsigned integer, and then writes that many characters
            // to the stream. 
            virtual void Write( const WideString& value )
            {
                auto converted = AnsiString::From( value );
                Write( converted );
            }


            virtual void WriteArray( const std::vector<bool>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer = ( byte )( value ? 1 : 0 );
                    OutStream->Write( &buffer, 1 );
                }
            }

            virtual void WriteArray( const std::vector<char>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    OutStream->Write( &value, 1 );
                }
            }

            virtual void WriteArray( const std::vector<unsigned char>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    OutStream->Write( &value, 1 );
                }
            }

            virtual void WriteArray( const std::vector<short>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[2];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    OutStream->Write( &buffer, 2 );
                }
            }

            virtual void WriteArray( const std::vector<unsigned short>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[2];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    OutStream->Write( &buffer, 2 );
                }
            }

            virtual void WriteArray( const std::vector<int>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[4];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    buffer[2] = ( byte )( value >> 16 );
                    buffer[3] = ( byte )( value >> 24 );
                    OutStream->Write( buffer, 4 );
                }
            }

            virtual void WriteArray( const std::vector<unsigned int>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[4];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    buffer[2] = ( byte )( value >> 16 );
                    buffer[3] = ( byte )( value >> 24 );
                    OutStream->Write( buffer, 4 );
                }
            }

            virtual void WriteArray( const std::vector<long long>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[8];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    buffer[2] = ( byte )( value >> 16 );
                    buffer[3] = ( byte )( value >> 24 );
                    buffer[4] = ( byte )( value >> 32 );
                    buffer[5] = ( byte )( value >> 40 );
                    buffer[6] = ( byte )( value >> 48 );
                    buffer[7] = ( byte )( value >> 56 );
                    OutStream->Write( buffer, 8 );
                }
            }

            virtual void WriteArray( const std::vector<unsigned long long>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    byte buffer[8];
                    buffer[0] = ( byte )value;
                    buffer[1] = ( byte )( value >> 8 );
                    buffer[2] = ( byte )( value >> 16 );
                    buffer[3] = ( byte )( value >> 24 );
                    buffer[4] = ( byte )( value >> 32 );
                    buffer[5] = ( byte )( value >> 40 );
                    buffer[6] = ( byte )( value >> 48 );
                    buffer[7] = ( byte )( value >> 56 );
                    OutStream->Write( buffer, 8 );
                }
            }

            virtual void WriteArray( const std::vector<float>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    uint TmpValue = *( uint * )&value;
                    byte buffer[4];
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    OutStream->Write( buffer, 4 );
                }
            }

            virtual void WriteArray( const std::vector<double>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    unsigned long long TmpValue = *( unsigned long long * ) &value;
                    byte buffer[8];
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    buffer[4] = ( byte )( TmpValue >> 32 );
                    buffer[5] = ( byte )( TmpValue >> 40 );
                    buffer[6] = ( byte )( TmpValue >> 48 );
                    buffer[7] = ( byte )( TmpValue >> 56 );
                    OutStream->Write( &buffer, 8 );
                }
            }


            virtual void WriteArray( const std::vector<std::complex<float>>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto& value : values )
                {
                    auto real = value.real( );
                    auto imag = value.imag( );

                    uint TmpValue = *( uint * )&real;
                    byte buffer[4];
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    OutStream->Write( buffer, 4 );

                    TmpValue = *( uint * )&imag;
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    OutStream->Write( buffer, 4 );
                }
            }

            virtual void WriteArray( const std::vector<std::complex<double>>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto& value : values )
                {
                    auto real = value.real( );
                    auto imag = value.imag( );

                    unsigned long long TmpValue = *( unsigned long long * ) &real;
                    byte buffer[8];
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    buffer[4] = ( byte )( TmpValue >> 32 );
                    buffer[5] = ( byte )( TmpValue >> 40 );
                    buffer[6] = ( byte )( TmpValue >> 48 );
                    buffer[7] = ( byte )( TmpValue >> 56 );
                    OutStream->Write( &buffer, 8 );

                    TmpValue = *( unsigned long long * ) &imag;
                    buffer[0] = ( byte )TmpValue;
                    buffer[1] = ( byte )( TmpValue >> 8 );
                    buffer[2] = ( byte )( TmpValue >> 16 );
                    buffer[3] = ( byte )( TmpValue >> 24 );
                    buffer[4] = ( byte )( TmpValue >> 32 );
                    buffer[5] = ( byte )( TmpValue >> 40 );
                    buffer[6] = ( byte )( TmpValue >> 48 );
                    buffer[7] = ( byte )( TmpValue >> 56 );
                    OutStream->Write( &buffer, 8 );
                }
            }

            virtual void WriteArray( const std::vector<DateTime>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    auto ticks = value.Ticks( );

                    byte buffer[8];
                    buffer[0] = ( byte )ticks;
                    buffer[1] = ( byte )( ticks >> 8 );
                    buffer[2] = ( byte )( ticks >> 16 );
                    buffer[3] = ( byte )( ticks >> 24 );
                    buffer[4] = ( byte )( ticks >> 32 );
                    buffer[5] = ( byte )( ticks >> 40 );
                    buffer[6] = ( byte )( ticks >> 48 );
                    buffer[7] = ( byte )( ticks >> 56 );
                    OutStream->Write( buffer, 8 );
                }
            }

            virtual void WriteArray( const std::vector<TimeSpan>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    auto ticks = value.Ticks( );

                    byte buffer[8];
                    buffer[0] = ( byte )ticks;
                    buffer[1] = ( byte )( ticks >> 8 );
                    buffer[2] = ( byte )( ticks >> 16 );
                    buffer[3] = ( byte )( ticks >> 24 );
                    buffer[4] = ( byte )( ticks >> 32 );
                    buffer[5] = ( byte )( ticks >> 40 );
                    buffer[6] = ( byte )( ticks >> 48 );
                    buffer[7] = ( byte )( ticks >> 56 );
                    OutStream->Write( buffer, 8 );
                }
            }

            virtual void WriteArray( const std::vector<AnsiString>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    int len = static_cast< int >( value.Length( ) );
                    Write7BitEncodedInt( len );
                    if ( len )
                    {
                        OutStream->Write( value.c_str( ), size_t( len ) );
                    }
                }
            }

            virtual void WriteArray( const std::vector<WideString>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    auto converted = AnsiString::From( value );
                    Write( converted );
                }
            }

            virtual void WriteArray( const std::vector<Guid>& values )
            {
                auto size = static_cast< int >( values.size( ) );
                OutStream->Write( &size, sizeof( size ) );
                for ( auto value : values )
                {
                    auto bytes = value.ToBytes( );
                    OutStream->Write( bytes.data( ), 16 );
                }
            }

            template<typename T>
            void Write( const Nullable<std::vector<T>>& value )
            {
                bool hasValue = value.HasValue( );
                Write( hasValue );
                if ( hasValue )
                {
                    Write( value.Value( ) );
                }
            }

            template<typename T>
            void Write( const std::shared_ptr<std::vector<T>>& value )
            {
                if ( value )
                {
                    Write( true );
                    Write( *value.get( ) );
                }
                else
                {
                    Write( false );
                }
            }


        };



    }
}
#pragma pack(pop)

#ifdef _MANAGED
#pragma managed(pop)
#endif

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Sea Surveillance AS
Norway Norway
Chief Architect - Sea Surveillance AS.

Specializing in integrated operations and high performance computing solutions.

I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.

Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...

A few Highlights:

  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI


More information about what I do for a living can be found at: harlinn.com or LinkedIn

You can contact me at espen@harlinn.no

Comments and Discussions