This commit is contained in:
dwitte@stanford.edu 2008-01-11 02:56:35 -08:00
Родитель 6ba4acd13f
Коммит d8e50854a6
8 изменённых файлов: 128 добавлений и 134 удалений

Просмотреть файл

@ -40,24 +40,19 @@
#include "nsISupports.idl" #include "nsISupports.idl"
[ptr] native const_nsID_ptr(const nsID); [scriptable, uuid(C86AE131-D101-11d2-9841-006008962422)]
[scriptable, uuid(baedc96a-9cee-4b6b-9160-90d257b3c8ef)]
interface nsIJSID : nsISupports interface nsIJSID : nsISupports
{ {
readonly attribute string name; readonly attribute string name;
readonly attribute string number; readonly attribute string number;
readonly attribute boolean valid; [noscript] readonly attribute nsIDPtr id;
readonly attribute boolean valid;
boolean equals(in nsIJSID other); boolean equals(in nsIJSID other);
void initialize(in string idString); void initialize(in string idString);
string toString(); string toString();
// returns a pointer to the internal nsID. this pointer is only valid
// while the nsIJSID object remains alive!
[notxpcom] const_nsID_ptr getID();
}; };
[scriptable, uuid(e08dcda0-d651-11d2-9843-006008962422)] [scriptable, uuid(e08dcda0-d651-11d2-9843-006008962422)]

Просмотреть файл

@ -669,8 +669,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
if(!JSVAL_IS_OBJECT(s) || if(!JSVAL_IS_OBJECT(s) ||
(!(obj = JSVAL_TO_OBJECT(s))) || (!(obj = JSVAL_TO_OBJECT(s))) ||
(!(pid = xpc_JSObjectToID(cx, obj))) || (!(pid = xpc_JSObjectToID(cx, obj))))
(!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID)))))
{ {
return JS_FALSE; return JS_FALSE;
} }

Просмотреть файл

