[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / baseassemblyspec.inl
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ============================================================
5 //
6 // BaseAssemblySpec.inl
7 // 
8
9
10 //
11 // Implements the BaseAssemblySpec class
12 //
13 // ============================================================
14
15 #ifndef __BASE_ASSEMBLY_SPEC_INL__
16 #define __BASE_ASSEMBLY_SPEC_INL__
17
18 BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB);
19
20 inline int BaseAssemblySpec::CompareStrings(LPCUTF8 string1, LPCUTF8 string2)
21 {
22     WRAPPER_NO_CONTRACT;
23     SString s1;
24     SString s2;
25     s1.SetUTF8(string1);
26     s2.SetUTF8(string2);        
27     return s1.CompareCaseInsensitive(s2);
28 }
29
30
31 inline BaseAssemblySpec::BaseAssemblySpec()
32 {
33     LIMITED_METHOD_CONTRACT;
34     ZeroMemory(this, sizeof(*this));
35     m_context.usMajorVersion = (USHORT) -1;
36     m_context.usMinorVersion = (USHORT) -1;
37     m_context.usBuildNumber = (USHORT) -1;
38     m_context.usRevisionNumber = (USHORT) -1;
39 };
40
41 inline BaseAssemblySpec::~BaseAssemblySpec()
42 {
43     WRAPPER_NO_CONTRACT;
44     if (m_ownedFlags & NAME_OWNED)
45         delete [] m_pAssemblyName;
46     if (m_ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED)
47         delete [] m_pbPublicKeyOrToken;
48     if (m_wszCodeBase && (m_ownedFlags & CODE_BASE_OWNED))
49         delete [] m_wszCodeBase;
50     if (m_ownedFlags & LOCALE_OWNED)
51         delete [] m_context.szLocale;
52     if (m_szWinRtTypeClassName && (m_ownedFlags & WINRT_TYPE_NAME_OWNED))
53         delete [] m_szWinRtTypeClassName;
54     if (m_szWinRtTypeNamespace && (m_ownedFlags & WINRT_TYPE_NAME_OWNED))
55         delete [] m_szWinRtTypeNamespace;
56 }
57
58 inline HRESULT BaseAssemblySpec::Init(LPCSTR pAssemblyName,
59                          const AssemblyMetaDataInternal* pContext, 
60                          const BYTE * pbPublicKeyOrToken, DWORD cbPublicKeyOrToken,
61                          DWORD dwFlags)
62 {
63     LIMITED_METHOD_CONTRACT;
64
65     _ASSERTE(pContext);
66
67     m_pAssemblyName = pAssemblyName;
68     m_pbPublicKeyOrToken = const_cast<BYTE *>(pbPublicKeyOrToken);
69     m_cbPublicKeyOrToken = cbPublicKeyOrToken;
70     m_dwFlags = dwFlags;
71     m_ownedFlags = 0;
72
73     m_context = *pContext;
74
75     return S_OK;
76 }
77
78 inline HRESULT BaseAssemblySpec::Init(LPCSTR pAssemblyDisplayName)
79 {
80     WRAPPER_NO_CONTRACT;
81     m_pAssemblyName = pAssemblyDisplayName;
82     // We eagerly parse the name to allow FusionBind::Hash to avoid throwing.
83     return ParseName();
84 }
85
86 inline VOID BaseAssemblySpec::CloneFields(int ownedFlags)
87 {
88     CONTRACTL
89     {
90         THROWS;
91         GC_NOTRIGGER;
92         MODE_ANY;
93         INJECT_FAULT(ThrowOutOfMemory(););
94     }
95     CONTRACTL_END
96
97 #if _DEBUG
98     DWORD hash = Hash();
99 #endif
100
101     if ((~m_ownedFlags & NAME_OWNED) && (ownedFlags & NAME_OWNED) &&
102         m_pAssemblyName) {
103         size_t len = strlen(m_pAssemblyName) + 1;
104         LPSTR temp = new char [len];
105         strcpy_s(temp, len, m_pAssemblyName);
106         m_pAssemblyName = temp;
107         m_ownedFlags |= NAME_OWNED;
108     }
109
110     if ((~m_ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED) && 
111         (ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED) && m_pbPublicKeyOrToken) {
112         BYTE *temp = new BYTE [m_cbPublicKeyOrToken];
113         memcpy(temp, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken);
114         m_pbPublicKeyOrToken = temp;
115         m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;
116     }
117
118     if ((~m_ownedFlags & LOCALE_OWNED) && (ownedFlags & LOCALE_OWNED) &&
119         m_context.szLocale) {
120         size_t len = strlen(m_context.szLocale) + 1;
121         LPSTR temp = new char [len];
122         strcpy_s(temp, len, m_context.szLocale);
123         m_context.szLocale = temp;
124         m_ownedFlags |= LOCALE_OWNED;
125     }
126     
127     if ((~m_ownedFlags & CODEBASE_OWNED) && (ownedFlags & CODEBASE_OWNED) &&
128         m_wszCodeBase) {
129         size_t len = wcslen(m_wszCodeBase) + 1;
130         LPWSTR temp = new WCHAR [len];
131         wcscpy_s(temp, len, m_wszCodeBase);
132         m_wszCodeBase = temp;
133         m_ownedFlags |= CODEBASE_OWNED;
134     }
135
136     if ((~m_ownedFlags & WINRT_TYPE_NAME_OWNED) && (ownedFlags & WINRT_TYPE_NAME_OWNED)) {
137             
138         NewArrayHolder<CHAR> nameTemp, namespaceTemp;
139
140         if (m_szWinRtTypeClassName) {
141         
142             size_t nameLen = strlen(m_szWinRtTypeClassName) + 1;
143             nameTemp = new CHAR [nameLen];
144             strcpy_s(nameTemp, nameLen, m_szWinRtTypeClassName);
145         }
146
147         if (m_szWinRtTypeNamespace){
148
149             size_t namespaceLen = strlen(m_szWinRtTypeNamespace) + 1;
150             namespaceTemp = new CHAR [namespaceLen];
151             strcpy_s(namespaceTemp, namespaceLen, m_szWinRtTypeNamespace);
152         }
153             
154         m_szWinRtTypeClassName = nameTemp.Extract();
155         m_szWinRtTypeNamespace = namespaceTemp.Extract();
156         if (m_szWinRtTypeClassName != NULL || m_szWinRtTypeNamespace != NULL)
157         {
158             m_ownedFlags |= WINRT_TYPE_NAME_OWNED;
159         }
160     }
161
162     _ASSERTE(hash == Hash());
163 }
164
165 inline VOID BaseAssemblySpec::CloneFieldsToLoaderHeap(int flags, LoaderHeap *pHeap, AllocMemTracker *pamTracker)
166 {
167     CONTRACTL
168     {
169         INSTANCE_CHECK;
170         THROWS;
171         GC_TRIGGERS;
172         MODE_ANY;
173         INJECT_FAULT(ThrowOutOfMemory(););
174     }
175     CONTRACTL_END
176
177 #if _DEBUG
178     DWORD hash = Hash();
179 #endif
180
181     if ((~m_ownedFlags & NAME_OWNED)  && (flags &NAME_OWNED) &&
182         m_pAssemblyName) {
183         size_t len = strlen(m_pAssemblyName) + 1;
184         LPSTR temp = (LPSTR)pamTracker->Track( pHeap->AllocMem(S_SIZE_T (len)) );
185         strcpy_s(temp, len, m_pAssemblyName);
186         m_pAssemblyName = temp;
187     }
188
189     if ((~m_ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED) && (flags &PUBLIC_KEY_OR_TOKEN_OWNED) &&
190         m_pbPublicKeyOrToken && m_cbPublicKeyOrToken > 0) {
191         BYTE *temp = (BYTE *)pamTracker->Track( pHeap->AllocMem(S_SIZE_T (m_cbPublicKeyOrToken)) );
192         memcpy(temp, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken);
193         m_pbPublicKeyOrToken = temp;
194     }
195
196     if ((~m_ownedFlags & LOCALE_OWNED)  && (flags &LOCALE_OWNED) &&
197         m_context.szLocale) {
198         size_t len = strlen(m_context.szLocale) + 1;
199         LPSTR temp = (char *)pamTracker->Track( pHeap->AllocMem(S_SIZE_T (len)) );
200         strcpy_s(temp, len, m_context.szLocale);
201         m_context.szLocale = temp;
202     }
203
204     if ((~m_ownedFlags & CODEBASE_OWNED)  && (flags &CODEBASE_OWNED) &&
205         m_wszCodeBase) {
206         size_t len = wcslen(m_wszCodeBase) + 1;
207         LPWSTR temp = (LPWSTR)pamTracker->Track( pHeap->AllocMem(S_SIZE_T(len*sizeof(WCHAR))) );
208         wcscpy_s(temp, len, m_wszCodeBase);
209         m_wszCodeBase = temp;
210     }
211
212     if ((~m_ownedFlags & WINRT_TYPE_NAME_OWNED) && (flags & WINRT_TYPE_NAME_OWNED)) {
213         if (m_szWinRtTypeNamespace)
214         {
215             size_t len = strlen(m_szWinRtTypeNamespace) + 1;
216             LPSTR temp = (LPSTR)pamTracker->Track( pHeap->AllocMem(S_SIZE_T(len*sizeof(CHAR))) );
217             strcpy_s(temp, len, m_szWinRtTypeNamespace);
218             m_szWinRtTypeNamespace = temp;
219         }
220
221         if (m_szWinRtTypeClassName)
222         {
223             size_t len = strlen(m_szWinRtTypeClassName) + 1;
224             LPSTR temp = (LPSTR)pamTracker->Track( pHeap->AllocMem(S_SIZE_T(len*sizeof(CHAR))) );
225             strcpy_s(temp, len, m_szWinRtTypeClassName);
226             m_szWinRtTypeClassName = temp;
227         }
228     }
229
230     _ASSERTE(hash == Hash());
231
232 }
233
234
235 inline void BaseAssemblySpec::CopyFrom(const BaseAssemblySpec *pSpec)
236 {
237     CONTRACTL
238     {
239         THROWS;
240         GC_NOTRIGGER;
241         MODE_ANY;
242         INJECT_FAULT(ThrowOutOfMemory(););
243     }
244     CONTRACTL_END
245
246     m_pAssemblyName = pSpec->m_pAssemblyName;
247
248     m_pbPublicKeyOrToken = pSpec->m_pbPublicKeyOrToken;
249     m_cbPublicKeyOrToken = pSpec->m_cbPublicKeyOrToken;
250     m_dwFlags = pSpec->m_dwFlags;
251     m_ownedFlags = 0;
252
253     m_wszCodeBase=pSpec->m_wszCodeBase;
254     m_szWinRtTypeNamespace = pSpec->m_szWinRtTypeNamespace;
255     m_szWinRtTypeClassName = pSpec->m_szWinRtTypeClassName;
256     
257     m_context = pSpec->m_context;
258
259     m_pHostBinder = pSpec->m_pHostBinder;
260
261     if ((pSpec->m_ownedFlags & BAD_NAME_OWNED) != 0)
262     {
263         m_ownedFlags |= BAD_NAME_OWNED;
264     }
265
266
267     m_pBindingContext = pSpec->m_pBindingContext;
268
269 }
270
271
272 inline DWORD BaseAssemblySpec::Hash()
273 {
274     CONTRACTL {
275         INSTANCE_CHECK;
276         NOTHROW;
277         GC_NOTRIGGER;
278         MODE_ANY;
279     } CONTRACTL_END;
280
281     if(m_wszCodeBase)
282         return HashString(m_wszCodeBase);
283
284     // Hash fields.
285     DWORD hash = 0;
286
287     if (m_pAssemblyName)
288         hash ^= HashStringA(m_pAssemblyName);
289     hash = _rotl(hash, 4);
290
291     hash ^= HashBytes(m_pbPublicKeyOrToken, m_cbPublicKeyOrToken);
292     hash = _rotl(hash, 4);
293         
294     hash ^= m_dwFlags;
295     hash = _rotl(hash, 4);
296
297
298     hash ^= m_context.usMajorVersion;
299     hash = _rotl(hash, 8);
300
301     if (m_context.usMajorVersion != (USHORT) -1) {
302         hash ^= m_context.usMinorVersion;
303         hash = _rotl(hash, 8);
304         
305         if (m_context.usMinorVersion != (USHORT) -1) {
306             hash ^= m_context.usBuildNumber;
307             hash = _rotl(hash, 8);
308         
309             if (m_context.usBuildNumber != (USHORT) -1) {
310                 hash ^= m_context.usRevisionNumber;
311                 hash = _rotl(hash, 8);
312             }
313         }
314     }
315
316     if (m_context.szLocale)
317         hash ^= HashStringA(m_context.szLocale);
318     hash = _rotl(hash, 4);
319
320     if (m_szWinRtTypeNamespace)
321     {
322         hash ^= HashStringA(m_szWinRtTypeNamespace);
323         hash = _rotl(hash, 4);
324     }
325
326     if (m_szWinRtTypeClassName)
327     {
328         hash ^= HashStringA(m_szWinRtTypeClassName);
329         hash = _rotl(hash, 4);
330     }
331
332
333     return hash;
334 }
335
336
337 inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompareFlags)
338 {
339     WRAPPER_NO_CONTRACT;
340
341
342     if(m_wszCodeBase || pSpec->m_wszCodeBase)
343     {
344         if(!m_wszCodeBase || !pSpec->m_wszCodeBase)    
345             return FALSE;
346         return wcscmp(m_wszCodeBase,(pSpec->m_wszCodeBase))==0;
347     }
348
349     // Compare fields
350
351     if (m_pAssemblyName != pSpec->m_pAssemblyName
352         && (m_pAssemblyName == NULL || pSpec->m_pAssemblyName == NULL
353             || strcmp(m_pAssemblyName, pSpec->m_pAssemblyName)))
354         return FALSE;
355
356     if (m_cbPublicKeyOrToken != pSpec->m_cbPublicKeyOrToken
357         || memcmp(m_pbPublicKeyOrToken, pSpec->m_pbPublicKeyOrToken, m_cbPublicKeyOrToken))
358         return FALSE;
359
360
361     if (m_dwFlags != pSpec->m_dwFlags)
362         return FALSE;
363
364     if (m_context.usMajorVersion != pSpec->m_context.usMajorVersion)
365         return FALSE;
366
367     if (m_context.usMajorVersion != (USHORT) -1) {
368         if (m_context.usMinorVersion != pSpec->m_context.usMinorVersion)
369             return FALSE;
370
371         if (m_context.usMinorVersion != (USHORT) -1) {
372             if (m_context.usBuildNumber != pSpec->m_context.usBuildNumber)
373                 return FALSE;
374             
375             if (m_context.usBuildNumber != (USHORT) -1) {
376                 if (m_context.usRevisionNumber != pSpec->m_context.usRevisionNumber)
377                     return FALSE;
378             }
379         }
380     }
381
382     if (m_context.szLocale != pSpec->m_context.szLocale
383         && (m_context.szLocale == NULL || pSpec->m_context.szLocale == NULL
384             || strcmp(m_context.szLocale, pSpec->m_context.szLocale)))
385         return FALSE;
386
387
388     // If the assemblySpec contains the binding context, then check if they match.
389     if (!(pSpec->IsAssemblySpecForMscorlib() && IsAssemblySpecForMscorlib()))
390     {
391         if (!AreSameBinderInstance(pSpec->m_pBindingContext, m_pBindingContext))
392         {
393             return FALSE;
394         }
395     }
396
397
398     return TRUE;
399 }
400
401
402 inline HRESULT BaseAssemblySpec::Init(mdToken kAssemblyToken,
403                                   IMDInternalImport *pImport)
404 {
405     CONTRACTL
406     {
407         NOTHROW;
408         GC_NOTRIGGER;
409         MODE_ANY;
410     }
411     CONTRACTL_END;
412
413     HRESULT hr;
414     if (TypeFromToken(kAssemblyToken) == mdtAssembly) {
415
416         IfFailRet(pImport->GetAssemblyProps(kAssemblyToken,
417                                   (const void **) &m_pbPublicKeyOrToken,
418                                   &m_cbPublicKeyOrToken,
419                                   NULL, 
420                                   &m_pAssemblyName,
421                                   &m_context,
422                                   &m_dwFlags));
423         
424         if (m_cbPublicKeyOrToken != 0)
425             m_dwFlags |= afPublicKey;
426     }
427     else
428         IfFailRet(pImport->GetAssemblyRefProps(kAssemblyToken,
429                                      (const void**) &m_pbPublicKeyOrToken,
430                                      &m_cbPublicKeyOrToken,
431                                      &m_pAssemblyName,
432                                      &m_context,
433                                      NULL,
434                                      NULL,
435                                      &m_dwFlags));
436
437     // When m_cbPublicKeyOrToken is 0, a NULL in m_pbPublicKeyOrToken indicates that public key or token
438     // is not specified, while a non-NULL in m_pbPublicKeyOrToken indicates an empty public key (i.e.,
439     // a non-strongnamed assembly).  However, the MetaData API puts a random value in m_pbPublicKeyOrToken
440     // when m_cbPublicKeyOrToken is 0.  Since AssemblyDef or AssemblyRef can't using partial name, we
441     // always ensure that m_pbPublicKeyOrToken is not NULL.
442     if (m_cbPublicKeyOrToken == 0)
443         m_pbPublicKeyOrToken = (PBYTE)1;
444
445     return S_OK;
446 }
447
448 inline HRESULT BaseAssemblySpec::Init(mdToken tkAssemblyRef,
449                                   IMetaDataAssemblyImport  *pImport)
450 {
451     CONTRACTL
452     {
453         NOTHROW;
454         GC_NOTRIGGER;
455         MODE_ANY;
456     }
457     CONTRACTL_END;
458
459     // Retrieve size of assembly name
460     ASSEMBLYMETADATA sContext;
461     LPWSTR wszAssemblyName=NULL;
462     ZeroMemory(&sContext, sizeof(ASSEMBLYMETADATA));
463     HRESULT hr = S_OK;
464     if(TypeFromToken(tkAssemblyRef) == mdtAssembly)
465     {
466         DWORD cchName;
467         IfFailRet(pImport->GetAssemblyProps(tkAssemblyRef,    // [IN] The Assembly for which to get the properties.
468                                             NULL,        // [OUT] Pointer to the public key or token.
469                                             NULL,        // [OUT] Count of bytes in the public key or token.
470                                             NULL,        // [OUT] Hash Algorithm
471                                             NULL,        // [OUT] Buffer to fill with name.
472                                             NULL,        // [IN] Size of buffer in wide chars.
473                                             &cchName,    // [OUT] Actual # of wide chars in name.
474                                             &sContext,   // [OUT] Assembly MetaData.
475                                             NULL));       // [OUT] Flags.
476
477         // Get the assembly name other naming properties
478         wszAssemblyName = (LPWSTR)_alloca(cchName * sizeof(WCHAR));
479         IfFailRet(pImport->GetAssemblyProps(tkAssemblyRef,
480                                             (const void **)&m_pbPublicKeyOrToken,
481                                             &m_cbPublicKeyOrToken,
482                                             NULL,
483                                             wszAssemblyName,
484                                             cchName,
485                                             &cchName,
486                                             &sContext,
487                                             &m_dwFlags));
488     }
489     else if(TypeFromToken(tkAssemblyRef) == mdtAssemblyRef)
490     {
491         DWORD cchName;
492         IfFailRet(pImport->GetAssemblyRefProps(tkAssemblyRef, // [IN] The AssemblyRef for which to get the properties.
493                                             NULL,        // [OUT] Pointer to the public key or token.
494                                             NULL,        // [OUT] Count of bytes in the public key or token.
495                                             NULL,        // [OUT] Buffer to fill with name.
496                                             NULL,        // [IN] Size of buffer in wide chars.
497                                             &cchName,    // [OUT] Actual # of wide chars in name.
498                                             &sContext,   // [OUT] Assembly MetaData.
499                                             NULL,        // [OUT] Hash blob.
500                                             NULL,        // [OUT] Count of bytes in the hash blob.
501                                             NULL));       // [OUT] Flags.
502
503         // Get the assembly name other naming properties
504         wszAssemblyName = (LPWSTR)_alloca(cchName * sizeof(WCHAR));
505         IfFailRet(pImport->GetAssemblyRefProps(tkAssemblyRef,
506                                             (const void **)&m_pbPublicKeyOrToken,
507                                             &m_cbPublicKeyOrToken,
508                                             wszAssemblyName,
509                                             cchName,
510                                             &cchName,
511                                             &sContext,
512                                             NULL,
513                                             NULL,
514                                             &m_dwFlags));
515     }
516     else
517     {
518         _ASSERTE(false && "unexpected token");
519     }
520     MAKE_UTF8PTR_FROMWIDE_NOTHROW(szAssemblyName,wszAssemblyName);
521     IfNullRet(szAssemblyName);
522     size_t len=strlen(szAssemblyName)+1;
523     NewArrayHolder<char> assemblyName(new(nothrow) char[len]);
524     IfNullRet(assemblyName);
525     strcpy_s(assemblyName,len,szAssemblyName);
526
527     m_pAssemblyName=assemblyName.Extract();
528     m_ownedFlags |= CODEBASE_OWNED;
529     SetContext(&sContext);
530     return S_OK;
531 }
532
533 inline void BaseAssemblySpec::SetCodeBase(LPCWSTR szCodeBase)
534 {
535     CONTRACTL
536     {
537         NOTHROW;
538         GC_NOTRIGGER;
539         MODE_ANY;
540     }
541     CONTRACTL_END;
542
543     if(m_wszCodeBase && (m_ownedFlags & CODEBASE_OWNED))
544         delete m_wszCodeBase;
545     m_ownedFlags &= ~CODEBASE_OWNED;
546     m_wszCodeBase=szCodeBase;
547 }
548
549 inline LPCWSTR BaseAssemblySpec::GetCodeBase()
550 {
551     LIMITED_METHOD_CONTRACT;
552     return m_wszCodeBase;
553 }
554
555 inline void BaseAssemblySpec::SetName(LPCSTR szName)
556 {
557     CONTRACTL
558     {
559         INSTANCE_CHECK;
560         GC_NOTRIGGER;
561         NOTHROW;
562     }
563     CONTRACTL_END;
564
565     if (m_pAssemblyName && (m_ownedFlags & NAME_OWNED))
566         delete [] m_pAssemblyName;
567     m_ownedFlags &= ~NAME_OWNED;
568     m_pAssemblyName = szName;
569 }
570
571 inline void BaseAssemblySpec::SetCulture(LPCSTR szCulture)
572 {
573     LIMITED_METHOD_CONTRACT;
574     if (m_context.szLocale && (m_ownedFlags & LOCALE_OWNED))
575         delete [] m_context.szLocale;
576     m_ownedFlags &= ~LOCALE_OWNED;    
577     if (strcmp(szCulture,"neutral")==0)
578         m_context.szLocale="";
579     else
580         m_context.szLocale=szCulture;
581 }
582
583 inline bool BaseAssemblySpec::IsNeutralCulture()
584 {
585     return strcmp(m_context.szLocale,"")==0;
586 }
587
588 inline void BaseAssemblySpec::SetContext(ASSEMBLYMETADATA* assemblyData)
589 {
590     LIMITED_METHOD_CONTRACT;
591     m_context.usMajorVersion=assemblyData->usMajorVersion;
592     m_context.usMinorVersion=assemblyData->usMinorVersion;
593     m_context.usBuildNumber=assemblyData->usBuildNumber;
594     m_context.usRevisionNumber=assemblyData->usRevisionNumber;
595     m_context.rProcessor=assemblyData->rProcessor;
596     m_context.ulProcessor=assemblyData->ulProcessor;
597     m_context.rOS=assemblyData->rOS;
598     m_context.ulOS=assemblyData->ulOS;
599     m_context.szLocale=""; 
600 };
601
602 inline BOOL BaseAssemblySpec::IsStrongNamed() const
603 {
604     LIMITED_METHOD_CONTRACT; 
605     return m_cbPublicKeyOrToken;
606 }
607
608 inline BOOL BaseAssemblySpec::HasPublicKey() const
609 {
610     LIMITED_METHOD_CONTRACT; 
611     return IsAfPublicKey(m_dwFlags) && m_cbPublicKeyOrToken != 0;
612 }
613
614 inline BOOL BaseAssemblySpec::HasPublicKeyToken() const
615 {
616     LIMITED_METHOD_CONTRACT;
617     return IsAfPublicKeyToken(m_dwFlags) && m_cbPublicKeyOrToken != 0;
618 }
619
620 inline LPCSTR BaseAssemblySpec::GetName()  const
621
622     LIMITED_METHOD_CONTRACT; 
623     return m_pAssemblyName; 
624 }
625
626
627
628 inline BOOL BaseAssemblySpec::VerifyBindingString(LPCWSTR pwStr) 
629 {
630     WRAPPER_NO_CONTRACT;
631     if (wcschr(pwStr, '\\') ||
632         wcschr(pwStr, '/') ||
633         wcschr(pwStr, ':'))
634         return FALSE;
635
636     return TRUE;
637 }
638
639
640 #endif // __BASE_ASSEMBLY_SPEC_INL__