bool hcp::Runtime::hasExtension(const char* path, const char* extension) { if (!path || !extension) { return false; } hcp_Int pathLen = hcp_szStrLen((hcp_cszStr)path); hcp_Int extLen = hcp_szStrLen((const hcp_szStr)extension); if (extLen >= pathLen) { return false; } const char* lhs = (const char*)((hcp_Size_t)path + (hcp_Size_t)pathLen); const char* rhs = (const char*)((hcp_Size_t)extension + (hcp_Size_t)extLen); while (rhs != extension) { char expected = *(rhs--); char actual = *(lhs--); // ignore case, cast all to caps expected = expected >= 97 && expected <= 122 ? (int)expected - 32 : expected; actual = actual >= 97 && actual <= 122 ? (int)actual - 32 : actual; if (expected != actual) { return false; } } return true; }
hcp_Int hcp_GetUint8(const hcp_tProtocol* pProtocol, const hcp_szStr Key, hcp_Uint8* pDest) { *pDest = 0; hcp_tString key; key.value = Key; key.length = hcp_szStrLen(Key); key.zeroTerm = HCP_TRUE; hcp_Boolean found = HCP_FALSE; hcp_Size_t index = hcp_FindFirst(&pProtocol->header, 0, &key, &found); if (found == HCP_FALSE) { return HCP_MISSINGCODECNODE; } hcp_tProtocolNode* node = (hcp_tProtocolNode*)hcp_ValueAt(&pProtocol->header, index); *pDest = (hcp_Uint8)hcp_Atio(&node->value); return HCP_NOERROR; }
hcp::Runtime* hcp_init_runtime(hcp_cszStr codecPath) { if (_r == nullptr) { hcp_tHost host; memset(&host, 0, sizeof(hcp_tHost)); host.free_ = _free; host.malloc_ = _malloc; host.memcpy_ = _memcpy; host.memset_ = _memset; _r = new hcp::Runtime(&host); } char const* err = nullptr; if (codecPath != nullptr && hcp_szStrLen(codecPath) > 0) { if (!_r->scanDir(codecPath, &err)) { } } return _r; }
bool hcp::Runtime::scanDir(const char* codecPath,const char** error) { uv_fs_t req; int numFiles = uv_fs_scandir(uv_default_loop(), &req, codecPath, UV_FS_SCANDIR, nullptr); if (numFiles < 0) { if (error) { *error = uv_strerror(numFiles); } return false; } for (int i = 0; i < numFiles; i++) { uv_dirent_t ent; hcp::tCodec codec; int r = uv_fs_scandir_next(&req, &ent); if (r == UV_EOF) { break; } hcp_Boolean found = HCP_FALSE; // skip codecs with duplicate name hcp_FindFirst(&_codecs.header, 0, (void*)ent.name, &found); if (found == HCP_TRUE) { continue; } if (hcp::Runtime::hasExtension(ent.name, ".DLL") || hcp::Runtime::hasExtension(ent.name, ".SO") || hcp::Runtime::hasExtension(ent.name, ".DYLIB")) { hcp_Size_t pathLen = hcp_szStrLen((hcp_szStr)codecPath); hcp_Size_t nameLen = hcp_szStrLen((hcp_szStr)ent.name); codec.path = (char*)hcp_Malloc(_state, pathLen + nameLen + 2); hcp_Memcpy(_state, codec.path, codecPath, pathLen); hcp_Memcpy(_state, codec.path + pathLen, "/", 1); hcp_Memcpy(_state, codec.path + pathLen + 1, ent.name, nameLen + 1); if (loadLibrary(codec.path, &codec, error)) { hcp_Size_t index; auto code = hcp_Push(&_codecs.header, &codec, &index); if (code != HCP_NOERROR) { // TODO: Logg load errors hcp_Free(_state, codec.path); } } else { // TODO: Logg load errors hcp_Free(_state, codec.path); } } else { continue; } } return true; }