@ -117,10 +117,14 @@ nsJSID::GetNumber(char * *aNumber)
return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
} }
NS_IMETHODIMP_(const nsID*) NS_IMETHODIMP
nsJSID::GetID() nsJSID::GetId(nsID* *aId)
{ {
return &mID; if(!aId)
return NS_ERROR_NULL_POINTER;
*aId = (nsID*) nsMemory::Clone(&mID, sizeof(nsID));
return *aId ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -139,13 +143,17 @@ nsJSID::Equals(nsIJSID *other, PRBool *_retval)
if(!_retval) if(!_retval)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
if(!other || mID.Equals(GetInvalidIID())) *_retval = PR_FALSE;
{
*_retval = PR_FALSE;
return NS_OK;
}
*_retval = other->GetID()->Equals(mID); if(!other || mID.Equals(GetInvalidIID()))
return NS_OK;
nsID* otherID;
if(NS_SUCCEEDED(other->GetId(&otherID)))
{
*_retval = mID.Equals(*otherID);
nsMemory::Free(otherID);
}
return NS_OK; return NS_OK;
} }
@ -155,22 +163,23 @@ nsJSID::Initialize(const char *idString)
if(!idString) if(!idString)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
PRBool success = PR_FALSE;
if(strlen(idString) && mID.Equals(GetInvalidIID())) if(strlen(idString) && mID.Equals(GetInvalidIID()))
{ {
Reset(); Reset();
if(idString[0] == '{') if(idString[0] == '{')
{ {
if(mID.Parse(idString)) nsID id;
if(id.Parse((char*)idString))
{ {
return NS_OK; mID = id;
success = PR_TRUE;
} }
// error - reset to invalid state
mID = GetInvalidIID();
} }
} }
return NS_ERROR_FAILURE; return success ? NS_OK : NS_ERROR_FAILURE;
} }
PRBool PRBool
@ -232,20 +241,6 @@ nsJSID::NewID(const char* str)
return idObj; return idObj;
} }
//static
nsJSID*
nsJSID::NewID(const nsID& id)
{
nsJSID* idObj = new nsJSID();
if(idObj)
{
NS_ADDREF(idObj);
idObj->mID = id;
}
return idObj;
}
/***************************************************************************/ /***************************************************************************/
// Class object support so that we can share prototypes of wrapper // Class object support so that we can share prototypes of wrapper
@ -417,19 +412,19 @@ NS_IMETHODIMP nsJSIID::GetName(char * *aName)
NS_IMETHODIMP nsJSIID::GetNumber(char * *aNumber) NS_IMETHODIMP nsJSIID::GetNumber(char * *aNumber)
{ {
char str[NSID_LENGTH];
const nsIID* id; const nsIID* id;
mInfo->GetIIDShared(&id); mInfo->GetIIDShared(&id);
id->ToProvidedString(str); char* str = id->ToString();
*aNumber = (char*) nsMemory::Clone(str, NSID_LENGTH); if(!str)
return NS_ERROR_OUT_OF_MEMORY;
*aNumber = (char*) nsMemory::Clone(str, strlen(str)+1);
PR_Free(str);
return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
} }
NS_IMETHODIMP_(const nsID*) nsJSIID::GetID() NS_IMETHODIMP nsJSIID::GetId(nsID* *aId)
{ {
const nsIID* id; return mInfo->GetInterfaceIID((nsIID**)aId);
mInfo->GetIIDShared(&id);
return id;
} }
NS_IMETHODIMP nsJSIID::GetValid(PRBool *aValid) NS_IMETHODIMP nsJSIID::GetValid(PRBool *aValid)
@ -443,13 +438,17 @@ NS_IMETHODIMP nsJSIID::Equals(nsIJSID *other, PRBool *_retval)
if(!_retval) if(!_retval)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
if(!other) *_retval = PR_FALSE;
{
*_retval = PR_FALSE;
return NS_OK;
}
mInfo->IsIID(other->GetID(), _retval); if(!other)
return NS_OK;
nsID* otherID;
if(NS_SUCCEEDED(other->GetId(&otherID)))
{
mInfo->IsIID((nsIID*)otherID, _retval);
nsMemory::Free(otherID);
}
return NS_OK; return NS_OK;
} }
@ -674,8 +673,8 @@ NS_IMETHODIMP nsJSCID::GetName(char * *aName)
NS_IMETHODIMP nsJSCID::GetNumber(char * *aNumber) NS_IMETHODIMP nsJSCID::GetNumber(char * *aNumber)
{return mDetails.GetNumber(aNumber);} {return mDetails.GetNumber(aNumber);}
NS_IMETHODIMP_(const nsID*) nsJSCID::GetID() NS_IMETHODIMP nsJSCID::GetId(nsID* *aId)
{return &mDetails.ID();} {return mDetails.GetId(aId);}
NS_IMETHODIMP nsJSCID::GetValid(PRBool *aValid) NS_IMETHODIMP nsJSCID::GetValid(PRBool *aValid)
{return mDetails.GetValid(aValid);} {return mDetails.GetValid(aValid);}
@ -737,28 +736,6 @@ nsJSCID::NewID(const char* str)
return idObj; return idObj;
} }
static const nsID*
GetIIDArg(PRUint32 argc, jsval* argv, JSContext* cx)
{
const nsID* iid;
// If an IID was passed in then use it
if(argc)
{
JSObject* iidobj;
jsval val = *argv;
if(JSVAL_IS_PRIMITIVE(val) ||
!(iidobj = JSVAL_TO_OBJECT(val)) ||
!(iid = xpc_JSObjectToID(cx, iidobj)))
{
return nsnull;
}
}
else
iid = &NS_GET_IID(nsISupports);
return iid;
}
/* nsISupports createInstance (); */ /* nsISupports createInstance (); */
NS_IMETHODIMP NS_IMETHODIMP
@ -798,17 +775,32 @@ nsJSCID::CreateInstance(nsISupports **_retval)
nsIXPCSecurityManager* sm; nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager( sm = xpcc->GetAppropriateSecurityManager(
nsIXPCSecurityManager::HOOK_CREATE_INSTANCE); nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID())))
{ {
// the security manager vetoed. It should have set an exception. // the security manager vetoed. It should have set an exception.
ccxp->SetExceptionWasThrown(JS_TRUE); ccxp->SetExceptionWasThrown(JS_TRUE);
return NS_OK; return NS_OK;
} }
nsID iid;
// If an IID was passed in then use it // If an IID was passed in then use it
const nsID* iid = GetIIDArg(argc, argv, cx); if(argc)
if (!iid) {
return NS_ERROR_XPC_BAD_IID; JSObject* iidobj;
jsval val = *argv;
nsID* piid = nsnull;
if(JSVAL_IS_PRIMITIVE(val) ||
!(iidobj = JSVAL_TO_OBJECT(val)) ||
!(piid = xpc_JSObjectToID(cx, iidobj)))
{
return NS_ERROR_XPC_BAD_IID;
}
iid = *piid;
nsMemory::Free(piid);
}
else
iid = NS_GET_IID(nsISupports);
nsCOMPtr<nsIComponentManager> compMgr; nsCOMPtr<nsIComponentManager> compMgr;
nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr)); nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr));
@ -816,7 +808,7 @@ nsJSCID::CreateInstance(nsISupports **_retval)
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsISupports> inst; nsCOMPtr<nsISupports> inst;
rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst)); rv = compMgr->CreateInstance(*mDetails.GetID(), nsnull, iid, getter_AddRefs(inst));
NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!"); NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!");
if(NS_FAILED(rv) || !inst) if(NS_FAILED(rv) || !inst)
@ -824,7 +816,7 @@ nsJSCID::CreateInstance(nsISupports **_retval)
JSObject* instJSObj; JSObject* instJSObj;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder; nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->WrapNative(cx, obj, inst, *iid, getter_AddRefs(holder)); rv = xpc->WrapNative(cx, obj, inst, iid, getter_AddRefs(holder));
if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj))) if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj)))
return NS_ERROR_XPC_CANT_CREATE_WN; return NS_ERROR_XPC_CANT_CREATE_WN;
@ -871,17 +863,32 @@ nsJSCID::GetService(nsISupports **_retval)
nsIXPCSecurityManager* sm; nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager( sm = xpcc->GetAppropriateSecurityManager(
nsIXPCSecurityManager::HOOK_GET_SERVICE); nsIXPCSecurityManager::HOOK_GET_SERVICE);
if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID())))
{ {
// the security manager vetoed. It should have set an exception. // the security manager vetoed. It should have set an exception.
ccxp->SetExceptionWasThrown(JS_TRUE); ccxp->SetExceptionWasThrown(JS_TRUE);
return NS_OK; return NS_OK;
} }
nsID iid;
// If an IID was passed in then use it // If an IID was passed in then use it
const nsID* iid = GetIIDArg(argc, argv, cx); if(argc)
if (!iid) {
return NS_ERROR_XPC_BAD_IID; JSObject* iidobj;
jsval val = *argv;
nsID* piid = nsnull;
if(JSVAL_IS_PRIMITIVE(val) ||
!(iidobj = JSVAL_TO_OBJECT(val)) ||
!(piid = xpc_JSObjectToID(cx, iidobj)))
{
return NS_ERROR_XPC_BAD_IID;
}
iid = *piid;
nsMemory::Free(piid);
}
else
iid = NS_GET_IID(nsISupports);
nsCOMPtr<nsIServiceManager> svcMgr; nsCOMPtr<nsIServiceManager> svcMgr;
nsresult rv = NS_GetServiceManager(getter_AddRefs(svcMgr)); nsresult rv = NS_GetServiceManager(getter_AddRefs(svcMgr));
@ -889,14 +896,14 @@ nsJSCID::GetService(nsISupports **_retval)
return rv; return rv;
nsCOMPtr<nsISupports> srvc; nsCOMPtr<nsISupports> srvc;
rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc)); rv = svcMgr->GetService(*mDetails.GetID(), iid, getter_AddRefs(srvc));
NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!"); NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!");
if(NS_FAILED(rv) || !srvc) if(NS_FAILED(rv) || !srvc)
return NS_ERROR_XPC_GS_RETURNED_FAILURE; return NS_ERROR_XPC_GS_RETURNED_FAILURE;
JSObject* instJSObj; JSObject* instJSObj;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder; nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder)); rv = xpc->WrapNative(cx, obj, srvc, iid, getter_AddRefs(holder));
if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj))) if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj)))
return NS_ERROR_XPC_CANT_CREATE_WN; return NS_ERROR_XPC_CANT_CREATE_WN;
@ -955,7 +962,7 @@ nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
{ {
nsID cid; nsID cid;
if(NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid))) if(NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid)))
*bp = cid.Equals(mDetails.ID()); *bp = cid.Equals(*mDetails.GetID());
} }
} }
return rv; return rv;
@ -969,31 +976,36 @@ xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID)
{ {
JSObject *obj = nsnull; JSObject *obj = nsnull;
nsCOMPtr<nsIJSID> iid = char* idString = aID.ToString();
dont_AddRef(static_cast<nsIJSID*>(nsJSID::NewID(aID))); if(idString)
if(iid)
{ {
nsXPConnect* xpc = nsXPConnect::GetXPConnect(); nsCOMPtr<nsIJSID> iid =
if(xpc) dont_AddRef(static_cast<nsIJSID*>(nsJSID::NewID(idString)));
PR_Free(idString);
if(iid)
{ {
nsCOMPtr<nsIXPConnectJSObjectHolder> holder; nsXPConnect* xpc = nsXPConnect::GetXPConnect();
nsresult rv = xpc->WrapNative(cx, jsobj, if(xpc)
static_cast<nsISupports*>(iid),
NS_GET_IID(nsIJSID),
getter_AddRefs(holder));
if(NS_SUCCEEDED(rv) && holder)
{ {
holder->GetJSObject(&obj); nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsresult rv = xpc->WrapNative(cx, jsobj,
static_cast<nsISupports*>(iid),
NS_GET_IID(nsIJSID),
getter_AddRefs(holder));
if(NS_SUCCEEDED(rv) && holder)
{
holder->GetJSObject(&obj);
}
} }
} }
} }
return obj; return obj;
} }
// note: returned pointer is only valid while |obj| remains alive! nsID*
const nsID*
xpc_JSObjectToID(JSContext *cx, JSObject* obj) xpc_JSObjectToID(JSContext *cx, JSObject* obj)
{ {
nsID* id = nsnull;
if(!cx || !obj) if(!cx || !obj)
return nsnull; return nsnull;
@ -1005,9 +1017,9 @@ xpc_JSObjectToID(JSContext *cx, JSObject* obj)
wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) ||
wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID))))
{ {
return ((nsIJSID*)wrapper->GetIdentityObject())->GetID(); ((nsIJSID*)wrapper->GetIdentityObject())->GetId(&id);
} }
return nsnull; return id;
} }
JSBool JSBool

