blob: 3e22146ee84225e3c78b186657327974112233a3 [file] [log] [blame]
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This is the main DLL file.
#include "stdafx.h"
#include "dnssd_NET.h"
#include "DebugServices.h"
#include "PString.h"
using namespace System::Net::Sockets;
using namespace System::Diagnostics;
using namespace Apple;
using namespace Apple::DNSSD;
//===========================================================================================================================
// Constants
//===========================================================================================================================
#define DEBUG_NAME "[dnssd.NET] "
//
// ConvertToString
//
static String*
ConvertToString(const char * utf8String)
{
return __gc new String(utf8String, 0, strlen(utf8String), __gc new UTF8Encoding(true, true));
}
//
// class ServiceRef
//
// ServiceRef serves as the base class for all DNSService operations.
//
// It manages the DNSServiceRef, and implements processing the
// result
//
ServiceRef::ServiceRef(Object * callback)
:
m_bDisposed(false),
m_callback(callback),
m_thread(NULL)
{
m_impl = new ServiceRefImpl(this);
}
ServiceRef::~ServiceRef()
{
}
//
// StartThread
//
// Starts the main processing thread
//
void
ServiceRef::StartThread()
{
check( m_impl != NULL );
m_impl->SetupEvents();
m_thread = new Thread(new ThreadStart(this, &Apple::DNSSD::ServiceRef::ProcessingThread));
m_thread->Name = S"DNSService Thread";
m_thread->IsBackground = true;
m_thread->Start();
}
//
// ProcessingThread
//
// The Thread class can only invoke methods in MC++ types. So we
// make a ProcessingThread method that forwards to the impl
//
void
ServiceRef::ProcessingThread()
{
m_impl->ProcessingThread();
}
//
// Dispose
//
// Calls impl-Dispose(). This ultimately will call DNSServiceRefDeallocate()
//
void
ServiceRef::Dispose()
{
check(m_impl != NULL);
check(m_bDisposed == false);
if (!m_bDisposed)
{
m_bDisposed = true;
//
// Call Dispose. This won't call DNSServiceRefDeallocate()
// necessarily. It depends on what thread this is being
// called in.
//
m_impl->Dispose();
m_impl = NULL;
m_thread = NULL;
GC::SuppressFinalize(this);
}
}
//
// EnumerateDomainsDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::EnumerateDomainsDispatch
(
ServiceFlags flags,
int interfaceIndex,
ErrorCode errorCode,
String * replyDomain
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::EnumerateDomainsReply * OnEnumerateDomainsReply = static_cast<DNSService::EnumerateDomainsReply*>(m_callback);
OnEnumerateDomainsReply(this, flags, interfaceIndex, errorCode, replyDomain);
}
}
//
// RegisterDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::RegisterDispatch
(
ServiceFlags flags,
ErrorCode errorCode,
String * name,
String * regtype,
String * domain
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::RegisterReply * OnRegisterReply = static_cast<DNSService::RegisterReply*>(m_callback);
OnRegisterReply(this, flags, errorCode, name, regtype, domain);
}
}
//
// BrowseDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::BrowseDispatch
(
ServiceFlags flags,
int interfaceIndex,
ErrorCode errorCode,
String * serviceName,
String * regtype,
String * replyDomain
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::BrowseReply * OnBrowseReply = static_cast<DNSService::BrowseReply*>(m_callback);
OnBrowseReply(this, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain);
}
}
//
// ResolveDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::ResolveDispatch
(
ServiceFlags flags,
int interfaceIndex,
ErrorCode errorCode,
String * fullname,
String * hosttarget,
int port,
Byte txtRecord[]
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::ResolveReply * OnResolveReply = static_cast<DNSService::ResolveReply*>(m_callback);
OnResolveReply(this, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtRecord);
}
}
//
// RegisterRecordDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::RegisterRecordDispatch
(
ServiceFlags flags,
ErrorCode errorCode,
RecordRef * record
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::RegisterRecordReply * OnRegisterRecordReply = static_cast<DNSService::RegisterRecordReply*>(m_callback);
OnRegisterRecordReply(this, flags, errorCode, record);
}
}
//
// QueryRecordDispatch
//
// Dispatch a reply to the delegate.
//
void
ServiceRef::QueryRecordDispatch
(
ServiceFlags flags,
int interfaceIndex,
ErrorCode errorCode,
String * fullname,
int rrtype,
int rrclass,
Byte rdata[],
int ttl
)
{
if ((m_callback != NULL) && (m_impl != NULL))
{
DNSService::QueryRecordReply * OnQueryRecordReply = static_cast<DNSService::QueryRecordReply*>(m_callback);
OnQueryRecordReply(this, flags, interfaceIndex, errorCode, fullname, rrtype, rrclass, rdata, ttl);
}
}
//
// ServiceRefImpl::ServiceRefImpl()
//
// Constructs a new ServiceRefImpl. We save the pointer to our enclosing
// class in a gcroot handle. This satisfies the garbage collector as
// the outer class is a managed type
//
ServiceRef::ServiceRefImpl::ServiceRefImpl(ServiceRef * outer)
:
m_socketEvent(NULL),
m_stopEvent(NULL),
m_disposed(false),
m_outer(outer),
m_ref(NULL)
{
m_threadId = GetCurrentThreadId();
}
//
// ServiceRefImpl::~ServiceRefImpl()
//
// Deallocate all resources associated with the ServiceRefImpl
//
ServiceRef::ServiceRefImpl::~ServiceRefImpl()
{
if (m_socketEvent != NULL)
{
CloseHandle(m_socketEvent);
m_socketEvent = NULL;
}
if (m_stopEvent != NULL)
{
CloseHandle(m_stopEvent);
m_stopEvent = NULL;
}
if (m_ref != NULL)
{
DNSServiceRefDeallocate(m_ref);
m_ref = NULL;
}
}
//
// ServiceRefImpl::SetupEvents()
//
// Setup the events necessary to manage multi-threaded dispatch
// of DNSService Events
//
void
ServiceRef::ServiceRefImpl::SetupEvents()
{
check(m_ref != NULL);
m_socket = (SOCKET) DNSServiceRefSockFD(m_ref);
check(m_socket != INVALID_SOCKET);
m_socketEvent = CreateEvent(NULL, 0, 0, NULL);
if (m_socketEvent == NULL)
{
throw new DNSServiceException(Unknown);
}
int err = WSAEventSelect(m_socket, m_socketEvent, FD_READ|FD_CLOSE);
if (err != 0)
{
throw new DNSServiceException(Unknown);
}
m_stopEvent = CreateEvent(NULL, 0, 0, NULL);
if (m_stopEvent == NULL)
{
throw new DNSServiceException(Unknown);
}
}
//
// ServiceRefImpl::ProcessingThread()
//
// Wait for socket events on the DNSServiceRefSockFD(). Also wait
// for stop events
//
void
ServiceRef::ServiceRefImpl::ProcessingThread()
{
check( m_socketEvent != NULL );
check( m_stopEvent != NULL );
check( m_ref != NULL );
HANDLE handles[2];
handles[0] = m_socketEvent;
handles[1] = m_stopEvent;
while (m_disposed == false)
{
int ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
//
// it's a socket event
//
if (ret == WAIT_OBJECT_0)
{
DNSServiceProcessResult(m_ref);
}
//
// else it's a stop event
//
else if (ret == WAIT_OBJECT_0 + 1)
{
break;
}
else
{
//
// unexpected wait result
//
dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, ret );
}
}
delete this;
}
//
// ServiceRefImpl::Dispose()
//
// Calls DNSServiceRefDeallocate()
//
void
ServiceRef::ServiceRefImpl::Dispose()
{
OSStatus err;
BOOL ok;
check(m_disposed == false);
m_disposed = true;
ok = SetEvent(m_stopEvent);
err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
require_noerr( err, exit );
exit:
return;
}
//
// ServiceRefImpl::EnumerateDomainsCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char * replyDomain,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
self->m_outer->EnumerateDomainsDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(replyDomain));
}
}
//
// ServiceRefImpl::RegisterCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::RegisterCallback
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
const char * name,
const char * regtype,
const char * domain,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
self->m_outer->RegisterDispatch((ServiceFlags) flags, (ErrorCode) errorCode, ConvertToString(name), ConvertToString(regtype), ConvertToString(domain));
}
}
//
// ServiceRefImpl::BrowseCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::BrowseCallback
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char * serviceName,
const char * regtype,
const char * replyDomain,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
self->m_outer->BrowseDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(serviceName), ConvertToString(regtype), ConvertToString(replyDomain));
}
}
//
// ServiceRefImpl::ResolveCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::ResolveCallback
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char * fullname,
const char * hosttarget,
uint16_t notAnIntPort,
uint16_t txtLen,
const char * txtRecord,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
Byte txtRecordBytes[];
txtRecordBytes = NULL;
if (txtLen > 0)
{
//
// copy raw memory into managed byte array
//
txtRecordBytes = new Byte[txtLen];
Byte __pin * p = &txtRecordBytes[0];
memcpy(p, txtRecord, txtLen);
}
self->m_outer->ResolveDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), ConvertToString(hosttarget), ntohs(notAnIntPort), txtRecordBytes);
}
}
//
// ServiceRefImpl::RegisterRecordCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::RegisterRecordCallback
(
DNSServiceRef sdRef,
DNSRecordRef rrRef,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
RecordRef * record = NULL;
if (errorCode == 0)
{
record = new RecordRef;
record->m_impl->m_ref = rrRef;
}
self->m_outer->RegisterRecordDispatch((ServiceFlags) flags, (ErrorCode) errorCode, record);
}
}
//
// ServiceRefImpl::QueryRecordCallback()
//
// This is the callback from dnssd.dll. We pass this up to our outer, managed type
//
void DNSSD_API
ServiceRef::ServiceRefImpl::QueryRecordCallback
(
DNSServiceRef DNSServiceRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char * fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
const void * rdata,
uint32_t ttl,
void * context
)
{
ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
check( self != NULL );
check( self->m_outer != NULL );
if (self->m_disposed == false)
{
Byte rdataBytes[];
if (rdlen)
{
rdataBytes = new Byte[rdlen];
Byte __pin * p = &rdataBytes[0];
memcpy(p, rdata, rdlen);
}
self->m_outer->QueryRecordDispatch((ServiceFlags) flags, (int) interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), rrtype, rrclass, rdataBytes, ttl);
}
}
/*
* EnumerateDomains()
*
* This maps to DNSServiceEnumerateDomains(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::EnumerateDomains
(
int flags,
int interfaceIndex,
EnumerateDomainsReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
int err;
err = DNSServiceEnumerateDomains(&sdRef->m_impl->m_ref, flags, interfaceIndex, ServiceRef::ServiceRefImpl::EnumerateDomainsCallback, sdRef->m_impl);
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* Register()
*
* This maps to DNSServiceRegister(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::Register
(
int flags,
int interfaceIndex,
String * name,
String * regtype,
String * domain,
String * host,
int port,
Byte txtRecord[],
RegisterReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
PString * pName = new PString(name);
PString * pType = new PString(regtype);
PString * pDomain = new PString(domain);
PString * pHost = new PString(host);
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
if ((txtRecord != NULL) && (txtRecord->Length > 0))
{
len = txtRecord->Length;
p = &txtRecord[0];
v = (void*) p;
}
int err = DNSServiceRegister(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(), pHost->c_str(), htons(port), len, v, ServiceRef::ServiceRefImpl::RegisterCallback, sdRef->m_impl );
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* AddRecord()
*
* This maps to DNSServiceAddRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
RecordRef*
DNSService::AddRecord
(
ServiceRef * sdRef,
int flags,
int rrtype,
Byte rdata[],
int ttl
)
{
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
if ((rdata != NULL) && (rdata->Length > 0))
{
len = rdata->Length;
p = &rdata[0];
v = (void*) p;
}
RecordRef * record = new RecordRef;
int err = DNSServiceAddRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, rrtype, len, v, ttl);
if (err != 0)
{
throw new DNSServiceException(err);
}
return record;
}
/*
* UpdateRecord()
*
* This maps to DNSServiceUpdateRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
void
DNSService::UpdateRecord
(
ServiceRef * sdRef,
RecordRef * record,
int flags,
Byte rdata[],
int ttl
)
{
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
if ((rdata != NULL) && (rdata->Length > 0))
{
len = rdata->Length;
p = &rdata[0];
v = (void*) p;
}
int err = DNSServiceUpdateRecord(sdRef->m_impl->m_ref, record ? record->m_impl->m_ref : NULL, flags, len, v, ttl);
if (err != 0)
{
throw new DNSServiceException(err);
}
}
/*
* RemoveRecord()
*
* This maps to DNSServiceRemoveRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
void
DNSService::RemoveRecord
(
ServiceRef * sdRef,
RecordRef * record,
int flags
)
{
int err = DNSServiceRemoveRecord(sdRef->m_impl->m_ref, record->m_impl->m_ref, flags);
if (err != 0)
{
throw new DNSServiceException(err);
}
}
/*
* Browse()
*
* This maps to DNSServiceBrowse(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::Browse
(
int flags,
int interfaceIndex,
String * regtype,
String * domain,
BrowseReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
PString * pType = new PString(regtype);
PString * pDomain = new PString(domain);
int err = DNSServiceBrowse(&sdRef->m_impl->m_ref, flags, interfaceIndex, pType->c_str(), pDomain->c_str(),(DNSServiceBrowseReply) ServiceRef::ServiceRefImpl::BrowseCallback, sdRef->m_impl);
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* Resolve()
*
* This maps to DNSServiceResolve(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::Resolve
(
int flags,
int interfaceIndex,
String * name,
String * regtype,
String * domain,
ResolveReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
PString * pName = new PString(name);
PString * pType = new PString(regtype);
PString * pDomain = new PString(domain);
int err = DNSServiceResolve(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(),(DNSServiceResolveReply) ServiceRef::ServiceRefImpl::ResolveCallback, sdRef->m_impl);
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* CreateConnection()
*
* This maps to DNSServiceCreateConnection(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::CreateConnection
(
RegisterRecordReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
int err = DNSServiceCreateConnection(&sdRef->m_impl->m_ref);
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* RegisterRecord()
*
* This maps to DNSServiceRegisterRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
RecordRef*
DNSService::RegisterRecord
(
ServiceRef * sdRef,
ServiceFlags flags,
int interfaceIndex,
String * fullname,
int rrtype,
int rrclass,
Byte rdata[],
int ttl
)
{
RecordRef * record = new RecordRef;
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
PString * pFullname = new PString(fullname);
if ((rdata != NULL) && (rdata->Length > 0))
{
len = rdata->Length;
p = &rdata[0];
v = (void*) p;
}
int err = DNSServiceRegisterRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v, ttl, (DNSServiceRegisterRecordReply) ServiceRef::ServiceRefImpl::RegisterRecordCallback, sdRef->m_impl);
if (err != 0)
{
throw new DNSServiceException(err);
}
return record;
}
/*
* QueryRecord()
*
* This maps to DNSServiceQueryRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
ServiceRef*
DNSService::QueryRecord
(
ServiceFlags flags,
int interfaceIndex,
String * fullname,
int rrtype,
int rrclass,
QueryRecordReply * callback
)
{
ServiceRef * sdRef = new ServiceRef(callback);
PString * pFullname = new PString(fullname);
int err = DNSServiceQueryRecord(&sdRef->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, (DNSServiceQueryRecordReply) ServiceRef::ServiceRefImpl::QueryRecordCallback, sdRef->m_impl);
if (err != 0)
{
throw new DNSServiceException(err);
}
sdRef->StartThread();
return sdRef;
}
/*
* ReconfirmRecord()
*
* This maps to DNSServiceReconfirmRecord(). Returns an
* initialized ServiceRef on success, throws an exception
* on failure.
*/
void
DNSService::ReconfirmRecord
(
ServiceFlags flags,
int interfaceIndex,
String * fullname,
int rrtype,
int rrclass,
Byte rdata[]
)
{
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
PString * pFullname = new PString(fullname);
if ((rdata != NULL) && (rdata->Length > 0))
{
len = rdata->Length;
p = &rdata[0];
v = (void*) p;
}
DNSServiceReconfirmRecord(flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v);
}
void
TextRecord::SetValue
(
String * key,
Byte value[] /* may be NULL */
)
{
PString * pKey = new PString(key);
int len = 0;
Byte __pin * p = NULL;
void * v = NULL;
DNSServiceErrorType err;
if (value && (value->Length > 0))
{
len = value->Length;
p = &value[0];
v = (void*) p;
}
err = TXTRecordSetValue(&m_impl->m_ref, pKey->c_str(), len, v);
if (err != 0)
{
throw new DNSServiceException(err);
}
}
void
TextRecord::RemoveValue
(
String * key
)
{
PString * pKey = new PString(key);
DNSServiceErrorType err;
err = TXTRecordRemoveValue(&m_impl->m_ref, pKey->c_str());
if (err != 0)
{
throw new DNSServiceException(err);
}
}
int
TextRecord::GetLength
(
)
{
return TXTRecordGetLength(&m_impl->m_ref);
}
Byte
TextRecord::GetBytes
(
) __gc[]
{
const void * noGCBytes = NULL;
Byte gcBytes[] = NULL;
noGCBytes = TXTRecordGetBytesPtr(&m_impl->m_ref);
int len = GetLength();
if (noGCBytes && len)
{
gcBytes = new Byte[len];
Byte __pin * p = &gcBytes[0];
memcpy(p, noGCBytes, len);
}
return gcBytes;
}
bool
TextRecord::ContainsKey
(
Byte txtRecord[],
String * key
)
{
PString * pKey = new PString(key);
Byte __pin * p = &txtRecord[0];
return (TXTRecordContainsKey(txtRecord->Length, p, pKey->c_str()) > 0) ? true : false;
}
Byte
TextRecord::GetValueBytes
(
Byte txtRecord[],
String * key
) __gc[]
{
uint8_t valueLen;
Byte ret[] = NULL;
PString * pKey = new PString(key);
Byte __pin * p1 = &txtRecord[0];
const void * v;
v = TXTRecordGetValuePtr(txtRecord->Length, p1, pKey->c_str(), &valueLen);
if (v != NULL)
{
ret = new Byte[valueLen];
Byte __pin * p2 = &ret[0];
memcpy(p2, v, valueLen);
}
return ret;
}
int
TextRecord::GetCount
(
Byte txtRecord[]
)
{
Byte __pin * p = &txtRecord[0];
return TXTRecordGetCount(txtRecord->Length, p);
}
Byte
TextRecord::GetItemAtIndex
(
Byte txtRecord[],
int index,
[Out] String ** key
) __gc[]
{
char keyBuf[255];
uint8_t keyBufLen = 255;
uint8_t valueLen;
void * value;
Byte ret[] = NULL;
DNSServiceErrorType err;
Byte __pin * p1 = &txtRecord[0];
err = TXTRecordGetItemAtIndex(txtRecord->Length, p1, index, keyBufLen, keyBuf, &valueLen, (const void**) &value);
if (err != 0)
{
throw new DNSServiceException(err);
}
*key = ConvertToString(keyBuf);
if (valueLen)
{
ret = new Byte[valueLen];
Byte __pin * p2 = &ret[0];
memcpy(p2, value, valueLen);
}
return ret;
}
//
// DNSServiceException::DNSServiceException()
//
// Constructs an exception with an error code
//
DNSServiceException::DNSServiceException
(
int _err
)
:
err(_err)
{
}
//
// This version of the constructor is useful for instances in which
// an inner exception is thrown, caught, and then a new exception
// is thrown in it's place
//
DNSServiceException::DNSServiceException
(
String * message,
System::Exception * innerException
)
{
}