1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Jeff Walden <jwalden+code@mit.edu>.
19 * Portions created by the Initial Developer are Copyright (C) 2007
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "TestHarness.h"
41 #include "nsIMemory.h"
43 /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
44 nsresult
TP_NewPipe2(nsIAsyncInputStream
** input
,
45 nsIAsyncOutputStream
** output
,
46 PRBool nonBlockingInput
,
47 PRBool nonBlockingOutput
,
49 PRUint32 segmentCount
,
50 nsIMemory
* segmentAlloc
)
52 nsCOMPtr
<nsIPipe
> pipe
= do_CreateInstance("@mozilla.org/pipe;1");
54 return NS_ERROR_OUT_OF_MEMORY
;
56 nsresult rv
= pipe
->Init(nonBlockingInput
,
65 pipe
->GetInputStream(input
);
66 pipe
->GetOutputStream(output
);
71 * Allocator can allocate exactly count * size bytes, stored at mMemory;
72 * immediately after the end of this is a byte-map of 0/1 values indicating
73 * which <size>-byte locations in mMemory are empty and which are filled.
74 * Pretty stupid, but enough to test bug 394692.
76 class BackwardsAllocator
: public nsIMemory
90 nsresult
Init(PRUint32 count
, size_t size
);
96 PRUint32
previous(PRUint32 i
)
110 NS_IMPL_ISUPPORTS1(BackwardsAllocator
, nsIMemory
)
112 nsresult
BackwardsAllocator::Init(PRUint32 count
, size_t size
)
116 fail("allocator already initialized!");
117 return NS_ERROR_ALREADY_INITIALIZED
;
120 mMemory
= new PRUint8
[count
* size
+ count
];
123 fail("failed to allocate mMemory!");
124 return NS_ERROR_OUT_OF_MEMORY
;
126 memset(mMemory
, 0, count
* size
+ count
);
135 NS_IMETHODIMP_(void*) BackwardsAllocator::Alloc(size_t size
)
139 NS_ERROR("umm, why would this be reached for this test?");
143 PRUint32 index
= mIndex
;
145 while ((index
= previous(index
)) != mIndex
)
147 if (mMemory
[mSize
* mCount
+ index
] == 1)
149 mMemory
[mSize
* mCount
+ index
] = 1;
151 return &mMemory
[mSize
* index
];
154 NS_ERROR("shouldn't reach here in this test");
158 NS_IMETHODIMP_(void*) BackwardsAllocator::Realloc(void* ptr
, size_t newSize
)
160 NS_ERROR("shouldn't reach here in this test");
164 NS_IMETHODIMP_(void) BackwardsAllocator::Free(void* ptr
)
166 PRUint8
* p
= static_cast<PRUint8
*>(ptr
);
168 mMemory
[mCount
* mSize
+ (p
- mMemory
) / mSize
] = 0;
171 NS_IMETHODIMP
BackwardsAllocator::HeapMinimize(PRBool immediate
)
176 NS_IMETHODIMP
BackwardsAllocator::IsLowMemory(PRBool
* retval
)
183 nsresult
TestBackwardsAllocator()
185 const PRUint32 SEGMENT_COUNT
= 10;
186 const PRUint32 SEGMENT_SIZE
= 10;
188 nsRefPtr
<BackwardsAllocator
> allocator
= new BackwardsAllocator();
191 fail("Allocation of BackwardsAllocator failed!");
192 return NS_ERROR_OUT_OF_MEMORY
;
194 nsresult rv
= allocator
->Init(SEGMENT_COUNT
, SEGMENT_SIZE
);
198 nsCOMPtr
<nsIAsyncInputStream
> input
;
199 nsCOMPtr
<nsIAsyncOutputStream
> output
;
200 rv
= TP_NewPipe2(getter_AddRefs(input
),
201 getter_AddRefs(output
),
204 SEGMENT_SIZE
, SEGMENT_COUNT
, allocator
);
207 fail("TP_NewPipe2 failed: %x", rv
);
211 const PRUint32 BUFFER_LENGTH
= 100;
212 const char written
[] =
222 "9123456789"; // not just a memset, to ensure the allocator works correctly
223 if (sizeof(written
) < BUFFER_LENGTH
)
225 fail("test error with string size");
226 return NS_ERROR_FAILURE
;
230 rv
= output
->Write(written
, BUFFER_LENGTH
, &writeCount
);
231 if (NS_FAILED(rv
) || writeCount
!= BUFFER_LENGTH
)
233 fail("writing %d bytes (wrote %d bytes) to output failed: %x",
234 BUFFER_LENGTH
, writeCount
, rv
);
238 char read
[BUFFER_LENGTH
];
240 rv
= input
->Read(read
, BUFFER_LENGTH
, &readCount
);
241 if (NS_FAILED(rv
) || readCount
!= BUFFER_LENGTH
)
243 fail("reading %d bytes (got %d bytes) from input failed: %x",
244 BUFFER_LENGTH
, readCount
, rv
);
248 if (0 != memcmp(written
, read
, BUFFER_LENGTH
))
250 fail("didn't read the written data correctly!");
251 return NS_ERROR_FAILURE
;
254 passed("TestBackwardsAllocator");
258 int main(int argc
, char** argv
)
260 ScopedXPCOM
xpcom("nsPipe");
266 if (NS_FAILED(TestBackwardsAllocator()))