7
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
using System.Collections;
35
namespace Mono.Addins.Serialization
37
internal class BinaryXmlWriter
40
BinaryXmlTypeMap typeMap;
41
Hashtable stringTable = new Hashtable ();
43
public BinaryXmlWriter (Stream stream, BinaryXmlTypeMap typeMap)
45
this.typeMap = typeMap;
46
writer = new BinaryWriter (stream);
49
public void WriteBeginElement (string name)
51
writer.Write (BinaryXmlReader.TagBeginElement);
55
public void WriteEndElement ()
57
writer.Write (BinaryXmlReader.TagEndElement);
60
void WriteValueHeader (string name, TypeCode type)
62
writer.Write (BinaryXmlReader.TagValue);
64
writer.Write ((byte) type);
67
public void WriteValue (string name, bool b)
69
WriteValueHeader (name, TypeCode.Boolean);
73
public void WriteValue (string name, string s)
75
WriteValueHeader (name, TypeCode.String);
79
public void WriteValue (string name, char value)
81
WriteValueHeader (name, TypeCode.Char);
85
public void WriteValue (string name, byte value)
87
WriteValueHeader (name, TypeCode.Byte);
91
public void WriteValue (string name, short value)
93
WriteValueHeader (name, TypeCode.Int16);
97
public void WriteValue (string name, int value)
99
WriteValueHeader (name, TypeCode.Int32);
100
writer.Write (value);
103
public void WriteValue (string name, long value)
105
WriteValueHeader (name, TypeCode.Int64);
106
writer.Write (value);
109
public void WriteValue (string name, DateTime value)
111
WriteValueHeader (name, TypeCode.DateTime);
112
writer.Write (value.Ticks);
115
public void WriteValue (string name, object ob)
117
TypeCode t = ob != null ? Type.GetTypeCode (ob.GetType ()) : TypeCode.Empty;
118
WriteValueHeader (name, t);
119
if (t != TypeCode.Empty)
123
public void WriteValue (string name, IBinaryXmlElement ob)
126
WriteValueHeader (name, TypeCode.Empty);
128
WriteValueHeader (name, TypeCode.Object);
133
void WriteValue (object ob)
136
writer.Write ((byte) TypeCode.Empty);
138
TypeCode t = Type.GetTypeCode (ob.GetType ());
139
writer.Write ((byte) t);
144
void WriteValue (object ob, TypeCode t)
147
case TypeCode.Boolean: writer.Write ((bool)ob); break;
148
case TypeCode.Char: writer.Write ((char)ob); break;
149
case TypeCode.SByte: writer.Write ((sbyte)ob); break;
150
case TypeCode.Byte: writer.Write ((byte)ob); break;
151
case TypeCode.Int16: writer.Write ((short)ob); break;
152
case TypeCode.UInt16: writer.Write ((ushort)ob); break;
153
case TypeCode.Int32: writer.Write ((int)ob); break;
154
case TypeCode.UInt32: writer.Write ((uint)ob); break;
155
case TypeCode.Int64: writer.Write ((long)ob); break;
156
case TypeCode.UInt64: writer.Write ((ulong)ob); break;
157
case TypeCode.Single: writer.Write ((float)ob); break;
158
case TypeCode.Double: writer.Write ((double)ob); break;
159
case TypeCode.DateTime: writer.Write (((DateTime)ob).Ticks); break;
160
case TypeCode.String: WriteString ((string)ob); break;
161
case TypeCode.Object: WriteObject (ob); break;
163
throw new InvalidOperationException ("Unexpected value type: " + t);
167
void WriteObject (object ob)
170
writer.Write (BinaryXmlReader.TagObjectNull);
172
IBinaryXmlElement elem = ob as IBinaryXmlElement;
174
writer.Write (BinaryXmlReader.TagObject);
175
WriteString (typeMap.GetTypeName (elem));
179
else if (ob is IDictionary) {
180
IDictionary dict = (IDictionary) ob;
181
writer.Write (BinaryXmlReader.TagObjectDictionary);
182
writer.Write (dict.Count);
183
foreach (DictionaryEntry e in dict) {
185
WriteValue (e.Value);
188
else if (ob is ICollection) {
189
ICollection col = (ICollection) ob;
190
writer.Write (BinaryXmlReader.TagObjectArray);
192
writer.Write ((byte) Type.GetTypeCode (ob.GetType().GetElementType ()));
194
writer.Write ((byte) TypeCode.Object);
195
writer.Write (col.Count);
196
foreach (object e in col) {
201
throw new InvalidOperationException ("Invalid object type: " + ob.GetType ());
205
void WriteString (string s)
210
object ind = stringTable [s];
212
stringTable.Add (s, stringTable.Count);
213
byte[] bytes = Encoding.UTF8.GetBytes (s);
214
writer.Write (bytes.Length);
215
writer.Write (bytes);
217
// +2 because -1 is reserved for null, and 0 is considered positive
218
writer.Write (-((int)ind + 2));