Wed, 31 Dec 2014 06:09:35 +0100
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 }