Просмотреть файл

@ -2852,11 +2852,11 @@ public:
void SetNameToNoString() void SetNameToNoString()
{NS_ASSERTION(!mName, "name already set"); mName = gNoString;} {NS_ASSERTION(!mName, "name already set"); mName = gNoString;}
PRBool NameIsSet() const {return nsnull != mName;} PRBool NameIsSet() const {return nsnull != mName;}
const nsID& ID() const {return mID;} const nsID* GetID() const {return &mID;}
PRBool IsValid() const {return !mID.Equals(GetInvalidIID());} PRBool IsValid() const {return !mID.Equals(GetInvalidIID());}
static nsJSID* NewID(const char* str); static nsJSID* NewID(const char* str);
static nsJSID* NewID(const nsID& id);
nsJSID(); nsJSID();
virtual ~nsJSID(); virtual ~nsJSID();
@ -3316,7 +3316,7 @@ private:
extern JSObject* extern JSObject*
xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID); xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID);
extern const nsID* extern nsID*
xpc_JSObjectToID(JSContext *cx, JSObject* obj); xpc_JSObjectToID(JSContext *cx, JSObject* obj);
extern JSBool extern JSBool

Просмотреть файл

@ -320,9 +320,14 @@ JSBool XPCVariant::InitializeData(XPCCallContext& ccx)
// Let's see if it is a xpcJSID. // Let's see if it is a xpcJSID.
const nsID* id = xpc_JSObjectToID(ccx, jsobj); // XXX It might be nice to have a non-allocing version of xpc_JSObjectToID.
nsID* id = xpc_JSObjectToID(ccx, jsobj);
if(id) if(id)
return NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id)); {
JSBool success = NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id));
nsMemory::Free((char*)id);
return success;
}
// Let's see if it is a js array object. // Let's see if it is a js array object.

