aboutsummaryrefslogtreecommitdiff
path: root/SrcUnix/EmFileRefUnix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SrcUnix/EmFileRefUnix.cpp')
-rw-r--r--SrcUnix/EmFileRefUnix.cpp547
1 files changed, 547 insertions, 0 deletions
diff --git a/SrcUnix/EmFileRefUnix.cpp b/SrcUnix/EmFileRefUnix.cpp
new file mode 100644
index 0000000..df94e0c
--- /dev/null
+++ b/SrcUnix/EmFileRefUnix.cpp
@@ -0,0 +1,547 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 2000-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#include "EmCommon.h"
+#include "EmFileRefUnix.h"
+
+#include "Miscellaneous.h" // EndsWith
+#include "Platform.h" // stricmp
+
+#include <errno.h> // ENOENT
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+static const char* kExtension[] =
+{
+ NULL, // kFileTypeNone,
+ NULL, // kFileTypeApplication
+ ".rom", // kFileTypeROM,
+ ".psf", // kFileTypeSession,
+ ".pev", // kFileTypeEvents,
+ ".ini", // kFileTypePreference,
+ ".prc", // kFileTypePalmApp,
+ ".pdb", // kFileTypePalmDB,
+ ".pqa", // kFileTypePalmQA,
+ ".txt", // kFileTypeText,
+ NULL, // kFileTypePicture,
+ ".skin", // kFileTypeSkin,
+ ".prof", // kFileTypeProfile,
+ NULL, // kFileTypePalmAll,
+ NULL // kFileTypeAll
+};
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::EmFileRef
+ *
+ * DESCRIPTION: Various ways to make a file reference.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: nothing.
+ *
+ ***********************************************************************/
+
+EmFileRef::EmFileRef (void) :
+ fFilePath ()
+{
+ COMPILE_TIME_ASSERT(countof (kExtension) == kFileTypeLast);
+}
+
+
+EmFileRef::EmFileRef (const EmFileRef& other) :
+ fFilePath (other.fFilePath)
+{
+}
+
+
+EmFileRef::EmFileRef (const char* path) :
+ fFilePath (path)
+{
+ this->MaybePrependCurrentDirectory ();
+ this->MaybeNormalize ();
+}
+
+
+EmFileRef::EmFileRef (const string& path) :
+ fFilePath (path)
+{
+ this->MaybePrependCurrentDirectory ();
+ this->MaybeNormalize ();
+}
+
+
+EmFileRef::EmFileRef (const EmDirRef& parent, const char* path) :
+ fFilePath (parent.GetFullPath () + path)
+{
+ this->MaybeNormalize ();
+}
+
+
+EmFileRef::EmFileRef (const EmDirRef& parent, const string& path) :
+ fFilePath (parent.GetFullPath () + path)
+{
+ this->MaybeNormalize ();
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::EmFileRef
+ *
+ * DESCRIPTION: EmFileRef destructor. Nothing special to do...
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: nothing.
+ *
+ ***********************************************************************/
+
+EmFileRef::~EmFileRef (void)
+{
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::operator=
+ *
+ * DESCRIPTION: Assignment operator. If "other" is not the same as
+ * the controlled object, copy the contents.
+ *
+ * PARAMETERS: other - object to copy.
+ *
+ * RETURNED: reference to self.
+ *
+ ***********************************************************************/
+
+EmFileRef&
+EmFileRef::operator= (const EmFileRef& other)
+{
+ if (&other != this)
+ {
+ fFilePath = other.fFilePath;
+ }
+
+ return *this;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::IsSpecified
+ *
+ * DESCRIPTION: Returns whether or not the controlled object has been
+ * pointed to a (possibly non-existant) file, or if it's
+ * empty (that it, it was created with the default ctor).
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: True if the object points to a file.
+ *
+ ***********************************************************************/
+
+Bool
+EmFileRef::IsSpecified (void) const
+{
+ return !fFilePath.empty ();
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::Exists
+ *
+ * DESCRIPTION: Returns whether or not the controlled object points to
+ * an existing file.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: True if the referenced file exists.
+ *
+ ***********************************************************************/
+
+Bool
+EmFileRef::Exists (void) const
+{
+ if (this->IsSpecified ())
+ {
+ struct stat buf;
+ int result = stat (fFilePath.c_str (), &buf);
+
+ return result == 0;
+ }
+
+ return false;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::IsType
+ *
+ * DESCRIPTION: DESCRIPTION
+ *
+ * PARAMETERS: None
+ *
+ * RETURNED: Nothing
+ *
+ ***********************************************************************/
+
+Bool
+EmFileRef::IsType (EmFileType type) const
+{
+ if (fFilePath.size () > 4 &&
+ kExtension[type] != NULL &&
+ ::EndsWith (fFilePath.c_str (), kExtension[type]))
+ {
+ return true;
+ }
+
+ // Add special hacks for ROM files.
+ if (type == kFileTypeROM && ::StartsWith (fFilePath.c_str(), "rom."))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::SetCreatorAndType
+ *
+ * DESCRIPTION: Set the Finder type and creator information of the
+ * managed file.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: Nothing.
+ *
+ ***********************************************************************/
+
+void
+EmFileRef::SetCreatorAndType (EmFileCreator creator, EmFileType fileType) const
+{
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::GetAttr
+ *
+ * DESCRIPTION: Get basic file attributes of the managed file.
+ *
+ * PARAMETERS: A pointer to an integer where the mode bits will be stored.
+ *
+ * RETURNED: An integer containing an errno style error result, 0 for no error.
+ *
+ ***********************************************************************/
+
+int
+EmFileRef::GetAttr (int * mode) const
+{
+ EmAssert(mode);
+
+ *mode = 0;
+
+ if (!IsSpecified())
+ return ENOENT;
+
+ struct stat stat_buf;
+ if (stat(GetFullPath().c_str(), &stat_buf))
+ return errno;
+
+ if ((stat_buf.st_mode & S_IWUSR) == 0)
+ *mode |= kFileAttrReadOnly;
+
+ return 0;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::SetAttr
+ *
+ * DESCRIPTION: Set basic file attributes of the managed file.
+ *
+ * PARAMETERS: An integer containing bits from the EmFileAttr enum.
+ *
+ * RETURNED: An integer containing an errno style error result, 0 for no error.
+ *
+ ***********************************************************************/
+
+int
+EmFileRef::SetAttr (int mode) const
+{
+ if (!IsSpecified())
+ return ENOENT;
+
+ struct stat stat_buf;
+ if (stat(GetFullPath().c_str(), &stat_buf))
+ return errno;
+
+ stat_buf.st_mode &= ~S_IWUSR;
+ if (!(mode & kFileAttrReadOnly))
+ stat_buf.st_mode |= S_IWUSR;
+
+ if (chmod(GetFullPath().c_str(), stat_buf.st_mode))
+ return errno;
+
+ return 0;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::GetName
+ *
+ * DESCRIPTION: Returns the name of the referenced file. Only the file
+ * *name* is returned, not the full path.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: A string containing the name. If the file is not
+ * specified, an empty string is returned. No checks are
+ * made to see if the file actually exists.
+ *
+ ***********************************************************************/
+
+string
+EmFileRef::GetName (void) const
+{
+ string result;
+
+ if (this->IsSpecified ())
+ {
+ string::size_type pos = fFilePath.rfind ('/', string::npos);
+ EmAssert (pos != string::npos);
+
+ result = fFilePath.substr (pos + 1, string::npos);
+ }
+
+ return result;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::GetParent
+ *
+ * DESCRIPTION: Returns an object representing the parent (or container)
+ * of the managed file.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: An object representing the file's parent.
+ *
+ ***********************************************************************/
+
+EmDirRef
+EmFileRef::GetParent (void) const
+{
+ EmDirRef result;
+
+ if (this->IsSpecified () && fFilePath != "/")
+ {
+ string::size_type pos = fFilePath.rfind ('/', string::npos);
+ EmAssert (pos != string::npos);
+
+ result = EmDirRef (fFilePath.substr (0, pos + 1));
+ }
+
+ return result;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::GetFullPath
+ *
+ * DESCRIPTION: Get a full (platform-specific) path to the object.
+ *
+ * PARAMETERS: none.
+ *
+ * RETURNED: An string representing the file's path.
+ *
+ ***********************************************************************/
+
+string
+EmFileRef::GetFullPath (void) const
+{
+ return fFilePath;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: EmFileRef::operator==
+ * FUNCTION: EmFileRef::operator!=
+ * FUNCTION: EmFileRef::operator>
+ * FUNCTION: EmFileRef::operator<
+ *
+ * DESCRIPTION: Bogus operators for wiggy VC++ compiler which won't let
+ * us instantiate STL containers without them.
+ *
+ * PARAMETERS: other - object to compare ourself to.
+ *
+ * RETURNED: True if the requested condition is true. Comparisons
+ * are based on the file's full path.
+ *
+ ***********************************************************************/
+
+bool
+EmFileRef::operator== (const EmFileRef& other) const
+{
+ return _stricmp (fFilePath.c_str (), other.fFilePath.c_str ()) == 0;
+}
+
+
+bool
+EmFileRef::operator!= (const EmFileRef& other) const
+{
+ return _stricmp (fFilePath.c_str (), other.fFilePath.c_str ()) != 0;
+}
+
+
+bool
+EmFileRef::operator> (const EmFileRef& other) const
+{
+ return _stricmp (fFilePath.c_str (), other.fFilePath.c_str ()) < 0;
+}
+
+
+bool
+EmFileRef::operator< (const EmFileRef& other) const
+{
+ return _stricmp (fFilePath.c_str (), other.fFilePath.c_str ()) > 0;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: FromPrefString
+ *
+ * DESCRIPTION: Initialize this object from the string containing a file
+ * reference stored in a preference file.
+ *
+ * PARAMETERS: s - the string from the preference file
+ *
+ * RETURNED: True if we were able to carry out the initialization.
+ * False otherwise. Note that the string is NOT validated
+ * to see if it refers to an existing file.
+ *
+ ***********************************************************************/
+
+bool
+EmFileRef::FromPrefString (const string& s)
+{
+ fFilePath = s;
+
+ return true;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: ToPrefString
+ *
+ * DESCRIPTION: Produce a string that can be stored to a preference file
+ * and which can later be used to reproduce the current
+ * file reference object.
+ *
+ * PARAMETERS: None
+ *
+ * RETURNED: The string to be written to the preference file.
+ *
+ ***********************************************************************/
+
+string
+EmFileRef::ToPrefString (void) const
+{
+ return fFilePath;
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: MaybePrependCurrentDirectory
+ *
+ * DESCRIPTION: Prepend the current working directory if the managed
+ * path is not a full path.
+ *
+ * PARAMETERS: None
+ *
+ * RETURNED: Nothing
+ *
+ ***********************************************************************/
+
+void
+EmFileRef::MaybePrependCurrentDirectory (void)
+{
+ if (fFilePath[0] != '/')
+ {
+ size_t bufSize = 256;
+ char* buffer = (char*) Platform::AllocateMemory (bufSize);
+ while (getcwd (buffer, bufSize) == NULL)
+ {
+ if (errno != ERANGE)
+ return;
+
+ bufSize *= 2;
+ buffer = (char*) Platform::ReallocMemory (buffer, bufSize);
+ }
+
+ size_t cwdLen = strlen (buffer);
+ if (cwdLen)
+ {
+ if (buffer[cwdLen - 1] != '/')
+ fFilePath = string (buffer) + "/" + fFilePath;
+ else
+ fFilePath = string (buffer) + fFilePath;
+ }
+
+ Platform::DisposeMemory (buffer);
+ }
+}
+
+
+/***********************************************************************
+ *
+ * FUNCTION: MaybeNormalize
+ *
+ * DESCRIPTION: The routines we use to fetch a file from the user
+ * sometimes return full paths starting with double
+ * slashes. While the file system allows that, it play
+ * havoc with our operator=(). Patch up full paths
+ * so that they don't start with '//'
+ *
+ * PARAMETERS: None
+ *
+ * RETURNED: Nothing
+ *
+ ***********************************************************************/
+
+void
+EmFileRef::MaybeNormalize (void)
+{
+ if (fFilePath.size () >= 2 &&
+ fFilePath[0] == '/' &&
+ fFilePath[1] == '/')
+ {
+ fFilePath.erase (fFilePath.begin ());
+ }
+}