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