char* os_formattime(date_t* date, const char* fmt) { char* buffer; // Bail out on strftime formats that can produce a zero-length string. if((fmt[0] == '\0') || !strcmp(fmt, "%p") || !strcmp(fmt, "%P")) { buffer = (char*)pony_alloc(1); buffer[0] = '\0'; return buffer; } struct tm tm; date_to_tm(date, &tm); size_t len = 64; size_t r = 0; while(r == 0) { buffer = (char*)pony_alloc(len); r = strftime(buffer, len, fmt, &tm); len <<= 1; } return buffer; }
const char* os_readdir() { #if defined(PLATFORM_IS_WINDOWS) if(opendir_handle == INVALID_HANDLE_VALUE) return NULL; size_t len = strlen(opendir_data.cFileName) + 1; if(skip_entry(opendir_data.cFileName, len - 1)) { if(!FindNextFile(opendir_handle, &opendir_data)) { os_closedir(); return NULL; } return os_readdir(); } char* cstring = (char*)pony_alloc(len); memcpy(cstring, opendir_data.cFileName, len); if(!FindNextFile(opendir_handle, &opendir_data)) os_closedir(); return cstring; #elif defined(PLATFORM_IS_POSIX_BASED) if(opendir_handle == NULL) return NULL; struct dirent entry; struct dirent* result; if(readdir_r(opendir_handle, &entry, &result) != 0) return NULL; if(result == NULL) return NULL; size_t len = strlen(result->d_name) + 1; if(skip_entry(result->d_name, len - 1)) return os_readdir(); char* cstring = pony_alloc(len); memcpy(cstring, result->d_name, len); return cstring; #else return NULL; #endif }
PONY_EXTERN_C_BEGIN char* pony_os_realpath(const char* path) { #ifdef PLATFORM_IS_WINDOWS char resolved[FILENAME_MAX]; if(GetFullPathName(path, FILENAME_MAX, resolved, NULL) == 0 || GetFileAttributes(resolved) == INVALID_FILE_ATTRIBUTES) return NULL; #elif defined(PLATFORM_IS_POSIX_BASED) char resolved[PATH_MAX]; if(realpath(path, resolved) == NULL) return NULL; #endif size_t len = strlen(resolved) + 1; #ifdef PLATFORM_IS_WINDOWS for(; resolved[len - 1] == '\\'; --len) resolved[len - 1] = '\0'; #endif char* cstring = (char*)pony_alloc(pony_ctx(), len); memcpy(cstring, resolved, len); return cstring; }
void* pony_deserialise_offset(pony_ctx_t* ctx, pony_type_t* t, uintptr_t offset) { // If the high bit of the offset is set, it is either an unserialised // primitive, or an unserialised field in an opaque object. if((offset & HIGH_BIT) != 0) { offset &= ~HIGH_BIT; if(offset > __DescTableSize) return NULL; // Return the global instance, if there is one. It's ok to return null if // there is no global instance, as this will then be an unserialised // field in an opaque object. t = (&__DescTable)[offset]; return t->instance; } // Lookup the offset, return the associated object if there is one. serialise_t k; k.key = offset; serialise_t* s = ponyint_serialise_get(&ctx->serialise, &k); if(s != NULL) return (void*)s->value; // If we haven't been passed a type descriptor, read one. if(t == NULL) { // Make sure we have space to read a type id. if((offset + sizeof(uintptr_t)) > ctx->serialise_size) pony_throw(); // Turn the type id into a descriptor pointer. uintptr_t id = *(uintptr_t*)((uintptr_t)ctx->serialise_buffer + offset); t = (&__DescTable)[id]; } // If it's a primitive, return the global instance. if(t->instance != NULL) return t->instance; // Make sure we have space to read the object. if((offset + t->size) > ctx->serialise_size) pony_throw(); // Allocate the object, memcpy to it. void* object = pony_alloc(ctx, t->size); memcpy(object, (void*)((uintptr_t)ctx->serialise_buffer + offset), t->size); // Store a mapping of offset to object. s = POOL_ALLOC(serialise_t); s->key = offset; s->value = (uintptr_t)object; ponyint_serialise_put(&ctx->serialise, s); recurse(ctx, object, t->deserialise); return object; }
void* pony_deserialise_block(pony_ctx_t* ctx, uintptr_t offset, size_t size) { // Allocate the block, memcpy to it. if((offset + size) > ctx->serialise_size) pony_throw(); void* block = pony_alloc(ctx, size); memcpy(block, (void*)((uintptr_t)ctx->serialise_buffer + offset), size); return block; }
char* os_cwd() { #if defined(PLATFORM_IS_WINDOWS) char* cwd = _getcwd(NULL, 0); #else char* cwd = getcwd(NULL, 0); #endif size_t len = strlen(cwd) + 1; char* cstring = (char*)pony_alloc(len); memcpy(cstring, cwd, len); free(cwd); return cstring; }