Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1456 chris 1
using System;
2
using System.IO;
3
using System.Linq;
4
using System.Text;
5
 
6
 
7
 
8
namespace EndianHandling
9
{
10
    public class EndianBinaryWriter
11
    {
12
        /* ===[ Notes ]====================================================== */
13
 
14
        /* If there is a discrepency between the system's endianness and the
15
         * requested operation, reverse the bytes where needed. In cases where
16
         * the system's endianness is the requested mode, take no action. The
17
         * following table illustrates when byte reversals are made:
18
         *
19
         * +-----------------------------+-------------+---------+
20
         * | BitConverter.IsLittleEndian | this.bigEnd | Action  |
21
         * +-----------------------------+-------------+---------+
22
         * | True                        | True        | Reverse |
23
         * | True                        | False       | None    |
24
         * | False                       | True        | None    |
25
         * | False                       | False       | Reverse |
26
         * +-----------------------------+-------------+---------+
27
         *
28
         * Therefore, use XOR logic to determine whether to reverse bytes.
29
         *
30
         */
31
 
32
        /* ===[ Constants ]================================================== */
33
 
34
        internal const string DEFAULT_ENCODING   = "UTF8";
35
        internal const bool   DEFAULT_BIG_ENDIAN = false;
36
 
37
        /* ===[ Fields ]===================================================== */
38
 
39
        protected Stream       output;
40
        protected Encoding     encoding;
41
        protected BinaryWriter writer;
42
        protected bool         bigEnd;
43
 
44
        /* ===[ Constructors ]=============================================== */
45
 
46
        public EndianBinaryWriter(Stream output)
47
            : this(output, Encoding.GetEncoding(DEFAULT_ENCODING)) { }
48
 
49
        public EndianBinaryWriter(Stream output, Encoding encoding)
50
            : this(output, encoding, DEFAULT_BIG_ENDIAN) { }
51
 
52
        public EndianBinaryWriter(Stream output, Encoding encoding, bool bigEndian)
53
        {
54
            this.output   = output;
55
            this.encoding = encoding;
56
            this.writer   = new BinaryWriter(output, encoding);
57
            this.bigEnd   = bigEndian;
58
        }
59
 
60
        /* ===[ Properties ]================================================= */
61
 
62
        public bool BigEndian
63
        {
64
            get { return bigEnd; }
65
            set { bigEnd = value; }
66
        }
67
 
68
        public bool LittleEndian
69
        {
70
            get { return !bigEnd; }
71
            set { bigEnd = !value; }
72
        }
73
 
74
        /* ===[ Methods ]==================================================== */
75
 
76
        public void Flush()
77
        {
78
            writer.Flush();
79
        }
80
 
81
        /* ===[ 8-bit ]============== */
82
 
83
        public uint Write(byte data)
84
        {
85
            writer.Write(data);
86
            return sizeof(byte);
87
        }
88
 
89
        public uint Write(sbyte data)
90
        {
91
            writer.Write(data);
92
            return sizeof(byte);
93
        }
94
 
95
        public uint Write(bool data)
96
        {
97
            return Write(data
98
                ? (byte)0x01
99
                : (byte)0x00);
100
        }
101
 
102
        /* ===[ 16-bit ]============= */
103
 
104
        public uint Write(char data)
105
        {
106
            return Write(EndianBytes(BitConverter.GetBytes(data)));
107
        }
108
 
109
        public uint Write(short data)
110
        {
111
            return Write(EndianBytes(BitConverter.GetBytes(data)));
112
        }
113
 
114
        public uint Write(ushort data)
115
        {
116
            return Write(EndianBytes(BitConverter.GetBytes(data)));
117
        }
118
 
119
        /* ===[ 32-bit ]============= */
120
 
121
        public uint Write(float data)
122
        {
123
            return Write(EndianBytes(BitConverter.GetBytes(data)));
124
        }
125
 
126
        public uint Write(int data)
127
        {
128
            return Write(EndianBytes(BitConverter.GetBytes(data)));
129
        }
130
 
131
        public uint Write(uint data)
132
        {
133
            return Write(EndianBytes(BitConverter.GetBytes(data)));
134
        }
135
 
136
        /* ===[ 64-bit ]============= */
137
 
138
        public uint Write(double data)
139
        {
140
            return Write(EndianBytes(BitConverter.GetBytes(data)));
141
        }
142
 
143
        public uint Write(long data)
144
        {
145
            return Write(EndianBytes(BitConverter.GetBytes(data)));
146
        }
147
 
148
        public uint Write(ulong data)
149
        {
150
            return Write(EndianBytes(BitConverter.GetBytes(data)));
151
        }
152
 
153
        /* ===[ N-bit ]============== */
154
 
155
        public uint Write(byte[] data)
156
        {
157
            writer.Write(data);
158
            return (uint)data.LongLength;
159
        }
160
 
161
        public uint Write(char[] data)
162
        {
163
            return (uint)data
164
                .Sum(c => Write(c));
165
        }
166
 
167
        public uint Write(string data)
168
        {
169
            return Write(encoding.GetBytes(data));
170
        }
171
 
172
        public uint Write(byte[] buffer, int index, int count)
173
        {
174
            writer.Write(buffer, index, count);
175
            return (uint)count;
176
        }
177
 
178
        public uint Write(char[] chars, int index, int count)
179
        {
180
            return (uint)chars
181
                .Skip(index)
182
                .Take(count)
183
                .Sum(c => Write(c));
184
        }
185
 
186
        /* ========================== */
187
 
188
        protected byte[] EndianBytes(byte[] data)
189
        {
190
            return (BitConverter.IsLittleEndian ^ bigEnd)
191
                ? data
192
                : data.Reverse().ToArray();
193
        }
194
 
195
        /* ===[ EOF ]======================================================== */
196
    }
197
}