1/* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19
20#include "stdafx.h"
21
22#include "TXTRecord.h"
23
24#include "StringServices.h"
25
26#include <DebugServices.h>
27
28
29
30
31
32// CTXTRecord
33
34
35
36
37
38STDMETHODIMP CTXTRecord::SetValue(BSTR key, VARIANT value)
39
40{
41
42	std::string			keyUTF8;
43
44	ByteArray			valueArray;
45
46	BOOL				ok;
47
48	DNSServiceErrorType	err;
49
50	HRESULT				hr = S_OK;
51
52
53
54	if ( !m_allocated )
55
56	{
57
58		TXTRecordCreate( &m_tref, 0, NULL );
59
60		m_allocated = TRUE;
61
62	}
63
64
65
66	ok = BSTRToUTF8( key, keyUTF8 );
67
68	require_action( ok, exit, hr = S_FALSE );
69
70
71
72	ok = VariantToByteArray( &value, valueArray );
73
74	require_action( ok, exit, hr = S_FALSE );
75
76
77
78	err = TXTRecordSetValue( &m_tref, keyUTF8.c_str(), ( uint8_t ) valueArray.size(), &valueArray[ 0 ] );
79
80	require_action( !err, exit, hr = S_FALSE );
81
82
83
84exit:
85
86
87
88	return hr;
89
90}
91
92
93
94STDMETHODIMP CTXTRecord::RemoveValue(BSTR key)
95
96{
97
98	HRESULT hr = S_OK;
99
100
101
102	if ( m_allocated )
103
104	{
105
106		std::string			keyUTF8;
107
108		BOOL				ok;
109
110		DNSServiceErrorType	err;
111
112
113
114		ok = BSTRToUTF8( key, keyUTF8 );
115
116		require_action( ok, exit, hr = S_FALSE );
117
118
119
120		err = TXTRecordRemoveValue( &m_tref, keyUTF8.c_str() );
121
122		require_action( !err, exit, hr = S_FALSE );
123
124	}
125
126
127
128exit:
129
130
131
132	return hr;
133
134}
135
136
137
138STDMETHODIMP CTXTRecord::ContainsKey(BSTR key, VARIANT_BOOL* retval)
139
140{
141
142	std::string keyUTF8;
143
144	int			ret	= 0;
145
146	HRESULT		err	= S_OK;
147
148
149
150	if ( m_byteArray.size() > 0 )
151
152	{
153
154		BOOL ok;
155
156
157
158		ok = BSTRToUTF8( key, keyUTF8 );
159
160		require_action( ok, exit, err = S_FALSE );
161
162
163
164		ret = TXTRecordContainsKey( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str() );
165
166	}
167
168
169
170	*retval = ( ret ) ? VARIANT_TRUE : VARIANT_FALSE;
171
172
173
174exit:
175
176
177
178	return err;
179
180}
181
182
183
184STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value)
185
186{
187
188	std::string		keyUTF8;
189
190	const void	*	rawValue;
191
192	uint8_t			rawValueLen;
193
194	BOOL			ok	= TRUE;
195
196	HRESULT			hr	= S_OK;
197
198
199
200	VariantClear( value );
201
202
203
204	if ( m_byteArray.size() > 0 )
205
206	{
207
208		ok = BSTRToUTF8( key, keyUTF8 );
209
210		require_action( ok, exit, hr = S_FALSE );
211
212
213
214		rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen );
215
216
217
218		if ( rawValue )
219
220		{
221
222			ok = ByteArrayToVariant( rawValue, rawValueLen, value );
223
224			require_action( ok, exit, hr = S_FALSE );
225
226		}
227
228	}
229
230
231
232exit:
233
234
235
236	return hr;
237
238}
239
240
241
242STDMETHODIMP CTXTRecord::GetCount(ULONG* count)
243
244{
245
246	*count = 0;
247
248	if ( m_allocated )
249	{
250		*count = TXTRecordGetCount( TXTRecordGetLength( &m_tref ), TXTRecordGetBytesPtr( &m_tref ) );
251	}
252	else if ( m_byteArray.size() > 0 )
253	{
254
255		*count = TXTRecordGetCount( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ] );
256
257	}
258
259
260
261	return S_OK;
262
263}
264
265
266
267STDMETHODIMP CTXTRecord::GetKeyAtIndex(ULONG index, BSTR* retval)
268
269{
270
271	char				keyBuf[ 64 ];
272
273	uint8_t				rawValueLen;
274
275	const void		*	rawValue;
276
277	CComBSTR			temp;
278
279	DNSServiceErrorType	err;
280
281	BOOL				ok;
282
283	HRESULT				hr = S_OK;
284
285
286
287	err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );
288
289	require_action( !err, exit, hr = S_FALSE );
290
291
292
293	ok = UTF8ToBSTR( keyBuf, temp );
294
295	require_action( ok, exit, hr = S_FALSE );
296
297
298
299	*retval = temp;
300
301
302
303exit:
304
305
306
307	return hr;
308
309}
310
311
312
313STDMETHODIMP CTXTRecord::GetValueAtIndex(ULONG index, VARIANT* retval)
314
315{
316
317	char				keyBuf[ 64 ];
318
319	uint8_t				rawValueLen;
320
321	const void		*	rawValue;
322
323	CComBSTR			temp;
324
325	DNSServiceErrorType	err;
326
327	BOOL				ok;
328
329	HRESULT				hr = S_OK;
330
331
332
333	err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );
334
335	require_action( !err, exit, hr = S_FALSE );
336
337
338
339	ok = ByteArrayToVariant( rawValue, rawValueLen, retval );
340
341	require_action( ok, exit, hr = S_FALSE );
342
343
344
345exit:
346
347
348
349	return hr;
350
351}
352
353
354
355
356
357void
358
359CTXTRecord::SetBytes
360
361	(
362
363	const unsigned char	*	bytes,
364
365	uint16_t				len
366
367	)
368
369{
370
371	check ( bytes != NULL );
372
373	check( len );
374
375
376
377	m_byteArray.reserve( len );
378
379	m_byteArray.assign( bytes, bytes + len );
380
381}
382
383