Mono.Zeroconf – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | // |
2 | // TxtRecord.cs |
||
3 | // |
||
4 | // Authors: |
||
5 | // Aaron Bockover <abockover@novell.com> |
||
6 | // |
||
7 | // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) |
||
8 | // |
||
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: |
||
16 | // |
||
17 | // The above copyright notice and this permission notice shall be |
||
18 | // included in all copies or substantial portions of the Software. |
||
19 | // |
||
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. |
||
27 | // |
||
28 | |||
29 | using System; |
||
30 | using System.Text; |
||
31 | using System.Collections; |
||
32 | using System.Runtime.InteropServices; |
||
33 | |||
34 | namespace Mono.Zeroconf.Providers.Bonjour |
||
35 | { |
||
36 | public class TxtRecord : ITxtRecord |
||
37 | { |
||
38 | private IntPtr handle = IntPtr.Zero; |
||
39 | private ushort length; |
||
40 | private IntPtr buffer; |
||
41 | |||
42 | private static readonly Encoding encoding = new ASCIIEncoding(); |
||
43 | |||
44 | public TxtRecord() |
||
45 | { |
||
46 | handle = Marshal.AllocHGlobal(16); |
||
47 | Native.TXTRecordCreate(handle, 0, IntPtr.Zero); |
||
48 | } |
||
49 | |||
50 | public TxtRecord(ushort length, IntPtr buffer) |
||
51 | { |
||
52 | this.length = length; |
||
53 | this.buffer = buffer; |
||
54 | } |
||
55 | |||
56 | public void Dispose() |
||
57 | { |
||
58 | if(handle != IntPtr.Zero) { |
||
59 | Native.TXTRecordDeallocate(handle); |
||
60 | handle = IntPtr.Zero; |
||
61 | } |
||
62 | } |
||
63 | |||
64 | public void Add(string key, string value) |
||
65 | { |
||
66 | Add(new TxtRecordItem(key, value)); |
||
67 | } |
||
68 | |||
69 | public void Add(string key, byte [] value) |
||
70 | { |
||
71 | Add(new TxtRecordItem(key, value)); |
||
72 | } |
||
73 | |||
74 | public void Add(TxtRecordItem item) |
||
75 | { |
||
76 | if(handle == IntPtr.Zero) { |
||
77 | throw new InvalidOperationException("This TXT Record is read only"); |
||
78 | } |
||
79 | |||
80 | string key = item.Key; |
||
81 | if(key[key.Length - 1] != '\0') { |
||
82 | key += "\0"; |
||
83 | } |
||
84 | |||
85 | ServiceError error = Native.TXTRecordSetValue(handle, encoding.GetBytes(key + "\0"), |
||
86 | (sbyte)item.ValueRaw.Length, item.ValueRaw); |
||
87 | |||
88 | if(error != ServiceError.NoError) { |
||
89 | throw new ServiceErrorException(error); |
||
90 | } |
||
91 | } |
||
92 | |||
93 | public void Remove(string key) |
||
94 | { |
||
95 | if(handle == IntPtr.Zero) { |
||
96 | throw new InvalidOperationException("This TXT Record is read only"); |
||
97 | } |
||
98 | |||
99 | ServiceError error = Native.TXTRecordRemoveValue(handle, encoding.GetBytes(key)); |
||
100 | |||
101 | if(error != ServiceError.NoError) { |
||
102 | throw new ServiceErrorException(error); |
||
103 | } |
||
104 | } |
||
105 | |||
106 | public TxtRecordItem GetItemAt(int index) |
||
107 | { |
||
108 | byte [] key = new byte[32]; |
||
109 | byte value_length = 0; |
||
110 | IntPtr value_raw = IntPtr.Zero; |
||
111 | |||
112 | if(index < 0 || index >= Count) { |
||
113 | throw new IndexOutOfRangeException(); |
||
114 | } |
||
115 | |||
116 | ServiceError error = Native.TXTRecordGetItemAtIndex(RawLength, RawBytes, (ushort)index, |
||
117 | (ushort)key.Length, key, out value_length, out value_raw); |
||
118 | |||
119 | if(error != ServiceError.NoError) { |
||
120 | throw new ServiceErrorException(error); |
||
121 | } |
||
122 | |||
123 | byte [] buffer = new byte[value_length]; |
||
124 | for(int i = 0; i < value_length; i++) { |
||
125 | buffer[i] = Marshal.ReadByte(value_raw, i); |
||
126 | } |
||
127 | |||
128 | int pos = 0; |
||
129 | for(; pos < key.Length && key[pos] != 0; pos++); |
||
130 | |||
131 | return new TxtRecordItem(encoding.GetString(key, 0, pos), buffer); |
||
132 | } |
||
133 | |||
134 | public IEnumerator GetEnumerator() |
||
135 | { |
||
136 | return new TxtRecordEnumerator(this); |
||
137 | } |
||
138 | |||
139 | public override string ToString() |
||
140 | { |
||
141 | string ret = String.Empty; |
||
142 | int i = 0; |
||
143 | int count = Count; |
||
144 | |||
145 | foreach(TxtRecordItem item in this) { |
||
146 | ret += "\"" + item.ToString() + "\""; |
||
147 | if(i < count - 1) { |
||
148 | ret += ", "; |
||
149 | } |
||
150 | |||
151 | i++; |
||
152 | } |
||
153 | |||
154 | return ret; |
||
155 | } |
||
156 | |||
157 | public TxtRecordItem this[string key] { |
||
158 | get { |
||
159 | foreach(TxtRecordItem item in this) { |
||
160 | if(item.Key == key) { |
||
161 | return item; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | return null; |
||
166 | } |
||
167 | } |
||
168 | |||
169 | public IntPtr RawBytes { |
||
170 | get { return handle == IntPtr.Zero ? buffer : Native.TXTRecordGetBytesPtr(handle); } |
||
171 | } |
||
172 | |||
173 | public ushort RawLength { |
||
174 | get { return handle == IntPtr.Zero ? length : Native.TXTRecordGetLength(handle); } |
||
175 | } |
||
176 | |||
177 | public int Count { |
||
178 | get { return Native.TXTRecordGetCount(RawLength, RawBytes); } |
||
179 | } |
||
180 | |||
181 | public ITxtRecord BaseRecord { |
||
182 | get { return this; } |
||
183 | } |
||
184 | } |
||
185 | } |