xpcom/sample/nsSample.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/. */
     7 /**
     8  *
     9  * A sample of XPConnect. This file contains an implementation nsSample
    10  * of the interface nsISample.
    11  *
    12  */
    13 #include <stdio.h>
    15 #include "nsSample.h"
    16 #include "nsMemory.h"
    18 #include "nsEmbedString.h"
    19 #include "nsIClassInfoImpl.h"
    20 ////////////////////////////////////////////////////////////////////////
    22 nsSampleImpl::nsSampleImpl() : mValue(nullptr)
    23 {
    24     mValue = (char*)nsMemory::Clone("initial value", 14);
    25 }
    27 nsSampleImpl::~nsSampleImpl()
    28 {
    29     if (mValue)
    30         nsMemory::Free(mValue);
    31 }
    33 /**
    34  * NS_IMPL_ISUPPORTS expands to a simple implementation of the nsISupports
    35  * interface.  This includes a proper implementation of AddRef, Release,
    36  * and QueryInterface.  If this class supported more interfaces than just
    37  * nsISupports, 
    38  * you could use NS_IMPL_ADDREF() and NS_IMPL_RELEASE() to take care of the
    39  * simple stuff, but you would have to create QueryInterface on your own.
    40  * nsSampleFactory.cpp is an example of this approach.
    41  * Notice that the second parameter to the macro is name of the interface, and
    42  * NOT the #defined IID.
    43  *
    44  * The _CI variant adds support for nsIClassInfo, which permits introspection
    45  * and interface flattening.
    46  */
    47 NS_IMPL_CLASSINFO(nsSampleImpl, nullptr, 0, NS_SAMPLE_CID)
    48 NS_IMPL_ISUPPORTS_CI(nsSampleImpl, nsISample)
    49 /**
    50  * Notice that in the protoype for this function, the NS_IMETHOD macro was
    51  * used to declare the return type.  For the implementation, the return
    52  * type is declared by NS_IMETHODIMP
    53  */
    54 NS_IMETHODIMP
    55 nsSampleImpl::GetValue(char** aValue)
    56 {
    57     NS_PRECONDITION(aValue != nullptr, "null ptr");
    58     if (! aValue)
    59         return NS_ERROR_NULL_POINTER;
    61     if (mValue) {
    62         /**
    63          * GetValue's job is to return data known by an instance of
    64          * nsSampleImpl to the outside world.  If we  were to simply return 
    65          * a pointer to data owned by this instance, and the client were to
    66          * free it, bad things would surely follow.
    67          * On the other hand, if we create a new copy of the data for our
    68          * client, and it turns out that client is implemented in JavaScript,
    69          * there would be no way to free the buffer.  The solution to the 
    70          * buffer ownership problem is the nsMemory singleton.  Any buffer
    71          * returned by an XPCOM method should be allocated by the nsMemory.
    72          * This convention lets things like JavaScript reflection do their
    73          * job, and simplifies the way C++ clients deal with returned buffers.
    74          */
    75         *aValue = (char*) nsMemory::Clone(mValue, strlen(mValue) + 1);
    76         if (! *aValue)
    77             return NS_ERROR_NULL_POINTER;
    78     }
    79     else {
    80         *aValue = nullptr;
    81     }
    82     return NS_OK;
    83 }
    85 NS_IMETHODIMP
    86 nsSampleImpl::SetValue(const char* aValue)
    87 {
    88     NS_PRECONDITION(aValue != nullptr, "null ptr");
    89     if (! aValue)
    90         return NS_ERROR_NULL_POINTER;
    92     if (mValue) {
    93         nsMemory::Free(mValue);
    94     }
    96     /**
    97      * Another buffer passing convention is that buffers passed INTO your
    98      * object ARE NOT YOURS.  Keep your hands off them, unless they are
    99      * declared "inout".  If you want to keep the value for posterity,
   100      * you will have to make a copy of it.
   101      */
   102     mValue = (char*) nsMemory::Clone(aValue, strlen(aValue) + 1);
   103     return NS_OK;
   104 }
   106 NS_IMETHODIMP
   107 nsSampleImpl::Poke(const char* aValue)
   108 {
   109     return SetValue((char*) aValue);
   110 }
   113 static void GetStringValue(nsACString& aValue)
   114 {
   115     NS_CStringSetData(aValue, "GetValue");
   116 }
   118 NS_IMETHODIMP
   119 nsSampleImpl::WriteValue(const char* aPrefix)
   120 {
   121     NS_PRECONDITION(aPrefix != nullptr, "null ptr");
   122     if (! aPrefix)
   123         return NS_ERROR_NULL_POINTER;
   125     printf("%s %s\n", aPrefix, mValue);
   127     // This next part illustrates the nsEmbedString:
   128     nsEmbedString foopy;
   129     foopy.Append(char16_t('f'));
   130     foopy.Append(char16_t('o'));
   131     foopy.Append(char16_t('o'));
   132     foopy.Append(char16_t('p'));
   133     foopy.Append(char16_t('y'));
   135     const char16_t* f = foopy.get();
   136     uint32_t l = foopy.Length();
   137     printf("%c%c%c%c%c %d\n", char(f[0]), char(f[1]), char(f[2]), char(f[3]), char(f[4]), l);
   139     nsEmbedCString foopy2;
   140     GetStringValue(foopy2);
   142     //foopy2.AppendLiteral("foopy");
   143     const char* f2 = foopy2.get();
   144     uint32_t l2 = foopy2.Length();
   146     printf("%s %d\n", f2, l2);
   148     return NS_OK;
   149 }

mercurial