Education/Learning/UnderstandingXpcomFiles: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 165: Line 165:


The followLinks attribute becomes ::GetFollowLinks and ::SetFollowLinks, and diskSpaceAvailable becomes ::GetDiskSpaceAvailable.  Simple when you know, and used everywhere in the source.
The followLinks attribute becomes ::GetFollowLinks and ::SetFollowLinks, and diskSpaceAvailable becomes ::GetDiskSpaceAvailable.  Simple when you know, and used everywhere in the source.
=== nsI vs. ns ===
The interface is named '''nsILocalFile''' and the implementations are all named '''nsLocalFile*''', dropping the ''I''.  This is another obvious thing once you know to look for it, but can be confusing when you start and your eye skims over '''nsIFoo''' and '''nsFoo''' as though they were the same thing.  Incidentally, the ''ns'' prefix stands for Netscape, and you'll also sometimes encounter ''mozI'' and ''moz'' as a naming prefix. 


== Interface Implementations ==
== Interface Implementations ==
Line 188: Line 192:
  83 #endif
  83 #endif


[http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileCommon.cpp nsLocalFileCommon.cpp] includes [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFile.h nsLocalFile.h], and therefore all the platform specific headers we added above.  It implements some common elements of the interface, leaving specifics to platform-specific implementations.  If we take Windows and [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileWin.h nsLocalFileWin.h] as an example, we see where the NS_DECL_NSILOCALFILE macro gets used:
The build system once again does the heavy lifting and figures out which implementation to use at compile time (see [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/Makefile.in Makefile.in]):
 
82    // nsILocalFile interface
83    NS_DECL_NSILOCALFILE
 
We also see how
 
 
 
 
 
 
 
* nsILocalFileWin
* nsILocalFileUnix
* nsILocalFileOS2
* nsILocalFileOSX
 
Depending on the operating system we are on, we need to implement this interface differently (the 'XP' in XPCOM stands for cross-platform, after all).  The build system once again does the heavy lifting and figures out which implementation to use at compile time (see [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/Makefile.in Makefile.in]):


  91  ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
  91  ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
Line 222: Line 208:
  103 endif # OS2
  103 endif # OS2


=== nsI vs. ns ===
[http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileCommon.cpp nsLocalFileCommon.cpp] includes [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFile.h nsLocalFile.h], and therefore all the platform specific headers we added above.  It implements some common elements of the interface, leaving specifics to platform-specific implementations.  If we take Windows and [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileWin.h nsLocalFileWin.h] as an example, we see where the NS_DECL_NSILOCALFILE macro gets used, and therefore where our interface gets declared:
 
82    // nsILocalFile interface
83    NS_DECL_NSILOCALFILE
 
We also see how our interface methods and attributes get implemented for this platform.  Here is the code for the '''followLinks''' attribute and '''launch''' method:
 
<pre>
2565 /* attribute PRBool followLinks; */
2566 NS_IMETHODIMP
2567 nsLocalFile::GetFollowLinks(PRBool *aFollowLinks)
2568 {
2569    *aFollowLinks = mFollowSymlinks;
2570    return NS_OK;
2571 }
2572 NS_IMETHODIMP
2573 nsLocalFile::SetFollowLinks(PRBool aFollowLinks)
2574 {
2575    MakeDirty();
2576    mFollowSymlinks = aFollowLinks;
2577    return NS_OK;
2578 }
...
2678 NS_IMETHODIMP
2679 nsLocalFile::Launch()
2680 {
2681    const nsString &path = mWorkingPath;
2682
2683    // use the app registry name to launch a shell execute....
2684    LONG r = (LONG) ::ShellExecuteW(NULL, NULL, path.get(), NULL, NULL,
2685                                    SW_SHOWNORMAL);
2686
2687    // if the file has no association, we launch windows' "what do you want to do" dialog
2688    if (r == SE_ERR_NOASSOC) {
2689        nsAutoString shellArg;
2690        shellArg.Assign(NS_LITERAL_STRING("shell32.dll,OpenAs_RunDLL ") + path);
2691        r = (LONG) ::ShellExecuteW(NULL, NULL, L"RUNDLL32.EXE", shellArg.get(),
2692                                    NULL, SW_SHOWNORMAL);
2693    }
2694    if (r < 32) {
2695        switch (r) {
2696          case 0:
2697          case SE_ERR_OOM:
2698            return NS_ERROR_OUT_OF_MEMORY;
2699          case ERROR_FILE_NOT_FOUND:
2700            return NS_ERROR_FILE_NOT_FOUND;
2701          case ERROR_PATH_NOT_FOUND:
2702            return NS_ERROR_FILE_UNRECOGNIZED_PATH;
2703          case ERROR_BAD_FORMAT:
2704            return NS_ERROR_FILE_CORRUPTED;
2705          case SE_ERR_ACCESSDENIED:
2706            return NS_ERROR_FILE_ACCESS_DENIED;
2707          case SE_ERR_ASSOCINCOMPLETE:
2708          case SE_ERR_NOASSOC:
2709            return NS_ERROR_UNEXPECTED;
2710          case SE_ERR_DDEBUSY:
2711          case SE_ERR_DDEFAIL:
2712          case SE_ERR_DDETIMEOUT:
2713            return NS_ERROR_NOT_AVAILABLE;
2714          case SE_ERR_DLLNOTFOUND:
2715            return NS_ERROR_FAILURE;
2716          case SE_ERR_SHARE:
2717            return NS_ERROR_FILE_IS_LOCKED;
2718          default:
2719            return NS_ERROR_FILE_EXECUTION_FAILED;
2720        }
2721    }
2722    return NS_OK;
2723 }
</pre>
 
== Conclusion ==
 
We've followed the chain from our IDL to a C++ implementation specific to Windows, in the processing visiting:


The interface is named '''nsILocalFile''' and our four implementations are all named '''nsLocalFile*''', dropping the ''I''. This is another obvious thing once you know to look for it, but can be confusing when you start and your eye skims over '''nsIFoo''' and '''nsFoo''' as though they were the same thing. Incidentally, the ''ns'' prefix stands for Netscape, and you'll also sometimes encounter ''mozI'' and ''moz'' as a naming prefix.  
* nsILocalFile.idl
* nsILocalFile.h
* nsLocalFile.h
* nsLocalFileWin.h
* nsLocalFileCommon.cpp
* nsLocalFileWin.cpp


Understanding the difference between all these files, and knowing where to look for them, goes along way to helping you understand the code.


still editing...
For further information about how to use XPCOM interfaces like nsILocalFile, see [[Education/Learning/UsingXpcom|Using XPCOM Components in C++ and JavaScript]].
Confirmed users
656

edits

Navigation menu