summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/API2
-rw-r--r--include/Handle.h4
-rw-r--r--include/Input.h7
-rw-r--r--include/Output.h3
-rw-r--r--lib/Handle.cc32
-rw-r--r--lib/Input.cc45
-rw-r--r--lib/Output.cc41
7 files changed, 99 insertions, 35 deletions
diff --git a/doc/API b/doc/API
index c9ec6a9..fcbbaec 100644
--- a/doc/API
+++ b/doc/API
@@ -122,7 +122,7 @@ will clean the extract function, I swear.
int to_int() const;
Tries to convert the String into an int. If the string is *exactly* not an int, it
-will returns 0. Even " 123" will be rejected.
+will return 0. Even " 123" will be rejected.
double to_double() const;
The same with a double.
diff --git a/include/Handle.h b/include/Handle.h
index 763a34b..938c594 100644
--- a/include/Handle.h
+++ b/include/Handle.h
@@ -40,10 +40,13 @@ class Handle : public Base {
virtual int Dup() const throw (GeneralException);
virtual void SetZ(int = 9) throw (GeneralException);
virtual void Flush();
+
+ void * mmap(off_t = 0, size_t = -1);
protected:
Handle(int h);
int GetHandle() const;
off_t itell;
+ void * hFile;
private:
ssize_t uwrite(const void *, size_t) throw (GeneralException);
ssize_t uread(void *, size_t);
@@ -52,6 +55,7 @@ class Handle : public Base {
gzFile zfile;
z_stream zstrm;
int z, c;
+ void * hMapObject;
};
Handle & operator<<(Handle &, const String &);
diff --git a/include/Input.h b/include/Input.h
index 18173d2..6b53012 100644
--- a/include/Input.h
+++ b/include/Input.h
@@ -40,7 +40,7 @@ class Input : public Handle {
bool fromarchive;
private:
- static int wrapopen(const String &, openresults_t *);
+ int wrapopen(const String &, openresults_t *);
};
class Stdin_t : public Input {
@@ -59,8 +59,9 @@ class Archive : public Base {
Archive(Handle *, int = ARCHIVE_BUILTIN);
virtual ~Archive();
protected:
- static bool inarchive(const String &);
- static int open(const String &, Input::openresults_t *) throw (GeneralException);
+ static Archive * inarchive(const String &);
+ Handle * GetHandle();
+ int open(const String &, Input::openresults_t *);
private:
void create() throw (GeneralException);
bool inarchivein(const String &);
diff --git a/include/Output.h b/include/Output.h
index 3d97922..0967182 100644
--- a/include/Output.h
+++ b/include/Output.h
@@ -21,6 +21,9 @@ class Output : public Handle {
String n;
off_t size;
time_t date_modif;
+
+ private:
+ int wrapopen(const String &, int, int);
};
class Stdout_t : public Output {
diff --git a/lib/Handle.cc b/lib/Handle.cc
index 83eb15d..2006b19 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -37,7 +37,7 @@ enum {
INFLATE
};
-Handle::Handle(const Handle & nh) : itell(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0)
+Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0)
{
#ifdef DEBUG
printm(M_INFO, String(_("Duplication of handle ")) + nh.h + _(" to ") + h + "\n");
@@ -513,3 +513,33 @@ void Handle::Flush() {
#endif
}
}
+
+void * Handle::mmap(off_t offset, size_t length) {
+ if (length == -1) {
+ length = GetSize();
+ }
+#ifndef _WIN32
+ return ::mmap(0, length, (CanRead() ? PROT_READ : 0) | (CanWrite() ? PROT_WRITE : 0), MAP_SHARED, h, offset);
+#else
+ void * lpvMem = 0;
+ hMapObject = CreateFileMapping(
+ hFile,
+ 0,
+ CanWrite() ? PAGE_READWRITE : PAGE_READONLY,
+ 0,
+ length,
+ GetName().to_charp());
+ if (hMapObject != NULL) {
+ lpvMem = MapViewOfFile(
+ hMapObject,
+ CanWrite() ? FILE_MAP_WRITE : FILE_MAP_READ,
+ 0,
+ offset,
+ length);
+ if (lpvMem == NULL) {
+ CloseHandle(hMapObject);
+ }
+ }
+ return lpvMem;
+#endif
+}
diff --git a/lib/Input.cc b/lib/Input.cc
index fdff787..a6eb09f 100644
--- a/lib/Input.cc
+++ b/lib/Input.cc
@@ -155,32 +155,24 @@ int Input::wrapopen(const String & fname, openresults_t * results) {
printm(M_INFO, _("Wrap-opening ") + fname + "\n");
#endif
if (fname[0] != '/') {
- bool t;
+ Archive * t;
t = Archive::inarchive(fname);
if (t) {
#ifdef DEBUG
printm(M_BARE, _("Trying to open the file in archive, since it seems to be here\n"));
#endif
- return Archive::open(fname, results);
+#ifdef _WIN32
+ hFile = t->GetHandle();
+#endif
+ return t->open(fname, results);
}
}
results->name = "";
-#if 0
- return open(fname.to_charp(), O_RDONLY
-#ifdef _WIN32
- | O_BINARY
-#endif
- );
+#ifndef _WIN32
+ return open(fname.to_charp(), O_RDONLY);
#else
- HANDLE hFile = CreateFile(
- fname.to_charp(),
- GENERIC_READ,
- 0,
- 0,
- OPEN_EXISTING,
- 0,
- 0);
- return _open_osfhandle((INT_PTR) hFile, O_RDONLY);
+ hFile = CreateFile(fname.to_charp(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ return _open_osfhandle((INT_PTR) hFile, O_RDONLY | O_BINARY);
#endif
}
@@ -215,14 +207,16 @@ Archive::Archive(Handle * hand, int atype) :
create();
}
+#ifdef _MSC_VER
#pragma pack(1)
+#endif
struct PEsection_t {
char name[8];
Uint32 VSize, VAdd, SizeOf, Pointer, PTRelocs, PTLNs;
Uint16 NR, NLN;
Uint32 Chars;
-};
+} PACKED;
void Archive::create() throw (GeneralException) {
char buffer[1024];
@@ -305,7 +299,7 @@ Archive::~Archive() {
delete archive;
}
-bool Archive::inarchive(const String & fname) {
+Archive * Archive::inarchive(const String & fname) {
Archive * p;
for (p = header; p; p = p->next) {
#ifdef DEBUG
@@ -315,13 +309,14 @@ bool Archive::inarchive(const String & fname) {
#ifdef DEBUG
printm(M_BARE, _("File `") + fname + _("' found in archive ") + p->name + "\n");
#endif
- return true;
+ return p;
}
}
- return false;
+ return 0;
}
-int Archive::open(const String & fname, Input::openresults_t * results) throw (GeneralException) {
+int Archive::open(const String & fname, Input::openresults_t * results) {
+#if 0
Archive * p;
for (p = header; p; p = p->next) {
@@ -331,6 +326,12 @@ int Archive::open(const String & fname, Input::openresults_t * results) throw (G
return p->openin(fname, results);
}
throw IOGeneral(_("File `") + fname + _("' not found in archive collection."));
+#endif
+ return openin(fname, results);
+}
+
+Handle * Archive::GetHandle() {
+ return archive;
}
bool Archive::inarchivein(const String & fname) {
diff --git a/lib/Output.cc b/lib/Output.cc
index b4ed359..912af25 100644
--- a/lib/Output.cc
+++ b/lib/Output.cc
@@ -21,14 +21,7 @@
#endif
Output::Output(String no, int create, int trunc) throw (GeneralException) :
- Handle(no.strlen() ? open(no.to_charp(), (create ? O_CREAT : 0) | (trunc ? O_TRUNC : 0)
-#ifdef _WIN32
-| O_RDWR | O_BINARY
-#endif
-#if defined __linux__ || defined __CYGWIN32__
-| O_WRONLY, 00666
-#endif
-) : dup(1)),
+ Handle(no.strlen() ? wrapopen(no.to_charp(), create, trunc) : dup(1)),
n(no) {
if (GetHandle() < 0) {
throw IOGeneral(String(_("Error opening file ")) + no + _(" for writing: ") + strerror(errno));
@@ -44,6 +37,38 @@ Output::Output(String no, int create, int trunc) throw (GeneralException) :
date_modif = s.st_mtime;
}
+int Output::wrapopen(const String & n, int create, int trunc) {
+#ifndef _WIN32
+ return open(no.to_charp(), (create ? O_CREAT : 0) |
+ (trunc ? O_TRUNC : 0) | O_WRONLY, 00666);
+#else
+ DWORD dwCreationDisposition;
+ switch ((create ? 1 : 0) | (trunc ? 2 : 0)) {
+ case 0: // no creation, no trunc
+ dwCreationDisposition = OPEN_EXISTING;
+ break;
+ case 1: // creation, no trunc if existing
+ dwCreationDisposition = OPEN_ALWAYS;
+ break;
+ case 2: // no creation, trunc of existing file
+ dwCreationDisposition = TRUNCATE_EXISTING;
+ break;
+ case 3: // creation, truc if existing
+ dwCreationDisposition = CREATE_ALWAYS;
+ break;
+ }
+ hFile = CreateFile(
+ n.to_charp(),
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ 0,
+ dwCreationDisposition,
+ FILE_ATTRIBUTE_ARCHIVE,
+ 0);
+ return _open_osfhandle((INT_PTR) hFile, O_WRONLY | O_BINARY);
+#endif
+}
+
Output::Output(const Output & o) : Handle(o), n(o.n) {
}