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 38 STDMETHODIMP 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 84 exit: 85 86 87 88 return hr; 89 90 } 91 92 93 94 STDMETHODIMP 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 128 exit: 129 130 131 132 return hr; 133 134 } 135 136 137 138 STDMETHODIMP 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 174 exit: 175 176 177 178 return err; 179 180 } 181 182 183 184 STDMETHODIMP 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 232 exit: 233 234 235 236 return hr; 237 238 } 239 240 241 242 STDMETHODIMP CTXTRecord::GetCount(ULONG* count) 243 244 { 245 246 *count = 0; 247 248 249 250 if ( m_byteArray.size() > 0 ) 251 252 { 253 254 *count = TXTRecordGetCount( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ] ); 255 256 } 257 258 259 260 return S_OK; 261 262 } 263 264 265 266 STDMETHODIMP CTXTRecord::GetKeyAtIndex(ULONG index, BSTR* retval) 267 268 { 269 270 char keyBuf[ 64 ]; 271 272 uint8_t rawValueLen; 273 274 const void * rawValue; 275 276 CComBSTR temp; 277 278 DNSServiceErrorType err; 279 280 BOOL ok; 281 282 HRESULT hr = S_OK; 283 284 285 286 err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue ); 287 288 require_action( !err, exit, hr = S_FALSE ); 289 290 291 292 ok = UTF8ToBSTR( keyBuf, temp ); 293 294 require_action( ok, exit, hr = S_FALSE ); 295 296 297 298 *retval = temp; 299 300 301 302 exit: 303 304 305 306 return hr; 307 308 } 309 310 311 312 STDMETHODIMP CTXTRecord::GetValueAtIndex(ULONG index, VARIANT* retval) 313 314 { 315 316 char keyBuf[ 64 ]; 317 318 uint8_t rawValueLen; 319 320 const void * rawValue; 321 322 CComBSTR temp; 323 324 DNSServiceErrorType err; 325 326 BOOL ok; 327 328 HRESULT hr = S_OK; 329 330 331 332 err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue ); 333 334 require_action( !err, exit, hr = S_FALSE ); 335 336 337 338 ok = ByteArrayToVariant( rawValue, rawValueLen, retval ); 339 340 require_action( ok, exit, hr = S_FALSE ); 341 342 343 344 exit: 345 346 347 348 return hr; 349 350 } 351 352 353 354 355 356 void 357 358 CTXTRecord::SetBytes 359 360 ( 361 362 const unsigned char * bytes, 363 364 uint16_t len 365 366 ) 367 368 { 369 370 check ( bytes != NULL ); 371 372 check( len ); 373 374 375 376 m_byteArray.reserve( len ); 377 378 m_byteArray.assign( bytes, bytes + len ); 379 380 } 381 382