rdf/datasource/src/nsFileSystemDataSource.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7   Implementation for a file system RDF data store.
     8  */
    10 #include "nsFileSystemDataSource.h"
    12 #include <ctype.h> // for toupper()
    13 #include <stdio.h>
    14 #include "nsArrayEnumerator.h"
    15 #include "nsCOMArray.h"
    16 #include "nsISupportsArray.h"
    17 #include "nsIRDFDataSource.h"
    18 #include "nsIRDFObserver.h"
    19 #include "nsIServiceManager.h"
    20 #include "nsXPIDLString.h"
    21 #include "nsRDFCID.h"
    22 #include "rdfutil.h"
    23 #include "rdf.h"
    24 #include "nsEnumeratorUtils.h"
    25 #include "nsIURL.h"
    26 #include "nsIFileURL.h"
    27 #include "nsNetUtil.h"
    28 #include "nsIChannel.h"
    29 #include "nsIFile.h"
    30 #include "nsEscape.h"
    31 #include "nsCRTGlue.h"
    32 #include "nsAutoPtr.h"
    34 #ifdef XP_WIN
    35 #include "windef.h"
    36 #include "winbase.h"
    37 #include "nsILineInputStream.h"
    38 #include "nsDirectoryServiceDefs.h"
    39 #endif
    41 #define NS_MOZICON_SCHEME           "moz-icon:"
    43 static const char kFileProtocol[]         = "file://";
    45 bool
    46 FileSystemDataSource::isFileURI(nsIRDFResource *r)
    47 {
    48     bool        isFileURIFlag = false;
    49     const char  *uri = nullptr;
    51     r->GetValueConst(&uri);
    52     if ((uri) && (!strncmp(uri, kFileProtocol, sizeof(kFileProtocol) - 1)))
    53     {
    54         // XXX HACK HACK HACK
    55         if (!strchr(uri, '#'))
    56         {
    57             isFileURIFlag = true;
    58         }
    59     }
    60     return(isFileURIFlag);
    61 }
    65 bool
    66 FileSystemDataSource::isDirURI(nsIRDFResource* source)
    67 {
    68     nsresult    rv;
    69     const char  *uri = nullptr;
    71     rv = source->GetValueConst(&uri);
    72     if (NS_FAILED(rv)) return(false);
    74     nsCOMPtr<nsIFile> aDir;
    76     rv = NS_GetFileFromURLSpec(nsDependentCString(uri), getter_AddRefs(aDir));
    77     if (NS_FAILED(rv)) return(false);
    79     bool isDirFlag = false;
    81     rv = aDir->IsDirectory(&isDirFlag);
    82     if (NS_FAILED(rv)) return(false);
    84     return(isDirFlag);
    85 }
    88 nsresult
    89 FileSystemDataSource::Init()
    90 {
    91     nsresult rv;
    93     mRDFService = do_GetService("@mozilla.org/rdf/rdf-service;1");
    94     NS_ENSURE_TRUE(mRDFService, NS_ERROR_FAILURE);
    96     rv =  mRDFService->GetResource(NS_LITERAL_CSTRING("NC:FilesRoot"),
    97                                    getter_AddRefs(mNC_FileSystemRoot));
    98     nsresult tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "child"),
    99                                    getter_AddRefs(mNC_Child));
   100     if (NS_FAILED(tmp)) {
   101       rv = tmp;
   102     }
   103     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "Name"),
   104                                    getter_AddRefs(mNC_Name));
   105     if (NS_FAILED(tmp)) {
   106       rv = tmp;
   107     }
   108     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "URL"),
   109                                    getter_AddRefs(mNC_URL));
   110     if (NS_FAILED(tmp)) {
   111       rv = tmp;
   112     }
   113     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "Icon"),
   114                                    getter_AddRefs(mNC_Icon));
   115     if (NS_FAILED(tmp)) {
   116       rv = tmp;
   117     }
   118     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "Content-Length"),
   119                                    getter_AddRefs(mNC_Length));
   120     if (NS_FAILED(tmp)) {
   121       rv = tmp;
   122     }
   123     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "IsDirectory"),
   124                                    getter_AddRefs(mNC_IsDirectory));
   125     if (NS_FAILED(tmp)) {
   126       rv = tmp;
   127     }
   128     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"),
   129                                    getter_AddRefs(mWEB_LastMod));
   130     if (NS_FAILED(tmp)) {
   131       rv = tmp;
   132     }
   133     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "FileSystemObject"),
   134                                    getter_AddRefs(mNC_FileSystemObject));
   135     if (NS_FAILED(tmp)) {
   136       rv = tmp;
   137     }
   138     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI  "pulse"),
   139                                    getter_AddRefs(mNC_pulse));
   140     if (NS_FAILED(tmp)) {
   141       rv = tmp;
   142     }
   143     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"),
   144                                    getter_AddRefs(mRDF_InstanceOf));
   145     if (NS_FAILED(tmp)) {
   146       rv = tmp;
   147     }
   148     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"),
   149                                    getter_AddRefs(mRDF_type));
   151     static const char16_t kTrue[] = {'t','r','u','e','\0'};
   152     static const char16_t kFalse[] = {'f','a','l','s','e','\0'};
   154     tmp = mRDFService->GetLiteral(kTrue, getter_AddRefs(mLiteralTrue));
   155     if (NS_FAILED(tmp)) {
   156       rv = tmp;
   157     }
   158     tmp = mRDFService->GetLiteral(kFalse, getter_AddRefs(mLiteralFalse));
   159     if (NS_FAILED(tmp)) {
   160       rv = tmp;
   161     }
   162     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   164 #ifdef USE_NC_EXTENSION
   165     rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "extension"),
   166                                   getter_AddRefs(mNC_extension));
   167     NS_ENSURE_SUCCESS(rv, rv);
   168 #endif
   170 #ifdef XP_WIN
   171     rv =  mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IEFavorite"),
   172                                   getter_AddRefs(mNC_IEFavoriteObject));
   173     tmp = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IEFavoriteFolder"),
   174                                    getter_AddRefs(mNC_IEFavoriteFolder));
   175     if (NS_FAILED(tmp)) {
   176       rv = tmp;
   177     }
   178     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   180     nsCOMPtr<nsIFile> file;
   181     NS_GetSpecialDirectory(NS_WIN_FAVORITES_DIR, getter_AddRefs(file));
   182     if (file)
   183     {
   184         nsCOMPtr<nsIURI> furi;
   185         NS_NewFileURI(getter_AddRefs(furi), file);
   186         NS_ENSURE_TRUE(furi, NS_ERROR_FAILURE);
   188         file->GetNativePath(ieFavoritesDir);
   189     }
   190 #endif
   192     return NS_OK;
   193 }
   195 //static
   196 nsresult
   197 FileSystemDataSource::Create(nsISupports* aOuter, const nsIID& aIID, void **aResult)
   198 {
   199     NS_ENSURE_NO_AGGREGATION(aOuter);
   201     nsRefPtr<FileSystemDataSource> self = new FileSystemDataSource();
   202     if (!self)
   203         return NS_ERROR_OUT_OF_MEMORY;
   205     nsresult rv = self->Init();
   206     NS_ENSURE_SUCCESS(rv, rv);
   208     return self->QueryInterface(aIID, aResult);
   209 }
   211 NS_IMPL_ISUPPORTS(FileSystemDataSource, nsIRDFDataSource)
   213 NS_IMETHODIMP
   214 FileSystemDataSource::GetURI(char **uri)
   215 {
   216     NS_PRECONDITION(uri != nullptr, "null ptr");
   217     if (! uri)
   218         return NS_ERROR_NULL_POINTER;
   220     if ((*uri = NS_strdup("rdf:files")) == nullptr)
   221         return NS_ERROR_OUT_OF_MEMORY;
   223     return NS_OK;
   224 }
   228 NS_IMETHODIMP
   229 FileSystemDataSource::GetSource(nsIRDFResource* property,
   230                                 nsIRDFNode* target,
   231                                 bool tv,
   232                                 nsIRDFResource** source /* out */)
   233 {
   234     NS_PRECONDITION(property != nullptr, "null ptr");
   235     if (! property)
   236         return NS_ERROR_NULL_POINTER;
   238     NS_PRECONDITION(target != nullptr, "null ptr");
   239     if (! target)
   240         return NS_ERROR_NULL_POINTER;
   242     NS_PRECONDITION(source != nullptr, "null ptr");
   243     if (! source)
   244         return NS_ERROR_NULL_POINTER;
   246     *source = nullptr;
   247     return NS_RDF_NO_VALUE;
   248 }
   252 NS_IMETHODIMP
   253 FileSystemDataSource::GetSources(nsIRDFResource *property,
   254                                  nsIRDFNode *target,
   255                                  bool tv,
   256                                  nsISimpleEnumerator **sources /* out */)
   257 {
   258 //  NS_NOTYETIMPLEMENTED("write me");
   259     return NS_ERROR_NOT_IMPLEMENTED;
   260 }
   264 NS_IMETHODIMP
   265 FileSystemDataSource::GetTarget(nsIRDFResource *source,
   266                                 nsIRDFResource *property,
   267                                 bool tv,
   268                                 nsIRDFNode **target /* out */)
   269 {
   270     NS_PRECONDITION(source != nullptr, "null ptr");
   271     if (! source)
   272         return NS_ERROR_NULL_POINTER;
   274     NS_PRECONDITION(property != nullptr, "null ptr");
   275     if (! property)
   276         return NS_ERROR_NULL_POINTER;
   278     NS_PRECONDITION(target != nullptr, "null ptr");
   279     if (! target)
   280         return NS_ERROR_NULL_POINTER;
   282     *target = nullptr;
   284     nsresult        rv = NS_RDF_NO_VALUE;
   286     // we only have positive assertions in the file system data source.
   287     if (! tv)
   288         return NS_RDF_NO_VALUE;
   290     if (source == mNC_FileSystemRoot)
   291     {
   292         if (property == mNC_pulse)
   293         {
   294             nsIRDFLiteral   *pulseLiteral;
   295             mRDFService->GetLiteral(MOZ_UTF16("12"), &pulseLiteral);
   296             *target = pulseLiteral;
   297             return NS_OK;
   298         }
   299     }
   300     else if (isFileURI(source))
   301     {
   302         if (property == mNC_Name)
   303         {
   304             nsCOMPtr<nsIRDFLiteral> name;
   305             rv = GetName(source, getter_AddRefs(name));
   306             if (NS_FAILED(rv)) return(rv);
   307             if (!name)  rv = NS_RDF_NO_VALUE;
   308             if (rv == NS_RDF_NO_VALUE)  return(rv);
   309             return name->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   310         }
   311         else if (property == mNC_URL)
   312         {
   313             nsCOMPtr<nsIRDFLiteral> url;
   314             rv = GetURL(source, nullptr, getter_AddRefs(url));
   315             if (NS_FAILED(rv)) return(rv);
   316             if (!url)   rv = NS_RDF_NO_VALUE;
   317             if (rv == NS_RDF_NO_VALUE)  return(rv);
   319             return url->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   320         }
   321         else if (property == mNC_Icon)
   322         {
   323             nsCOMPtr<nsIRDFLiteral> url;
   324             bool isFavorite = false;
   325             rv = GetURL(source, &isFavorite, getter_AddRefs(url));
   326             if (NS_FAILED(rv)) return(rv);
   327             if (isFavorite || !url) rv = NS_RDF_NO_VALUE;
   328             if (rv == NS_RDF_NO_VALUE)  return(rv);
   330             const char16_t *uni = nullptr;
   331             url->GetValueConst(&uni);
   332             if (!uni)   return(NS_RDF_NO_VALUE);
   333             nsAutoString    urlStr;
   334             urlStr.Assign(NS_LITERAL_STRING(NS_MOZICON_SCHEME).get());
   335             urlStr.Append(uni);
   337             rv = mRDFService->GetLiteral(urlStr.get(), getter_AddRefs(url));
   338             if (NS_FAILED(rv) || !url)    return(NS_RDF_NO_VALUE);
   339             return url->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   340         }
   341         else if (property == mNC_Length)
   342         {
   343             nsCOMPtr<nsIRDFInt> fileSize;
   344             rv = GetFileSize(source, getter_AddRefs(fileSize));
   345             if (NS_FAILED(rv)) return(rv);
   346             if (!fileSize)  rv = NS_RDF_NO_VALUE;
   347             if (rv == NS_RDF_NO_VALUE)  return(rv);
   349             return fileSize->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   350         }
   351         else  if (property == mNC_IsDirectory)
   352         {
   353             *target = (isDirURI(source)) ? mLiteralTrue : mLiteralFalse;
   354             NS_ADDREF(*target);
   355             return NS_OK;
   356         }
   357         else if (property == mWEB_LastMod)
   358         {
   359             nsCOMPtr<nsIRDFDate> lastMod;
   360             rv = GetLastMod(source, getter_AddRefs(lastMod));
   361             if (NS_FAILED(rv)) return(rv);
   362             if (!lastMod)   rv = NS_RDF_NO_VALUE;
   363             if (rv == NS_RDF_NO_VALUE)  return(rv);
   365             return lastMod->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   366         }
   367         else if (property == mRDF_type)
   368         {
   369             nsCString type;
   370             rv = mNC_FileSystemObject->GetValueUTF8(type);
   371             if (NS_FAILED(rv)) return(rv);
   373 #ifdef  XP_WIN
   374             // under Windows, if its an IE favorite, return that type
   375             if (!ieFavoritesDir.IsEmpty())
   376             {
   377                 nsCString uri;
   378                 rv = source->GetValueUTF8(uri);
   379                 if (NS_FAILED(rv)) return(rv);
   381                 NS_ConvertUTF8toUTF16 theURI(uri);
   383                 if (theURI.Find(ieFavoritesDir) == 0)
   384                 {
   385                     if (theURI[theURI.Length() - 1] == '/')
   386                     {
   387                         rv = mNC_IEFavoriteFolder->GetValueUTF8(type);
   388                     }
   389                     else
   390                     {
   391                         rv = mNC_IEFavoriteObject->GetValueUTF8(type);
   392                     }
   393                     if (NS_FAILED(rv)) return(rv);
   394                 }
   395             }
   396 #endif
   398             NS_ConvertUTF8toUTF16 url(type);
   399             nsCOMPtr<nsIRDFLiteral> literal;
   400             mRDFService->GetLiteral(url.get(), getter_AddRefs(literal));
   401             rv = literal->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   402             return(rv);
   403         }
   404         else if (property == mNC_pulse)
   405         {
   406             nsCOMPtr<nsIRDFLiteral> pulseLiteral;
   407             mRDFService->GetLiteral(MOZ_UTF16("12"), getter_AddRefs(pulseLiteral));
   408             rv = pulseLiteral->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   409             return(rv);
   410         }
   411         else if (property == mNC_Child)
   412         {
   413             // Oh this is evil. Somebody kill me now.
   414             nsCOMPtr<nsISimpleEnumerator> children;
   415             rv = GetFolderList(source, false, true, getter_AddRefs(children));
   416             if (NS_FAILED(rv) || (rv == NS_RDF_NO_VALUE)) return(rv);
   418             bool hasMore;
   419             rv = children->HasMoreElements(&hasMore);
   420             if (NS_FAILED(rv)) return(rv);
   422             if (hasMore)
   423             {
   424                 nsCOMPtr<nsISupports> isupports;
   425                 rv = children->GetNext(getter_AddRefs(isupports));
   426                 if (NS_FAILED(rv)) return(rv);
   428                 return isupports->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   429             }
   430         }
   431 #ifdef USE_NC_EXTENSION
   432         else if (property == mNC_extension)
   433         {
   434             nsCOMPtr<nsIRDFLiteral> extension;
   435             rv = GetExtension(source, getter_AddRefs(extension));
   436             if (!extension)    rv = NS_RDF_NO_VALUE;
   437             if (rv == NS_RDF_NO_VALUE) return(rv);
   438             return extension->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
   439         }
   440 #endif
   441     }
   443     return(NS_RDF_NO_VALUE);
   444 }
   448 NS_IMETHODIMP
   449 FileSystemDataSource::GetTargets(nsIRDFResource *source,
   450                 nsIRDFResource *property,
   451                 bool tv,
   452                 nsISimpleEnumerator **targets /* out */)
   453 {
   454     NS_PRECONDITION(source != nullptr, "null ptr");
   455     if (! source)
   456         return NS_ERROR_NULL_POINTER;
   458     NS_PRECONDITION(property != nullptr, "null ptr");
   459     if (! property)
   460         return NS_ERROR_NULL_POINTER;
   462     NS_PRECONDITION(targets != nullptr, "null ptr");
   463     if (! targets)
   464         return NS_ERROR_NULL_POINTER;
   466     *targets = nullptr;
   468     // we only have positive assertions in the file system data source.
   469     if (! tv)
   470         return NS_RDF_NO_VALUE;
   472     nsresult rv;
   474     if (source == mNC_FileSystemRoot)
   475     {
   476         if (property == mNC_Child)
   477         {
   478             return GetVolumeList(targets);
   479         }
   480         else if (property == mNC_pulse)
   481         {
   482             nsCOMPtr<nsIRDFLiteral> pulseLiteral;
   483             mRDFService->GetLiteral(MOZ_UTF16("12"),
   484                                     getter_AddRefs(pulseLiteral));
   485             return NS_NewSingletonEnumerator(targets, pulseLiteral);
   486         }
   487     }
   488     else if (isFileURI(source))
   489     {
   490         if (property == mNC_Child)
   491         {
   492             return GetFolderList(source, false, false, targets);
   493         }
   494         else if (property == mNC_Name)
   495         {
   496             nsCOMPtr<nsIRDFLiteral> name;
   497             rv = GetName(source, getter_AddRefs(name));
   498             if (NS_FAILED(rv)) return rv;
   500             return NS_NewSingletonEnumerator(targets, name);
   501         }
   502         else if (property == mNC_URL)
   503         {
   504             nsCOMPtr<nsIRDFLiteral> url;
   505             rv = GetURL(source, nullptr, getter_AddRefs(url));
   506             if (NS_FAILED(rv)) return rv;
   508             return NS_NewSingletonEnumerator(targets, url);
   509         }
   510         else if (property == mRDF_type)
   511         {
   512             nsCString uri;
   513             rv = mNC_FileSystemObject->GetValueUTF8(uri);
   514             if (NS_FAILED(rv)) return rv;
   516             NS_ConvertUTF8toUTF16 url(uri);
   518             nsCOMPtr<nsIRDFLiteral> literal;
   519             rv = mRDFService->GetLiteral(url.get(), getter_AddRefs(literal));
   520             if (NS_FAILED(rv)) return rv;
   522             return NS_NewSingletonEnumerator(targets, literal);
   523         }
   524         else if (property == mNC_pulse)
   525         {
   526             nsCOMPtr<nsIRDFLiteral> pulseLiteral;
   527             rv = mRDFService->GetLiteral(MOZ_UTF16("12"),
   528                 getter_AddRefs(pulseLiteral));
   529             if (NS_FAILED(rv)) return rv;
   531             return NS_NewSingletonEnumerator(targets, pulseLiteral);
   532         }
   533     }
   535     return NS_NewEmptyEnumerator(targets);
   536 }
   540 NS_IMETHODIMP
   541 FileSystemDataSource::Assert(nsIRDFResource *source,
   542                        nsIRDFResource *property,
   543                        nsIRDFNode *target,
   544                        bool tv)
   545 {
   546     return NS_RDF_ASSERTION_REJECTED;
   547 }
   551 NS_IMETHODIMP
   552 FileSystemDataSource::Unassert(nsIRDFResource *source,
   553                          nsIRDFResource *property,
   554                          nsIRDFNode *target)
   555 {
   556     return NS_RDF_ASSERTION_REJECTED;
   557 }
   561 NS_IMETHODIMP
   562 FileSystemDataSource::Change(nsIRDFResource* aSource,
   563                              nsIRDFResource* aProperty,
   564                              nsIRDFNode* aOldTarget,
   565                              nsIRDFNode* aNewTarget)
   566 {
   567     return NS_RDF_ASSERTION_REJECTED;
   568 }
   572 NS_IMETHODIMP
   573 FileSystemDataSource::Move(nsIRDFResource* aOldSource,
   574                            nsIRDFResource* aNewSource,
   575                            nsIRDFResource* aProperty,
   576                            nsIRDFNode* aTarget)
   577 {
   578     return NS_RDF_ASSERTION_REJECTED;
   579 }
   583 NS_IMETHODIMP
   584 FileSystemDataSource::HasAssertion(nsIRDFResource *source,
   585                              nsIRDFResource *property,
   586                              nsIRDFNode *target,
   587                              bool tv,
   588                              bool *hasAssertion /* out */)
   589 {
   590     NS_PRECONDITION(source != nullptr, "null ptr");
   591     if (! source)
   592         return NS_ERROR_NULL_POINTER;
   594     NS_PRECONDITION(property != nullptr, "null ptr");
   595     if (! property)
   596         return NS_ERROR_NULL_POINTER;
   598     NS_PRECONDITION(target != nullptr, "null ptr");
   599     if (! target)
   600         return NS_ERROR_NULL_POINTER;
   602     NS_PRECONDITION(hasAssertion != nullptr, "null ptr");
   603     if (! hasAssertion)
   604         return NS_ERROR_NULL_POINTER;
   606     // we only have positive assertions in the file system data source.
   607     *hasAssertion = false;
   609     if (! tv) {
   610         return NS_OK;
   611     }
   613     if ((source == mNC_FileSystemRoot) || isFileURI(source))
   614     {
   615         if (property == mRDF_type)
   616         {
   617             nsCOMPtr<nsIRDFResource> resource( do_QueryInterface(target) );
   618             if (resource.get() == mRDF_type)
   619             {
   620                 *hasAssertion = true;
   621             }
   622         }
   623 #ifdef USE_NC_EXTENSION
   624         else if (property == mNC_extension)
   625         {
   626             // Cheat just a little here by making dirs always match
   627             if (isDirURI(source))
   628             {
   629                 *hasAssertion = true;
   630             }
   631             else
   632             {
   633                 nsCOMPtr<nsIRDFLiteral> extension;
   634                 GetExtension(source, getter_AddRefs(extension));
   635                 if (extension.get() == target)
   636                 {
   637                     *hasAssertion = true;
   638                 }
   639             }
   640         }
   641 #endif
   642         else if (property == mNC_IsDirectory)
   643         {
   644             bool isDir = isDirURI(source);
   645             bool isEqual = false;
   646             target->EqualsNode(mLiteralTrue, &isEqual);
   647             if (isEqual)
   648             {
   649                 *hasAssertion = isDir;
   650             }
   651             else
   652             {
   653                 target->EqualsNode(mLiteralFalse, &isEqual);
   654                 if (isEqual)
   655                     *hasAssertion = !isDir;
   656             }
   657         }
   658     }
   660     return NS_OK;
   661 }
   665 NS_IMETHODIMP 
   666 FileSystemDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
   667 {
   668     return NS_ERROR_NOT_IMPLEMENTED;
   669 }
   673 NS_IMETHODIMP 
   674 FileSystemDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
   675 {
   676     *result = false;
   678     if (aSource == mNC_FileSystemRoot)
   679     {
   680         *result = (aArc == mNC_Child || aArc == mNC_pulse);
   681     }
   682     else if (isFileURI(aSource))
   683     {
   684         if (aArc == mNC_pulse)
   685         {
   686             *result = true;
   687         }
   688         else if (isDirURI(aSource))
   689         {
   690 #ifdef  XP_WIN
   691             *result = isValidFolder(aSource);
   692 #else
   693             *result = true;
   694 #endif
   695         }
   696         else if (aArc == mNC_pulse || aArc == mNC_Name || aArc == mNC_Icon ||
   697                  aArc == mNC_URL || aArc == mNC_Length || aArc == mWEB_LastMod ||
   698                  aArc == mNC_FileSystemObject || aArc == mRDF_InstanceOf ||
   699                  aArc == mRDF_type)
   700         {
   701             *result = true;
   702         }
   703     }
   704     return NS_OK;
   705 }
   709 NS_IMETHODIMP
   710 FileSystemDataSource::ArcLabelsIn(nsIRDFNode *node,
   711                             nsISimpleEnumerator ** labels /* out */)
   712 {
   713 //  NS_NOTYETIMPLEMENTED("write me");
   714     return NS_ERROR_NOT_IMPLEMENTED;
   715 }
   719 NS_IMETHODIMP
   720 FileSystemDataSource::ArcLabelsOut(nsIRDFResource *source,
   721                    nsISimpleEnumerator **labels /* out */)
   722 {
   723     NS_PRECONDITION(source != nullptr, "null ptr");
   724     if (! source)
   725     return NS_ERROR_NULL_POINTER;
   727     NS_PRECONDITION(labels != nullptr, "null ptr");
   728     if (! labels)
   729     return NS_ERROR_NULL_POINTER;
   731     if (source == mNC_FileSystemRoot)
   732     {
   733         nsCOMArray<nsIRDFResource> resources;
   734         resources.SetCapacity(2);
   736         resources.AppendObject(mNC_Child);
   737         resources.AppendObject(mNC_pulse);
   739         return NS_NewArrayEnumerator(labels, resources);
   740     }
   741     else if (isFileURI(source))
   742     {
   743         nsCOMArray<nsIRDFResource> resources;
   744         resources.SetCapacity(2);
   746         if (isDirURI(source))
   747         {
   748 #ifdef  XP_WIN
   749             if (isValidFolder(source))
   750             {
   751                 resources.AppendObject(mNC_Child);
   752             }
   753 #else
   754             resources.AppendObject(mNC_Child);
   755 #endif
   756             resources.AppendObject(mNC_pulse);
   757         }
   759         return NS_NewArrayEnumerator(labels, resources);
   760     }
   762     return NS_NewEmptyEnumerator(labels);
   763 }
   767 NS_IMETHODIMP
   768 FileSystemDataSource::GetAllResources(nsISimpleEnumerator** aCursor)
   769 {
   770     NS_NOTYETIMPLEMENTED("sorry!");
   771     return NS_ERROR_NOT_IMPLEMENTED;
   772 }
   776 NS_IMETHODIMP
   777 FileSystemDataSource::AddObserver(nsIRDFObserver *n)
   778 {
   779     return NS_ERROR_NOT_IMPLEMENTED;
   780 }
   784 NS_IMETHODIMP
   785 FileSystemDataSource::RemoveObserver(nsIRDFObserver *n)
   786 {
   787     return NS_ERROR_NOT_IMPLEMENTED;
   788 }
   792 NS_IMETHODIMP
   793 FileSystemDataSource::GetAllCmds(nsIRDFResource* source,
   794                                      nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
   795 {
   796     return(NS_NewEmptyEnumerator(commands));
   797 }
   801 NS_IMETHODIMP
   802 FileSystemDataSource::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
   803                                        nsIRDFResource*   aCommand,
   804                                        nsISupportsArray/*<nsIRDFResource>*/* aArguments,
   805                                        bool* aResult)
   806 {
   807     return(NS_ERROR_NOT_IMPLEMENTED);
   808 }
   812 NS_IMETHODIMP
   813 FileSystemDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
   814                                 nsIRDFResource*   aCommand,
   815                                 nsISupportsArray/*<nsIRDFResource>*/* aArguments)
   816 {
   817     return(NS_ERROR_NOT_IMPLEMENTED);
   818 }
   822 NS_IMETHODIMP
   823 FileSystemDataSource::BeginUpdateBatch()
   824 {
   825     return NS_OK;
   826 }
   830 NS_IMETHODIMP
   831 FileSystemDataSource::EndUpdateBatch()
   832 {
   833     return NS_OK;
   834 }
   838 nsresult
   839 FileSystemDataSource::GetVolumeList(nsISimpleEnumerator** aResult)
   840 {
   841     nsCOMArray<nsIRDFResource> volumes;
   842     nsCOMPtr<nsIRDFResource> vol;
   844 #ifdef XP_WIN
   846     int32_t         driveType;
   847     wchar_t         drive[32];
   848     int32_t         volNum;
   850     for (volNum = 0; volNum < 26; volNum++)
   851     {
   852         swprintf( drive, L"%c:\\", volNum + (char16_t)'A');
   854         driveType = GetDriveTypeW(drive);
   855         if (driveType != DRIVE_UNKNOWN && driveType != DRIVE_NO_ROOT_DIR)
   856         {
   857           nsAutoCString url;
   858           url.AppendPrintf("file:///%c|/", volNum + 'A');
   859           nsresult rv = mRDFService->GetResource(url, getter_AddRefs(vol));
   860           if (NS_FAILED(rv))
   861             return rv;
   863           volumes.AppendObject(vol);
   864         }
   865     }
   866 #endif
   868 #ifdef XP_UNIX
   869     mRDFService->GetResource(NS_LITERAL_CSTRING("file:///"), getter_AddRefs(vol));
   870     volumes.AppendObject(vol);
   871 #endif
   873     return NS_NewArrayEnumerator(aResult, volumes);
   874 }
   878 #ifdef  XP_WIN
   879 bool
   880 FileSystemDataSource::isValidFolder(nsIRDFResource *source)
   881 {
   882     bool    isValid = true;
   883     if (ieFavoritesDir.IsEmpty())    return(isValid);
   885     nsresult        rv;
   886     nsCString       uri;
   887     rv = source->GetValueUTF8(uri);
   888     if (NS_FAILED(rv)) return(isValid);
   890     NS_ConvertUTF8toUTF16 theURI(uri);
   891     if (theURI.Find(ieFavoritesDir) == 0)
   892     {
   893         isValid = false;
   895         nsCOMPtr<nsISimpleEnumerator>   folderEnum;
   896         if (NS_SUCCEEDED(rv = GetFolderList(source, true, false, getter_AddRefs(folderEnum))))
   897         {
   898             bool        hasAny = false, hasMore;
   899             while (NS_SUCCEEDED(folderEnum->HasMoreElements(&hasMore)) &&
   900                    hasMore)
   901             {
   902                 hasAny = true;
   904                 nsCOMPtr<nsISupports>       isupports;
   905                 if (NS_FAILED(rv = folderEnum->GetNext(getter_AddRefs(isupports))))
   906                     break;
   907                 nsCOMPtr<nsIRDFResource>    res = do_QueryInterface(isupports);
   908                 if (!res)   break;
   910                 nsCOMPtr<nsIRDFLiteral>     nameLiteral;
   911                 if (NS_FAILED(rv = GetName(res, getter_AddRefs(nameLiteral))))
   912                     break;
   914                 const char16_t         *uniName;
   915                 if (NS_FAILED(rv = nameLiteral->GetValueConst(&uniName)))
   916                     break;
   917                 nsAutoString            name(uniName);
   919                 // An empty folder, or a folder that contains just "desktop.ini",
   920                 // is considered to be a IE Favorite; otherwise, its a folder
   921                 if (!name.LowerCaseEqualsLiteral("desktop.ini"))
   922                 {
   923                     isValid = true;
   924                     break;
   925                 }
   926             }
   927             if (!hasAny) isValid = true;
   928         }
   929     }
   930     return(isValid);
   931 }
   932 #endif
   936 nsresult
   937 FileSystemDataSource::GetFolderList(nsIRDFResource *source, bool allowHidden,
   938                 bool onlyFirst, nsISimpleEnumerator** aResult)
   939 {
   940     if (!isDirURI(source))
   941         return(NS_RDF_NO_VALUE);
   943     nsresult                    rv;
   945     const char      *parentURI = nullptr;
   946     rv = source->GetValueConst(&parentURI);
   947     if (NS_FAILED(rv))
   948         return(rv);
   949     if (!parentURI)
   950         return(NS_ERROR_UNEXPECTED);
   952     nsCOMPtr<nsIURI>    aIURI;
   953     if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(parentURI))))
   954         return(rv);
   956     nsCOMPtr<nsIFileURL>    fileURL = do_QueryInterface(aIURI);
   957     if (!fileURL)
   958         return NS_OK;
   960     nsCOMPtr<nsIFile>   aDir;
   961     if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aDir))))
   962         return(rv);
   964     // ensure that we DO NOT resolve aliases
   965     aDir->SetFollowLinks(false);
   967     nsCOMPtr<nsISimpleEnumerator>   dirContents;
   968     if (NS_FAILED(rv = aDir->GetDirectoryEntries(getter_AddRefs(dirContents))))
   969         return(rv);
   970     if (!dirContents)
   971         return(NS_ERROR_UNEXPECTED);
   973     nsCOMArray<nsIRDFResource> resources;
   974     bool            hasMore;
   975     while(NS_SUCCEEDED(rv = dirContents->HasMoreElements(&hasMore)) &&
   976           hasMore)
   977     {
   978         nsCOMPtr<nsISupports>   isupports;
   979         if (NS_FAILED(rv = dirContents->GetNext(getter_AddRefs(isupports))))
   980             break;
   982         nsCOMPtr<nsIFile>   aFile = do_QueryInterface(isupports);
   983         if (!aFile)
   984             break;
   986         if (!allowHidden)
   987         {
   988             bool            hiddenFlag = false;
   989             if (NS_FAILED(rv = aFile->IsHidden(&hiddenFlag)))
   990                 break;
   991             if (hiddenFlag)
   992                 continue;
   993         }
   995         nsAutoString leafStr;
   996         if (NS_FAILED(rv = aFile->GetLeafName(leafStr)))
   997             break;
   998         if (leafStr.IsEmpty())
   999             continue;
  1001         nsAutoCString           fullURI;
  1002         fullURI.Assign(parentURI);
  1003         if (fullURI.Last() != '/')
  1005             fullURI.Append('/');
  1008         char    *escLeafStr = nsEscape(NS_ConvertUTF16toUTF8(leafStr).get(), url_Path);
  1009         leafStr.Truncate();
  1011         if (!escLeafStr)
  1012             continue;
  1014         nsAutoCString           leaf(escLeafStr);
  1015         NS_Free(escLeafStr);
  1016         escLeafStr = nullptr;
  1018         // using nsEscape() [above] doesn't escape slashes, so do that by hand
  1019         int32_t         aOffset;
  1020         while ((aOffset = leaf.FindChar('/')) >= 0)
  1022             leaf.Cut((uint32_t)aOffset, 1);
  1023             leaf.Insert("%2F", (uint32_t)aOffset);
  1026         // append the encoded name
  1027         fullURI.Append(leaf);
  1029         bool            dirFlag = false;
  1030         rv = aFile->IsDirectory(&dirFlag);
  1031         if (NS_SUCCEEDED(rv) && dirFlag)
  1033             fullURI.Append('/');
  1036         nsCOMPtr<nsIRDFResource>    fileRes;
  1037         mRDFService->GetResource(fullURI, getter_AddRefs(fileRes));
  1039         resources.AppendObject(fileRes);
  1041         if (onlyFirst)
  1042             break;
  1045     return NS_NewArrayEnumerator(aResult, resources);
  1048 nsresult
  1049 FileSystemDataSource::GetLastMod(nsIRDFResource *source, nsIRDFDate **aResult)
  1051     *aResult = nullptr;
  1053     nsresult        rv;
  1054     const char      *uri = nullptr;
  1056     rv = source->GetValueConst(&uri);
  1057     if (NS_FAILED(rv)) return(rv);
  1058     if (!uri)
  1059         return(NS_ERROR_UNEXPECTED);
  1061     nsCOMPtr<nsIURI>    aIURI;
  1062     if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
  1063         return(rv);
  1065     nsCOMPtr<nsIFileURL>    fileURL = do_QueryInterface(aIURI);
  1066     if (!fileURL)
  1067         return NS_OK;
  1069     nsCOMPtr<nsIFile>   aFile;
  1070     if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
  1071         return(rv);
  1072     if (!aFile)
  1073         return(NS_ERROR_UNEXPECTED);
  1075     // ensure that we DO NOT resolve aliases
  1076     aFile->SetFollowLinks(false);
  1078     PRTime lastModDate;
  1079     if (NS_FAILED(rv = aFile->GetLastModifiedTime(&lastModDate)))
  1080         return(rv);
  1082     // convert from milliseconds to seconds
  1083     mRDFService->GetDateLiteral(lastModDate * PR_MSEC_PER_SEC, aResult);
  1085     return(NS_OK);
  1090 nsresult
  1091 FileSystemDataSource::GetFileSize(nsIRDFResource *source, nsIRDFInt **aResult)
  1093     *aResult = nullptr;
  1095     nsresult        rv;
  1096     const char      *uri = nullptr;
  1098     rv = source->GetValueConst(&uri);
  1099     if (NS_FAILED(rv))
  1100         return(rv);
  1101     if (!uri)
  1102         return(NS_ERROR_UNEXPECTED);
  1104     nsCOMPtr<nsIURI>    aIURI;
  1105     if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
  1106         return(rv);
  1108     nsCOMPtr<nsIFileURL>    fileURL = do_QueryInterface(aIURI);
  1109     if (!fileURL)
  1110         return NS_OK;
  1112     nsCOMPtr<nsIFile>   aFile;
  1113     if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
  1114         return(rv);
  1115     if (!aFile)
  1116         return(NS_ERROR_UNEXPECTED);
  1118     // ensure that we DO NOT resolve aliases
  1119     aFile->SetFollowLinks(false);
  1121     // don't do anything with directories
  1122     bool    isDir = false;
  1123     if (NS_FAILED(rv = aFile->IsDirectory(&isDir)))
  1124         return(rv);
  1125     if (isDir)
  1126         return(NS_RDF_NO_VALUE);
  1128     int64_t     aFileSize64;
  1129     if (NS_FAILED(rv = aFile->GetFileSize(&aFileSize64)))
  1130         return(rv);
  1132     // convert 64bits to 32bits
  1133     int32_t aFileSize32 = int32_t(aFileSize64);
  1134     mRDFService->GetIntLiteral(aFileSize32, aResult);
  1136     return(NS_OK);
  1141 nsresult
  1142 FileSystemDataSource::GetName(nsIRDFResource *source, nsIRDFLiteral **aResult)
  1144     nsresult        rv;
  1145     const char      *uri = nullptr;
  1147     rv = source->GetValueConst(&uri);
  1148     if (NS_FAILED(rv))
  1149         return(rv);
  1150     if (!uri)
  1151         return(NS_ERROR_UNEXPECTED);
  1153     nsCOMPtr<nsIURI>    aIURI;
  1154     if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
  1155         return(rv);
  1157     nsCOMPtr<nsIFileURL>    fileURL = do_QueryInterface(aIURI);
  1158     if (!fileURL)
  1159         return NS_OK;
  1161     nsCOMPtr<nsIFile>   aFile;
  1162     if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
  1163         return(rv);
  1164     if (!aFile)
  1165         return(NS_ERROR_UNEXPECTED);
  1167     // ensure that we DO NOT resolve aliases
  1168     aFile->SetFollowLinks(false);
  1170     nsAutoString name;
  1171     if (NS_FAILED(rv = aFile->GetLeafName(name)))
  1172         return(rv);
  1173     if (name.IsEmpty())
  1174         return(NS_ERROR_UNEXPECTED);
  1176 #ifdef  XP_WIN
  1177     // special hack for IE favorites under Windows; strip off the
  1178     // trailing ".url" or ".lnk" at the end of IE favorites names
  1179     int32_t nameLen = name.Length();
  1180     if ((strncmp(uri, ieFavoritesDir.get(), ieFavoritesDir.Length()) == 0) && (nameLen > 4))
  1182         nsAutoString extension;
  1183         name.Right(extension, 4);
  1184         if (extension.LowerCaseEqualsLiteral(".url") ||
  1185             extension.LowerCaseEqualsLiteral(".lnk"))
  1187             name.Truncate(nameLen - 4);
  1190 #endif
  1192     mRDFService->GetLiteral(name.get(), aResult);
  1194     return NS_OK;
  1199 #ifdef USE_NC_EXTENSION
  1200 nsresult
  1201 FileSystemDataSource::GetExtension(nsIRDFResource *source, nsIRDFLiteral **aResult)
  1203     nsCOMPtr<nsIRDFLiteral> name;
  1204     nsresult rv = GetName(source, getter_AddRefs(name));
  1205     if (NS_FAILED(rv))
  1206         return rv;
  1208     const char16_t* unicodeLeafName;
  1209     rv = name->GetValueConst(&unicodeLeafName);
  1210     if (NS_FAILED(rv))
  1211         return rv;
  1213     nsAutoString filename(unicodeLeafName);
  1214     int32_t lastDot = filename.RFindChar('.');
  1215     if (lastDot == -1)
  1217         mRDFService->GetLiteral(EmptyString().get(), aResult);
  1219     else
  1221         nsAutoString extension;
  1222         filename.Right(extension, (filename.Length() - lastDot));
  1223         mRDFService->GetLiteral(extension.get(), aResult);
  1226     return NS_OK;
  1228 #endif
  1230 #ifdef  XP_WIN
  1231 nsresult
  1232 FileSystemDataSource::getIEFavoriteURL(nsIRDFResource *source, nsString aFileURL, nsIRDFLiteral **urlLiteral)
  1234     nsresult        rv = NS_OK;
  1236     *urlLiteral = nullptr;
  1238     nsCOMPtr<nsIFile> f;
  1239     NS_GetFileFromURLSpec(NS_ConvertUTF16toUTF8(aFileURL), getter_AddRefs(f)); 
  1241     bool value;
  1243     if (NS_SUCCEEDED(f->IsDirectory(&value)) && value)
  1245         if (isValidFolder(source))
  1246             return(NS_RDF_NO_VALUE);
  1247         aFileURL.AppendLiteral("desktop.ini");
  1249     else if (aFileURL.Length() > 4)
  1251         nsAutoString    extension;
  1253         aFileURL.Right(extension, 4);
  1254         if (!extension.LowerCaseEqualsLiteral(".url"))
  1256             return(NS_RDF_NO_VALUE);
  1260     nsCOMPtr<nsIInputStream> strm;
  1261     NS_NewLocalFileInputStream(getter_AddRefs(strm),f);
  1262     nsCOMPtr<nsILineInputStream> linereader = do_QueryInterface(strm, &rv);
  1264     nsAutoString    line;
  1265     nsAutoCString   cLine;
  1266     while(NS_SUCCEEDED(rv))
  1268         bool    isEOF;
  1269         rv = linereader->ReadLine(cLine, &isEOF);
  1270         CopyASCIItoUTF16(cLine, line);
  1272         if (isEOF)
  1274             if (line.Find("URL=", true) == 0)
  1276                 line.Cut(0, 4);
  1277                 rv = mRDFService->GetLiteral(line.get(), urlLiteral);
  1278                 break;
  1280             else if (line.Find("CDFURL=", true) == 0)
  1282                 line.Cut(0, 7);
  1283                 rv = mRDFService->GetLiteral(line.get(), urlLiteral);
  1284                 break;
  1286             line.Truncate();
  1290     return(rv);
  1292 #endif
  1296 nsresult
  1297 FileSystemDataSource::GetURL(nsIRDFResource *source, bool *isFavorite, nsIRDFLiteral** aResult)
  1299     if (isFavorite) *isFavorite = false;
  1301     nsresult        rv;
  1302     nsCString       uri;
  1304     rv = source->GetValueUTF8(uri);
  1305     if (NS_FAILED(rv))
  1306         return(rv);
  1308     NS_ConvertUTF8toUTF16 url(uri);
  1310 #ifdef  XP_WIN
  1311     // under Windows, if its an IE favorite, munge the URL
  1312     if (!ieFavoritesDir.IsEmpty())
  1314         if (url.Find(ieFavoritesDir) == 0)
  1316             if (isFavorite) *isFavorite = true;
  1317             rv = getIEFavoriteURL(source, url, aResult);
  1318             return(rv);
  1321 #endif
  1323     // if we fall through to here, its not any type of bookmark
  1324     // stored in the platform native file system, so just set the URL
  1326     mRDFService->GetLiteral(url.get(), aResult);
  1328     return(NS_OK);

mercurial