char* arcan_find_resource_path(const char* label, const char* path, enum arcan_namespaces space) { if (label == NULL || path == NULL || verify_traverse(path) == NULL || verify_traverse(label) == NULL) return NULL; /* combine the two strings, add / delimiter if necessary and forward */ size_t len_1 = strlen(path); size_t len_2 = strlen(label); if (len_1 == 0) return arcan_find_resource(label, space, ARES_FILE); if (len_2 == 0) return NULL; /* append, re-use strlens and null terminate */ char buf[ len_1 + len_2 + 2 ]; memcpy(buf, path, len_1); buf[len_1] = '/'; memcpy(&buf[len_1+1], label, len_2 + 1); /* simply forward */ char* res = arcan_find_resource(buf, space, ARES_FILE); return res; }
char* arcan_find_resource(const char* label, enum arcan_namespaces space, enum resource_type ares) { if (label == NULL || verify_traverse(label) == NULL) return NULL; size_t label_len = strlen(label); for (int i = 1, j = 0; i <= RESOURCE_SYS_ENDM; i <<= 1, j++){ if ((space & i) == 0 || !namespaces.paths[j]) continue; char scratch[ namespaces.lenv[j] + label_len + 2 ]; snprintf(scratch, sizeof(scratch), label[0] == '/' ? "%s%s" : "%s/%s", namespaces.paths[j], label ); if ( ((ares & ARES_FILE) && arcan_isfile(scratch)) || ((ares & ARES_FOLDER) && arcan_isdir(scratch)) ) return strdup(scratch); } return NULL; }
unsigned arcan_glob(char* basename, enum arcan_namespaces space, void (*cb)(char*, void*), void* tag) { unsigned count = 0; if (!basename || verify_traverse(basename) == NULL) return 0; for (int i = 1; i <= RESOURCE_SYS_ENDM; i <<= 1){ if ((space & i) == 0) continue; char* path = arcan_expand_resource(basename, i); WIN32_FIND_DATA finddata; HANDLE findh = FindFirstFile(path, &finddata); if (findh != INVALID_HANDLE_VALUE) do{ if (!finddata.cFileName || strcmp(finddata.cFileName, "..") == 0 || strcmp(finddata.cFileName, ".") == 0) continue; cb(finddata.cFileName, tag); count++; } while (FindNextFile(findh, &finddata)); FindClose(findh); arcan_mem_free(path); } return count; }
char* arcan_expand_resource(const char* label, enum arcan_namespaces space) { assert( space > 0 && (space & (space - 1) ) == 0 ); int space_ind =i_log2(space); if (space_ind > sizeof(namespaces.paths)/sizeof(namespaces.paths[0]) || label == NULL || verify_traverse(label) == NULL || !namespaces.paths[space_ind] ) return NULL; size_t len_1 = strlen(label); size_t len_2 = namespaces.lenv[space_ind]; if (len_1 == 0) return namespaces.paths[space_ind] ? strdup( namespaces.paths[space_ind] ) : NULL; char cbuf[ len_1 + len_2 + 2 ]; memcpy(cbuf, namespaces.paths[space_ind], len_2); cbuf[len_2] = '/'; memcpy(&cbuf[len_2 + (label[0] == '/' ? 0 : 1)], label, len_1+1); return strdup(cbuf); }