convert classpath paths to absolute paths

This is necessary because some apps expect CodeSource.getLocation() to
return URL containing an absolute path.
This commit is contained in:
Joel Dice 2011-07-11 10:56:53 -06:00
parent 272789cf16
commit ab8e6cdc80
5 changed files with 83 additions and 41 deletions

View File

@ -22,6 +22,39 @@ class Allocator {
virtual void free(const void* p, unsigned size) = 0;
};
inline const char*
append(Allocator* allocator, const char* a, const char* b, const char* c)
{
unsigned al = strlen(a);
unsigned bl = strlen(b);
unsigned cl = strlen(c);
char* p = static_cast<char*>(allocator->allocate((al + bl + cl) + 1));
memcpy(p, a, al);
memcpy(p + al, b, bl);
memcpy(p + al + bl, c, cl + 1);
return p;
}
inline const char*
append(Allocator* allocator, const char* a, const char* b)
{
unsigned al = strlen(a);
unsigned bl = strlen(b);
char* p = static_cast<char*>(allocator->allocate((al + bl) + 1));
memcpy(p, a, al);
memcpy(p + al, b, bl + 1);
return p;
}
inline const char*
copy(Allocator* allocator, const char* a)
{
unsigned al = strlen(a);
char* p = static_cast<char*>(allocator->allocate(al + 1));
memcpy(p, a, al + 1);
return p;
}
} // namespace vm
#endif//ALLOCATOR_H

View File

@ -19,39 +19,6 @@ namespace {
const bool DebugFind = false;
const char*
append(Allocator* allocator, const char* a, const char* b, const char* c)
{
unsigned al = strlen(a);
unsigned bl = strlen(b);
unsigned cl = strlen(c);
char* p = static_cast<char*>(allocator->allocate((al + bl + cl) + 1));
memcpy(p, a, al);
memcpy(p + al, b, bl);
memcpy(p + al + bl, c, cl + 1);
return p;
}
const char*
append(Allocator* allocator, const char* a, const char* b)
{
unsigned al = strlen(a);
unsigned bl = strlen(b);
char* p = static_cast<char*>(allocator->allocate((al + bl) + 1));
memcpy(p, a, al);
memcpy(p + al, b, bl + 1);
return p;
}
const char*
copy(Allocator* allocator, const char* a)
{
unsigned al = strlen(a);
char* p = static_cast<char*>(allocator->allocate(al + 1));
memcpy(p, a, al + 1);
return p;
}
class Element {
public:
class Iterator {
@ -136,9 +103,12 @@ class DirectoryElement: public Element {
};
DirectoryElement(System* s, Allocator* allocator, const char* name):
s(s), allocator(allocator), name(name),
urlPrefix_(append(allocator, "file:", name, "/")),
sourceUrl_(append(allocator, "file:", name))
s(s),
allocator(allocator),
originalName(name),
name(s->toAbsolutePath(allocator, name)),
urlPrefix_(append(allocator, "file:", this->name, "/")),
sourceUrl_(append(allocator, "file:", this->name))
{ }
virtual Element::Iterator* iterator() {
@ -181,6 +151,7 @@ class DirectoryElement: public Element {
}
virtual void dispose() {
allocator->free(originalName, strlen(originalName) + 1);
allocator->free(name, strlen(name) + 1);
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
@ -189,6 +160,7 @@ class DirectoryElement: public Element {
System* s;
Allocator* allocator;
const char* originalName;
const char* name;
const char* urlPrefix_;
const char* sourceUrl_;
@ -454,10 +426,17 @@ class JarElement: public Element {
unsigned position;
};
JarElement(System* s, Allocator* allocator, const char* name):
s(s), allocator(allocator), name(name),
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
sourceUrl_(name ? append(allocator, "file:", name) : 0),
JarElement(System* s, Allocator* allocator, const char* name,
bool canonicalizePath = true):
s(s),
allocator(allocator),
originalName(name),
name(name and canonicalizePath
? s->toAbsolutePath(allocator, name) : name),
urlPrefix_(this->name
? append(allocator, "jar:file:", this->name, "!/") : 0),
sourceUrl_(this->name
? append(allocator, "file:", this->name) : 0),
region(0), index(0)
{ }
@ -530,6 +509,9 @@ class JarElement: public Element {
}
virtual void dispose(unsigned size) {
if (originalName != name) {
allocator->free(originalName, strlen(originalName) + 1);
}
allocator->free(name, strlen(name) + 1);
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
@ -544,6 +526,7 @@ class JarElement: public Element {
System* s;
Allocator* allocator;
const char* originalName;
const char* name;
const char* urlPrefix_;
const char* sourceUrl_;
@ -555,7 +538,7 @@ class BuiltinElement: public JarElement {
public:
BuiltinElement(System* s, Allocator* allocator, const char* name,
const char* libraryName):
JarElement(s, allocator, name),
JarElement(s, allocator, name, false),
libraryName(libraryName ? copy(allocator, libraryName) : 0)
{ }

View File

@ -776,6 +776,15 @@ class MySystem: public System {
return SO_SUFFIX;
}
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
if (name[0] == '/') {
return copy(allocator, name);
} else {
char buffer[PATH_MAX];
return append(allocator, getcwd(buffer, PATH_MAX), "/", name);
}
}
virtual Status load(System::Library** lib,
const char* name)
{

View File

@ -12,6 +12,7 @@
#define SYSTEM_H
#include "common.h"
#include "allocator.h"
namespace vm {
@ -140,6 +141,8 @@ class System {
virtual Status load(Library**, const char* name) = 0;
virtual char pathSeparator() = 0;
virtual char fileSeparator() = 0;
virtual const char* toAbsolutePath(Allocator* allocator,
const char* name) = 0;
virtual int64_t now() = 0;
virtual void yield() = 0;
virtual void exit(int code) = 0;

View File

@ -752,6 +752,20 @@ class MySystem: public System {
return SO_SUFFIX;
}
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
if (strncmp(name, "//", 2) == 0
or strncmp(name, "\\\\", 2) == 0
or strncmp(name + 1, ":/", 2) == 0
or strncmp(name + 1, ":\\", 2) == 0)
{
return copy(allocator, name);
} else {
TCHAR buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
return append(allocator, buffer, "\\", name);
}
}
virtual Status load(System::Library** lib,
const char* name)
{