Просмотреть файл

@ -1950,7 +1950,7 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, ccx); Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, ccx);
return JS_FALSE; return JS_FALSE;
} }
const nsID* iid; nsID* iid;
JSObject* obj; JSObject* obj;
if(!JSVAL_IS_OBJECT(argv[0]) || if(!JSVAL_IS_OBJECT(argv[0]) ||
(!(obj = JSVAL_TO_OBJECT(argv[0]))) || (!(obj = JSVAL_TO_OBJECT(argv[0]))) ||
@ -1971,6 +1971,7 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
if(NS_FAILED(invokeResult)) if(NS_FAILED(invokeResult))
{ {
ThrowBadResult(invokeResult, ccx); ThrowBadResult(invokeResult, ccx);
PR_Free(iid);
return JS_FALSE; return JS_FALSE;
} }
@ -1978,6 +1979,7 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
retval = XPCConvert::NativeData2JS(ccx, &v, &qiresult, retval = XPCConvert::NativeData2JS(ccx, &v, &qiresult,
nsXPTType::T_INTERFACE_IS | XPT_TDP_POINTER, nsXPTType::T_INTERFACE_IS | XPT_TDP_POINTER,
iid, ccx.GetCurrentJSObject(), &err); iid, ccx.GetCurrentJSObject(), &err);
PR_Free(iid);
NS_IF_RELEASE(qiresult); NS_IF_RELEASE(qiresult);
if(!retval) if(!retval)

Просмотреть файл

@ -126,10 +126,10 @@ PRBool nsID::Parse(const char *aIDStr)
char *nsID::ToString() const char *nsID::ToString() const
{ {
char *res = (char*)PR_Malloc(NSID_LENGTH); // use PR_Malloc if this is to be freed with nsCRT::free char *res = (char*)PR_Malloc(39); // use PR_Malloc if this is to be freed with nsCRT::free
if (res != NULL) { if (res != NULL) {
PR_snprintf(res, NSID_LENGTH, gIDFormat, PR_snprintf(res, 39, gIDFormat,
m0, (PRUint32) m1, (PRUint32) m2, m0, (PRUint32) m1, (PRUint32) m2,
(PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2], (PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2],
(PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5], (PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5],
@ -138,12 +138,3 @@ char *nsID::ToString() const
return res; return res;
} }
void nsID::ToProvidedString(char (&dest)[NSID_LENGTH]) const
{
PR_snprintf(dest, NSID_LENGTH, gIDFormat,
m0, (PRUint32) m1, (PRUint32) m2,
(PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2],
(PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5],
(PRUint32) m3[6], (PRUint32) m3[7]);
}

Просмотреть файл

@ -44,8 +44,6 @@
#include "nscore.h" #include "nscore.h"
#endif #endif
#define NSID_LENGTH 39
/** /**
* A "unique identifier". This is modeled after OSF DCE UUIDs. * A "unique identifier". This is modeled after OSF DCE UUIDs.
* @status FROZEN * @status FROZEN
@ -97,16 +95,8 @@ struct nsID {
/** /**
* nsID string encoder. Returns an allocated string in * nsID string encoder. Returns an allocated string in
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string. * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string.
* YOU SHOULD ONLY USE THIS IF YOU CANNOT USE ToProvidedString() BELOW.
*/ */
NS_COM_GLUE char* ToString() const; NS_COM_GLUE char* ToString() const;
/**
* nsID string encoder. Builds a string in
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format, into a char[NSID_LENGTH]
* buffer provided by the caller (for instance, on the stack).
*/
NS_COM_GLUE void ToProvidedString(char (&dest)[NSID_LENGTH]) const;
//@} //@}
}; };