version 1.3, 2015/04/20 18:10:14
|
version 1.4, 2015/04/20 18:19:56
|
|
|
| |
#include <stdio.h> | #include <stdio.h> |
#include <ctype.h> | #include <ctype.h> |
#include <base/strings.h> |
#include <pal/strings.h> |
#include <base/io.h> |
#include <pal/format.h> |
#include <base/dir.h> |
#include <base/log.h> |
#include <base/paths.h> | #include <base/paths.h> |
|
#include <base/naming.h> |
#include "provreg.h" | #include "provreg.h" |
#include "regfile.h" | #include "regfile.h" |
| |
|
|
typedef struct _ProvRegNamespaceNode | typedef struct _ProvRegNamespaceNode |
{ | { |
struct _ProvRegNamespaceNode* next; | struct _ProvRegNamespaceNode* next; |
|
|
typedef struct _ProvRegClassInheritanceNode | typedef struct _ProvRegClassInheritanceNode |
{ | { |
MI_ConstString cn; | MI_ConstString cn; |
|
const char* library; |
|
ProvHosting hosting; |
|
const char* user; |
struct _ProvRegClassInheritanceNode* parent; | struct _ProvRegClassInheritanceNode* parent; |
struct _ProvRegClassInheritanceNode* nextSibling; | struct _ProvRegClassInheritanceNode* nextSibling; |
struct _ProvRegClassInheritanceNode* firstChild; | struct _ProvRegClassInheritanceNode* firstChild; |
|
|
ProvRegClassInheritanceNode; | ProvRegClassInheritanceNode; |
| |
#if (MI_CHAR_TYPE == 1) | #if (MI_CHAR_TYPE == 1) |
#define MI_ScasecmpChar_MIChar Zcasecmp |
#define MI_ScasecmpChar_MIChar Tcscasecmp |
#else | #else |
static int MI_ScasecmpChar_MIChar( | static int MI_ScasecmpChar_MIChar( |
const char* str1, | const char* str1, |
const MI_Char* str2 ) |
const ZChar* str2 ) |
{ | { |
/* assuming str2 is ascii char-set only */ | /* assuming str2 is ascii char-set only */ |
for(;;) | for(;;) |
|
|
| |
/* returns last segment from the string or string itself; | /* returns last segment from the string or string itself; |
for example, for string abc,edf,ghk function returns 'ghk', 'edf' and 'abc' */ | for example, for string abc,edf,ghk function returns 'ghk', 'edf' and 'abc' */ |
static char* _GetNextReverse(char** text, char delim) |
static char* _GetNextReverse(_Inout_ CharPtr* text, char delim) |
{ | { |
char* start = *text; | char* start = *text; |
char* end; | char* end; |
|
|
*end = 0; | *end = 0; |
end++; | end++; |
} | } |
|
#ifdef _MSC_VER |
|
#pragma prefast(push) |
|
#pragma prefast (disable: 26016) |
|
#endif |
| |
/* Skip leading whitespace */ | /* Skip leading whitespace */ |
while (*end && isspace((unsigned char)*end)) | while (*end && isspace((unsigned char)*end)) |
end++; | end++; |
| |
return end; |
#ifdef _MSC_VER |
} |
#pragma prefast(pop) |
|
#endif |
static char* _Strdup(Batch* batch, const char* s) |
|
{ |
|
size_t size = strlen(s) + 1; |
|
char* p; |
|
size_t i; |
|
|
|
p = Batch_Get(batch, size * sizeof(char)); |
|
|
|
if (!p) |
|
return NULL; |
|
|
|
for (i = 0; i < size; i++) |
|
p[i] = s[i]; |
|
|
|
return p; |
|
} |
|
|
|
static MI_Char* _Strdup2(Batch* batch, const char* s) |
|
{ |
|
size_t size = strlen(s) + 1; |
|
MI_Char* p; |
|
size_t i; |
|
|
|
p = Batch_Get(batch, size * sizeof(MI_Char)); |
|
|
|
if (!p) |
|
return NULL; |
|
|
|
for (i = 0; i < size; i++) |
|
p[i] = (MI_Char)s[i]; |
|
| |
return p; |
return end; |
} | } |
| |
/* ********************************************************* */ | /* ********************************************************* */ |
|
|
| |
ProvRegNamespaceNode* _FindNamespace( | ProvRegNamespaceNode* _FindNamespace( |
ProvReg* self, | ProvReg* self, |
MI_ConstString ns) |
MI_ConstString ns, |
|
MI_Boolean extraClass) |
{ | { |
/* find namespace node in the list */ | /* find namespace node in the list */ |
ProvRegNamespaceNode* current = self->namespaces; |
ProvRegNamespaceNode* current; |
|
if(extraClass) |
|
current = self->namespacesForExtraClasses; |
|
else |
|
current = self->namespaces; |
| |
while (current && Zcasecmp(ns,current->ns) != 0) |
while (current && Tcscasecmp(ns,current->ns) != 0) |
current = current->next; | current = current->next; |
| |
return current; | return current; |
|
|
| |
ProvRegNamespaceNode* _FindOrCreateNamespace( | ProvRegNamespaceNode* _FindOrCreateNamespace( |
ProvReg* self, | ProvReg* self, |
MI_ConstString ns) |
MI_ConstString ns, |
|
MI_Boolean extraClass) |
{ | { |
ProvRegNamespaceNode* item = _FindNamespace(self,ns); |
ProvRegNamespaceNode* item = _FindNamespace(self,ns, extraClass); |
| |
if (item) | if (item) |
return item; | return item; |
|
|
| |
if (item) | if (item) |
{ | { |
|
if(extraClass) |
|
{ |
|
size_t size; |
|
size = Tcslen(ns) + 1; |
|
|
|
{ |
|
ZChar* nameSpace = Batch_Get(&self->batch, size * sizeof(ZChar)); |
|
if(nameSpace == NULL) |
|
{ |
|
trace_OutOfMemory(); |
|
return NULL; |
|
} |
|
Tcslcpy(nameSpace, ns, size); |
|
|
|
item->ns = nameSpace; |
|
item->next = self->namespacesForExtraClasses; |
|
self->namespacesForExtraClasses = item; |
|
} |
|
} |
|
else |
|
{ |
item->ns = ns; /* no need to strdup, since it's already in batch*/ | item->ns = ns; /* no need to strdup, since it's already in batch*/ |
item->next = self->namespaces; | item->next = self->namespaces; |
self->namespaces = item; | self->namespaces = item; |
} | } |
|
} |
| |
return item; | return item; |
} | } |
|
|
{ | { |
item = item->parent; | item = item->parent; |
| |
if (item->nextSibling) |
if (item && item->nextSibling) |
return item->nextSibling; | return item->nextSibling; |
} | } |
| |
|
|
| |
ProvRegClassInheritanceNode* _FindClassNodeInTree( | ProvRegClassInheritanceNode* _FindClassNodeInTree( |
ProvRegClassInheritanceNode* root, | ProvRegClassInheritanceNode* root, |
const MI_Char* cn) |
const ZChar* cn) |
{ | { |
while (root) | while (root) |
{ | { |
if (Zcasecmp(cn,root->cn)==0) |
if (Tcscasecmp(cn,root->cn)==0) |
{ | { |
return root; | return root; |
} | } |
|
|
ProvReg* self, | ProvReg* self, |
MI_ConstString ns, | MI_ConstString ns, |
const char* derivedClass, /* can be null */ | const char* derivedClass, /* can be null */ |
const char* baseClass ) |
const char* baseClass, |
|
const char* library, |
|
ProvHosting hosting, |
|
const char* user, |
|
MI_Boolean extraClass) |
{ | { |
/* get (or create if needed) namespace item */ | /* get (or create if needed) namespace item */ |
ProvRegNamespaceNode* namespaceNode = _FindOrCreateNamespace(self,ns); |
ProvRegNamespaceNode* namespaceNode = _FindOrCreateNamespace(self,ns, extraClass); |
ProvRegClassInheritanceNode* derivedNode, *baseNode; | ProvRegClassInheritanceNode* derivedNode, *baseNode; |
| |
if (!namespaceNode) | if (!namespaceNode) |
|
|
if ( !baseNode ) | if ( !baseNode ) |
return MI_RESULT_FAILED; | return MI_RESULT_FAILED; |
| |
baseNode->cn = _Strdup2(&self->batch, baseClass); |
baseNode->cn = Batch_StrTcsdup(&self->batch, baseClass); |
|
baseNode->library = Batch_Strdup(&self->batch, library); |
|
baseNode->hosting = hosting; |
|
if(user) |
|
{ |
|
baseNode->user = Batch_Strdup(&self->batch, user); |
|
if(!baseNode->user) |
|
return MI_RESULT_FAILED; |
|
} |
| |
if ( !baseNode->cn ) |
if ( !baseNode->cn || !baseNode->library) |
return MI_RESULT_FAILED; | return MI_RESULT_FAILED; |
| |
/* insert into tree */ | /* insert into tree */ |
|
|
if ( !derivedNode ) | if ( !derivedNode ) |
return MI_RESULT_FAILED; | return MI_RESULT_FAILED; |
| |
derivedNode->cn = _Strdup2(&self->batch, derivedClass); |
derivedNode->cn = Batch_StrTcsdup(&self->batch, derivedClass); |
|
derivedNode->library = Batch_Strdup(&self->batch, library); |
|
derivedNode->hosting = hosting; |
|
if(user) |
|
{ |
|
derivedNode->user = Batch_Strdup(&self->batch, user); |
|
if(!derivedNode->user) |
|
return MI_RESULT_FAILED; |
|
} |
| |
if ( !derivedNode->cn ) |
if ( !derivedNode->cn || !derivedNode->library) |
return MI_RESULT_FAILED; | return MI_RESULT_FAILED; |
| |
/* add as a child */ | /* add as a child */ |
|
|
ProvRegClassInheritanceNode *leftNode, *rightNode, *assocNode; | ProvRegClassInheritanceNode *leftNode, *rightNode, *assocNode; |
| |
/* check namespace */ | /* check namespace */ |
namespaceNode = _FindNamespace(self,ns); |
namespaceNode = _FindNamespace(self,ns, MI_FALSE); |
| |
if (!namespaceNode) | if (!namespaceNode) |
return MI_RESULT_INVALID_NAMESPACE; | return MI_RESULT_INVALID_NAMESPACE; |
|
|
static MI_Result _GetSubclasses2( | static MI_Result _GetSubclasses2( |
ProvReg* self, | ProvReg* self, |
ProvRegEntry* e, | ProvRegEntry* e, |
char* p) |
_Inout_ CharPtr p) |
{ | { |
/* get all sub-classes */ | /* get all sub-classes */ |
char* baseClass = _GetNextReverse(&p, ':'); | char* baseClass = _GetNextReverse(&p, ':'); |
|
|
while ( derivedClass ) | while ( derivedClass ) |
{ | { |
r = _AddClassInheritanceInfo(self, e->nameSpace, derivedClass, | r = _AddClassInheritanceInfo(self, e->nameSpace, derivedClass, |
baseClass); |
baseClass, e->libraryName, e->hosting, e->user, MI_FALSE); |
| |
if ( MI_RESULT_OK != r ) | if ( MI_RESULT_OK != r ) |
return r; | return r; |
|
|
} | } |
| |
/* add base class with no parent */ | /* add base class with no parent */ |
r = _AddClassInheritanceInfo(self, e->nameSpace, derivedClass, baseClass); |
r = _AddClassInheritanceInfo(self, e->nameSpace, derivedClass, baseClass, e->libraryName, e->hosting, e->user, MI_FALSE); |
if (MI_RESULT_OK != r) | if (MI_RESULT_OK != r) |
return r; | return r; |
| |
e->className = _Strdup2(&self->batch, baseClass); |
e->className = Batch_StrTcsdup(&self->batch, baseClass); |
if (!e->className) | if (!e->className) |
{ | { |
return MI_RESULT_FAILED; | return MI_RESULT_FAILED; |
} | } |
|
e->classNameHash = Hash(e->className); |
| |
return MI_RESULT_OK; | return MI_RESULT_OK; |
} | } |
|
|
e->provInterface = PROV_INTERFACE_STATIK; | e->provInterface = PROV_INTERFACE_STATIK; |
| |
/* ProvRegEntry.nameSpace */ | /* ProvRegEntry.nameSpace */ |
e->nameSpace = _Strdup2(&self->batch, nameSpace); |
e->nameSpace = Batch_StrTcsdup(&self->batch, nameSpace); |
|
if (!e->nameSpace) |
|
return -1; |
|
|
|
e->nameSpaceHash = Hash(e->nameSpace); |
| |
/* ProvRegEntry.libraryName */ | /* ProvRegEntry.libraryName */ |
e->libraryName = _Strdup(&self->batch, regFile->library); |
e->libraryName = Batch_Strdup(&self->batch, regFile->library); |
|
if (!e->libraryName) |
|
{ |
|
trace_ProvReg_ProvRegEntry_NULLLibraryName(nameSpace, regClass->name); |
|
return -1; |
|
} |
|
|
|
#if defined(CONFIG_ENABLE_PREEXEC) |
|
|
|
/* ProvRegEntry.preexec */ |
|
if (regFile->preexec) |
|
{ |
|
e->preexec = Batch_Strdup(&self->batch, regFile->preexec); |
|
if (!e->preexec) |
|
return -1; |
|
} |
|
|
|
#endif /* defined(CONFIG_ENABLE_PREEXEC) */ |
| |
/* ProvRegEntry.hosting*/ | /* ProvRegEntry.hosting*/ |
e->hosting = PROV_HOSTING_INPROC; | e->hosting = PROV_HOSTING_INPROC; |
| |
|
e->regType = regClass->regtype; |
|
|
|
e->instanceLifetimeContext = regFile->instanceLifetimeContext; |
|
|
if (regClass->hosting) | if (regClass->hosting) |
{ | { |
char hosting[64]; | char hosting[64]; |
|
|
else | else |
{ | { |
e->hosting = PROV_HOSTING_USER; | e->hosting = PROV_HOSTING_USER; |
e->user = _Strdup(&self->batch, hosting); |
e->user = Batch_Strdup(&self->batch, hosting); |
if (!e->user) | if (!e->user) |
return -1; | return -1; |
} | } |
|
|
return 0; | return 0; |
} | } |
| |
MI_Result ProvReg_Init2(ProvReg* self) |
static int _AddEntryForExtraClass( |
|
ProvReg* self, |
|
const char* nameSpace, |
|
RegFile* regFile, |
|
RegClass* regClass) |
|
{ |
|
/* get all sub-classes */ |
|
ProvHosting hosting; |
|
const char* user = NULL; |
|
CharPtr p = regClass->name; |
|
char* baseClass = _GetNextReverse(&p, ':'); |
|
char* derivedClass = _GetNextReverse(&p, ':'); |
|
MI_Result r; |
|
size_t size = strlen(nameSpace) + 1; |
|
|
|
hosting = PROV_HOSTING_INPROC; |
|
|
|
if (regClass->hosting) |
{ | { |
|
/* it either user name or one of two special values: |
|
* @inproc@ |
|
* @requestor@ |
|
*/ |
|
if (strcmp(regClass->hosting, PROV_REG_HOSTING_INPROC) == 0) |
|
{ |
|
hosting = PROV_HOSTING_INPROC; |
|
} |
|
else if (strcmp(regClass->hosting, PROV_REG_HOSTING_REQUESTOR) == 0) |
|
{ |
|
hosting = PROV_HOSTING_REQUESTOR; |
|
} |
|
else |
|
{ |
|
hosting = PROV_HOSTING_USER; |
|
user = regClass->hosting; |
|
} |
|
} |
|
|
|
#if 0 |
|
RegFile_Print(regFile, stdout); |
|
#endif |
|
|
|
/* expecting to find at least one class */ |
|
if (!baseClass) |
|
return MI_RESULT_INVALID_CLASS; |
|
|
|
{ |
|
ZChar s[PAL_MAX_PATH_SIZE]; |
|
size_t i; |
|
|
|
if(size > PAL_MAX_PATH_SIZE) |
|
return -1; |
|
|
|
for(i=0; i < size; i++) |
|
s[i] = (ZChar) nameSpace[i]; |
|
|
|
while ( derivedClass ) |
|
{ |
|
r = _AddClassInheritanceInfo(self, s, derivedClass, |
|
baseClass, regFile->library, hosting, user, MI_TRUE); |
|
|
|
if ( MI_RESULT_OK != r ) |
|
return r; |
|
|
|
baseClass = derivedClass; |
|
derivedClass = _GetNextReverse(&p, ':'); |
|
} |
|
|
|
/* add base class with no parent */ |
|
r = _AddClassInheritanceInfo(self, s, derivedClass, |
|
baseClass, regFile->library, hosting, user, MI_TRUE); |
|
|
|
if (MI_RESULT_OK != r) |
|
return -1; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
/* Initialize ProvReg strucutre from given directory */ |
|
_Use_decl_annotations_ |
|
MI_Result ProvReg_Init(ProvReg* self, const char* directory) |
|
{ |
|
RegFile* reg = NULL; |
Dir* dir = NULL; | Dir* dir = NULL; |
Dir* dir2 = NULL; | Dir* dir2 = NULL; |
RegFile* reg = NULL; |
MI_Result r = MI_RESULT_FAILED; |
Batch* b = NULL; |
|
| |
/* Zero-fill self */ | /* Zero-fill self */ |
memset(self, 0, sizeof(*self)); | memset(self, 0, sizeof(*self)); |
| |
|
dir = Dir_Open(directory); |
|
if (!dir) |
|
{ |
|
return r; |
|
} |
|
|
/* Initialize batch allocator */ | /* Initialize batch allocator */ |
Batch_Init(&self->batch, BATCH_MAX_PAGES); | Batch_Init(&self->batch, BATCH_MAX_PAGES); |
b = &self->batch; |
|
|
|
/* Open the 'omiregister' directory */ |
|
dir = Dir_Open(GetPath(ID_REGISTERDIR)); |
|
if (!dir) |
|
return MI_RESULT_FAILED; |
|
| |
/* For each namespace directory in 'omirgister' */ | /* For each namespace directory in 'omirgister' */ |
for (;;) | for (;;) |
{ | { |
DirEnt* ent = Dir_Read(dir); | DirEnt* ent = Dir_Read(dir); |
|
|
if (!ent) | if (!ent) |
|
{ |
break; | break; |
|
} |
| |
/* Ignore system directories */ | /* Ignore system directories */ |
if (strcmp(ent->name, ".") == 0 || strcmp(ent->name, "..") == 0) | if (strcmp(ent->name, ".") == 0 || strcmp(ent->name, "..") == 0) |
|
|
| |
/* Scan .reg files in the current namespace directory */ | /* Scan .reg files in the current namespace directory */ |
{ | { |
char path[MAX_PATH_SIZE]; |
char path[PAL_MAX_PATH_SIZE]; |
| |
Strlcpy(path, GetPath(ID_REGISTERDIR), sizeof(path)); |
Strlcpy(path, directory, sizeof(path)); |
Strlcat(path, "/", sizeof(path)); | Strlcat(path, "/", sizeof(path)); |
Strlcat(path, ent->name, sizeof(path)); | Strlcat(path, ent->name, sizeof(path)); |
| |
|
/* Skip if not a dir */ |
|
if(!Isdir(path)) |
|
continue; |
|
|
dir2 = Dir_Open(path); | dir2 = Dir_Open(path); |
if (!dir2) | if (!dir2) |
{ | { |
|
|
{ | { |
DirEnt* ent2 = Dir_Read(dir2); | DirEnt* ent2 = Dir_Read(dir2); |
if (!ent2) | if (!ent2) |
|
{ |
break; | break; |
|
} |
| |
/* Ignore system directories */ | /* Ignore system directories */ |
if (strcmp(ent2->name,".") == 0 || strcmp(ent2->name,"..") == 0) | if (strcmp(ent2->name,".") == 0 || strcmp(ent2->name,"..") == 0) |
|
{ |
|
continue; |
|
} |
|
|
|
/* Skip non-reg file */ |
|
{ |
|
char* affix = Strrchr(ent2->name, '.'); |
|
if (!affix || (Strcasecmp(&affix[1], "reg") != 0)) |
continue; | continue; |
|
} |
| |
/* Load the reg file */ | /* Load the reg file */ |
{ | { |
char regPath[MAX_PATH_SIZE]; |
char regPath[PAL_MAX_PATH_SIZE]; |
| |
/* Form path to .reg file */ | /* Form path to .reg file */ |
Strlcpy(regPath, path, sizeof(regPath)); | Strlcpy(regPath, path, sizeof(regPath)); |
|
|
reg = RegFile_New(regPath); | reg = RegFile_New(regPath); |
if (!reg) | if (!reg) |
{ | { |
goto failed; |
trace_ProvReg_SkipRegFile(scs(regPath)); |
|
continue; |
} | } |
| |
/* For each class in the reg file */ | /* For each class in the reg file */ |
{ | { |
RegClass* rc; | RegClass* rc; |
|
char* p = ent->name; |
|
|
|
/* Transpose NAMESPACE_SEPARATOR characters to '/' |
|
* characters |
|
*/ |
|
while (*p) |
|
{ |
|
if (*p == NAMESPACE_SEPARATOR) |
|
*p = '/'; |
|
p++; |
|
} |
| |
for (rc = reg->classesHead; rc; rc = rc->next) | for (rc = reg->classesHead; rc; rc = rc->next) |
{ | { |
|
if (_AddEntry(self, ent->name, reg, rc) != 0) |
|
{ |
|
goto failed; |
|
} |
|
} |
|
} |
|
|
|
/* For each extraClass in the reg file */ |
|
{ |
|
RegClass* rc; |
char* p = ent->name; | char* p = ent->name; |
| |
/* Transpose '#' characters to '/' characters */ |
/* Transpose NAMESPACE_SEPARATOR characters to '/' |
|
* characters |
|
*/ |
while (*p) | while (*p) |
{ | { |
if (*p == '#') |
if (*p == NAMESPACE_SEPARATOR) |
*p = '/'; | *p = '/'; |
p++; | p++; |
} | } |
| |
if (_AddEntry(self, ent->name, reg, rc) != 0) |
for (rc = reg->extraClassesHead; rc; rc = rc->next) |
|
{ |
|
if (_AddEntryForExtraClass(self, ent->name, reg, rc) != 0) |
{ | { |
goto failed; | goto failed; |
} | } |
|
|
dir2 = NULL; | dir2 = NULL; |
} | } |
} | } |
|
r = MI_RESULT_OK; |
/* Close directory */ |
|
Dir_Close(dir); |
|
|
|
return MI_RESULT_OK; |
|
| |
failed: | failed: |
|
|
if (dir) |
|
Dir_Close(dir); |
|
|
|
if (dir2) | if (dir2) |
|
{ |
Dir_Close(dir2); | Dir_Close(dir2); |
|
} |
|
if (dir) |
|
{ |
|
Dir_Close(dir); |
|
} |
|
if (r != MI_RESULT_OK) |
|
{ |
|
ProvReg_Destroy(self); |
|
memset(self, 0, sizeof(*self)); |
|
} |
|
if(reg) |
|
{ |
|
RegFile_Delete(reg); |
|
reg = NULL; |
|
} |
|
return r; |
|
} |
| |
return MI_RESULT_FAILED; |
/* Initialize ProvReg strucutre from omiregister directory */ |
|
_Use_decl_annotations_ |
|
MI_Result ProvReg_Init2(ProvReg* self) |
|
{ |
|
return ProvReg_Init(self, OMI_GetPath(ID_REGISTERDIR)); |
} | } |
| |
void ProvReg_Destroy( | void ProvReg_Destroy( |
|
|
| |
for (p = self->head; p; p = p->next) | for (p = self->head; p; p = p->next) |
{ | { |
fprintf(os, "==== ProvRegEntry\n"); |
Ftprintf(os, PAL_T("==== ProvRegEntry\n")); |
fprintf(os, "provInterface[%u]\n", p->provInterface); |
Ftprintf(os, PAL_T("provInterface[%u]\n"), p->provInterface); |
Fzprintf(os, MI_T("nameSpace[%s]\n"), p->nameSpace); |
Ftprintf(os, PAL_T("nameSpace[%T]\n"), tcs(p->nameSpace)); |
Fzprintf(os, MI_T("className[%s]\n"), p->className); |
Ftprintf(os, PAL_T("className[%T]\n"), tcs(p->className)); |
fprintf(os, "libraryName[%s]\n", p->libraryName); |
Ftprintf(os, PAL_T("libraryName[%s]\n"), scs(p->libraryName)); |
} | } |
} | } |
| |
const ProvRegEntry* ProvReg_FindProviderForClass( | const ProvRegEntry* ProvReg_FindProviderForClass( |
ProvReg* self, | ProvReg* self, |
const MI_Char* nameSpace, |
const ZChar* nameSpace, |
const MI_Char* className) |
const ZChar* className, |
|
MI_Result *findError) |
{ | { |
ProvRegEntry* p; |
return ProvReg_FindProviderForClassByType(self, nameSpace, className, PROVREG_DEFAULT, findError); |
|
|
for (p = self->head; p; p = p->next) |
|
{ |
|
if (Zcasecmp(p->className, className) == 0 && |
|
Zcasecmp(p->nameSpace, nameSpace) == 0) |
|
return p; |
|
} | } |
| |
/* Not found */ |
|
return NULL; |
|
} |
|
| |
/* returns ok or not-found; baseClass will be null if no base class exist */ | /* returns ok or not-found; baseClass will be null if no base class exist */ |
MI_Result ProvReg_GetDirectBaseClass( | MI_Result ProvReg_GetDirectBaseClass( |
ProvReg* self, | ProvReg* self, |
const MI_Char* nameSpace, |
const ZChar* nameSpace, |
const MI_Char* className, |
const ZChar* className, |
const MI_Char** baseClass) |
const ZChar** baseClass, |
|
MI_Boolean extraClass) |
{ | { |
ProvRegClassInheritanceNode* classNode; | ProvRegClassInheritanceNode* classNode; |
ProvRegNamespaceNode* namespaceNode; | ProvRegNamespaceNode* namespaceNode; |
|
|
*baseClass = 0; | *baseClass = 0; |
| |
/* check namespace */ | /* check namespace */ |
namespaceNode = _FindNamespace(self,nameSpace); |
namespaceNode = _FindNamespace(self,nameSpace, extraClass); |
| |
if (!namespaceNode) | if (!namespaceNode) |
return MI_RESULT_INVALID_NAMESPACE; | return MI_RESULT_INVALID_NAMESPACE; |
|
|
*/ | */ |
MI_Result ProvReg_BeginClasses( | MI_Result ProvReg_BeginClasses( |
ProvReg* self, | ProvReg* self, |
const MI_Char* nameSpace, |
const ZChar* nameSpace, |
const MI_Char* className, |
const ZChar* className, |
MI_Boolean deep, | MI_Boolean deep, |
ProvRegPosition* pos) |
ProvRegPosition* pos, |
|
MI_Boolean extraClass) |
{ | { |
ProvRegNamespaceNode* namespaceNode; | ProvRegNamespaceNode* namespaceNode; |
| |
|
|
pos->deep = deep; | pos->deep = deep; |
| |
/* check namespace */ | /* check namespace */ |
namespaceNode = _FindNamespace(self,nameSpace); |
namespaceNode = _FindNamespace(self,nameSpace, extraClass); |
| |
if (!namespaceNode) | if (!namespaceNode) |
return MI_RESULT_INVALID_NAMESPACE; | return MI_RESULT_INVALID_NAMESPACE; |
|
|
| |
MI_Result ProvReg_NextClass( | MI_Result ProvReg_NextClass( |
ProvRegPosition* pos, | ProvRegPosition* pos, |
const MI_Char** className, |
const ZChar** className, |
MI_Boolean* done) | MI_Boolean* done) |
{ | { |
if (!pos->current) | if (!pos->current) |
|
|
return MI_RESULT_OK; | return MI_RESULT_OK; |
} | } |
| |
|
|
|
|
/* returns enumerator to all registered association classes by given instance class | /* returns enumerator to all registered association classes by given instance class |
and (optionally) assoc/result classes */ | and (optionally) assoc/result classes */ |
MI_EXPORT MI_Result ProvReg_BeginAssocClasses( | MI_EXPORT MI_Result ProvReg_BeginAssocClasses( |
ProvReg* self, | ProvReg* self, |
const MI_Char* nameSpace, |
const ZChar* nameSpace, |
const MI_Char* className, |
const ZChar* className, |
const MI_Char* assocClassName, /* can be NULL */ |
const ZChar* assocClassName, /* can be NULL */ |
const MI_Char* resultClassName, /* can be NULL */ |
const ZChar* resultClassName, /* can be NULL */ |
ProvRegAssocPosition* pos) | ProvRegAssocPosition* pos) |
{ | { |
ProvRegNamespaceNode* namespaceNode; | ProvRegNamespaceNode* namespaceNode; |
|
|
memset( pos, 0, sizeof(*pos)); | memset( pos, 0, sizeof(*pos)); |
| |
/* check namespace */ | /* check namespace */ |
namespaceNode = _FindNamespace(self,nameSpace); |
namespaceNode = _FindNamespace(self,nameSpace, MI_FALSE); |
| |
if (!namespaceNode) | if (!namespaceNode) |
return MI_RESULT_INVALID_NAMESPACE; | return MI_RESULT_INVALID_NAMESPACE; |
|
|
| |
MI_EXPORT MI_Result ProvReg_NextAssocClass( | MI_EXPORT MI_Result ProvReg_NextAssocClass( |
ProvRegAssocPosition* pos, | ProvRegAssocPosition* pos, |
const MI_Char** className, |
const ZChar** className, |
MI_Boolean* done) | MI_Boolean* done) |
{ | { |
/* navigate to next */ | /* navigate to next */ |
|
|
return MI_RESULT_OK; | return MI_RESULT_OK; |
} | } |
| |
|
void MapRegPositionValuesToRegEntry( |
|
ProvRegEntry* reg, |
|
ProvRegPosition* pos) |
|
{ |
|
if(reg && pos) |
|
{ |
|
reg->className = pos->start->cn; |
|
reg->classNameHash = Hash(pos->start->cn); |
|
reg->hosting = pos->start->hosting; |
|
reg->libraryName = pos->start->library; |
|
//reg->provInterface |
|
reg->next = NULL; |
|
reg->user = pos->start->user; |
|
} |
|
} |
|
|
|
/* Find event steam provider under given namespace */ |
|
_Use_decl_annotations_ |
|
const ProvRegEntry* ProvReg_FindProviderForClassByType( |
|
ProvReg* self, |
|
const ZChar* nameSpace, |
|
const ZChar* className, |
|
ProvRegType type, |
|
MI_Result *findError) |
|
{ |
|
ProvRegEntry* p; |
|
MI_Boolean namespaceFound = 0; |
|
unsigned int nameSpaceHash = Hash(nameSpace); |
|
unsigned int classNameHash = 0; |
|
if (!className) |
|
{ |
|
if(findError) |
|
*findError = MI_RESULT_INVALID_PARAMETER; |
|
return NULL; |
|
} |
|
if (className) |
|
classNameHash = Hash(className); |
|
|
|
for (p = self->head; p; p = p->next) |
|
{ |
|
// comparing namespace everytime may slightly affect perf |
|
// but it enables us to give right error back to the client |
|
if (nameSpaceHash == p->nameSpaceHash && |
|
Tcscasecmp(p->nameSpace, nameSpace) == 0) |
|
{ |
|
if (p->regType == type) |
|
{ |
|
if (className) |
|
{ |
|
/* for normal and indication class */ |
|
if( classNameHash == p->classNameHash && |
|
Tcscasecmp(p->className, className) == 0) |
|
{ |
|
if(findError) |
|
{ |
|
*findError = MI_RESULT_OK; |
|
} |
|
return p; |
|
} |
|
} |
|
else |
|
{ |
|
/* for event stream class */ |
|
if(findError) |
|
{ |
|
*findError = MI_RESULT_OK; |
|
} |
|
return p; |
|
} |
|
namespaceFound = MI_TRUE; |
|
} |
|
} |
|
} |
|
|
|
if(findError) |
|
{ |
|
*findError = (MI_TRUE == namespaceFound) ? MI_RESULT_INVALID_CLASS : MI_RESULT_INVALID_NAMESPACE; |
|
} |
|
/* Not found */ |
|
return NULL; |
|
} |