VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/io/nsStringStream.cpp@ 4837

Last change on this file since 4837 was 1, checked in by vboxsync, 54 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
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/
9 *
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
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * mcmullen@netscape.com (original author)
24 * warren@netscape.com
25 * alecf@netscape.com
26 * scc@mozilla.org
27 * david.gardiner@unisa.edu.au
28 * fur@netscape.com
29 * norris@netscape.com
30 * pinkerton@netscape.com
31 * davidm@netscape.com
32 * sfraser@netscape.com
33 * darin@netscape.com
34 * bzbarsky@mit.edu
35 *
36 * Alternatively, the contents of this file may be used under the terms of
37 * either of the GNU General Public License Version 2 or later (the "GPL"),
38 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
39 * in which case the provisions of the GPL or the LGPL are applicable instead
40 * of those above. If you wish to allow use of your version of this file only
41 * under the terms of either the GPL or the LGPL, and not to allow others to
42 * use your version of this file under the terms of the MPL, indicate your
43 * decision by deleting the provisions above and replace them with the notice
44 * and other provisions required by the GPL or the LGPL. If you do not delete
45 * the provisions above, a recipient may use your version of this file under
46 * the terms of any one of the MPL, the GPL or the LGPL.
47 *
48 * ***** END LICENSE BLOCK ***** */
49
50/**
51 * Based on original code from nsIStringStream.cpp
52 */
53
54#include "nsStringStream.h"
55
56#include "prerror.h"
57#include "plstr.h"
58#include "nsReadableUtils.h"
59#include "nsCRT.h"
60#include "nsISeekableStream.h"
61#include "nsInt64.h"
62
63#define NS_FILE_RESULT(x) ns_file_convert_result((PRInt32)x)
64#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
65
66static nsresult ns_file_convert_result(PRInt32 nativeErr)
67{
68 return nativeErr ?
69 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES,((nativeErr)&0xFFFF))
70 : NS_OK;
71}
72
73//-----------------------------------------------------------------------------
74// nsIStringInputStream implementation
75//-----------------------------------------------------------------------------
76
77class nsStringInputStream : public nsIStringInputStream
78 , public nsIRandomAccessStore
79
80{
81public:
82 nsStringInputStream()
83 : mOffset(0)
84 , mLastResult(NS_OK)
85 , mEOF(PR_FALSE)
86 , mOwned(PR_FALSE)
87 , mConstString(nsnull)
88 , mLength(0)
89 {}
90
91private:
92 ~nsStringInputStream()
93 {
94 if (mOwned)
95 nsMemory::Free((char*)mConstString);
96 }
97
98public:
99 NS_DECL_ISUPPORTS
100
101 NS_DECL_NSISTRINGINPUTSTREAM
102 NS_DECL_NSIINPUTSTREAM
103
104 // nsIRandomAccessStore interface
105 NS_IMETHOD GetAtEOF(PRBool* outAtEOF);
106 NS_IMETHOD SetAtEOF(PRBool inAtEOF);
107
108 NS_DECL_NSISEEKABLESTREAM
109
110protected:
111 PRInt32 LengthRemaining() const
112 {
113 return mLength - mOffset;
114 }
115
116 void Clear()
117 {
118 NS_ASSERTION(mConstString || !mOwned,
119 "Can't have mOwned set and have a null string!");
120 if (mOwned)
121 nsMemory::Free((char*)mConstString);
122
123 // We're about to get a new string; clear the members that
124 // would no longer have valid values.
125 mOffset = 0;
126 mLastResult = NS_OK;
127 mEOF = PR_FALSE;
128 }
129
130 PRInt32 mOffset;
131 nsresult mLastResult;
132 PRPackedBool mEOF;
133 PRPackedBool mOwned;
134 const char* mConstString;
135 PRInt32 mLength;
136};
137
138NS_IMPL_THREADSAFE_ISUPPORTS4(nsStringInputStream,
139 nsIStringInputStream,
140 nsIInputStream,
141 nsIRandomAccessStore,
142 nsISeekableStream)
143
144/////////
145// nsIStringInputStream implementation
146/////////
147NS_IMETHODIMP
148nsStringInputStream::SetData(const char *data, PRInt32 dataLen)
149{
150 if (dataLen < 0)
151 dataLen = strlen(data);
152
153 return AdoptData(nsCRT::strndup(data, dataLen), dataLen);
154}
155
156NS_IMETHODIMP
157nsStringInputStream::AdoptData(char *data, PRInt32 dataLen)
158{
159 NS_ENSURE_ARG_POINTER(data);
160
161 if (dataLen < 0)
162 dataLen = strlen(data);
163
164 Clear();
165
166 mConstString = (const char *) data;
167 mLength = dataLen;
168 mOwned = PR_TRUE;
169 return NS_OK;
170}
171
172NS_IMETHODIMP
173nsStringInputStream::ShareData(const char *data, PRInt32 dataLen)
174{
175 NS_ENSURE_ARG_POINTER(data);
176
177 if (dataLen < 0)
178 dataLen = strlen(data);
179
180 Clear();
181
182 mConstString = data;
183 mLength = dataLen;
184 mOwned = PR_FALSE;
185 return NS_OK;
186}
187
188/////////
189// nsIInputStream implementation
190/////////
191NS_IMETHODIMP nsStringInputStream::Close()
192{
193 return NS_OK;
194}
195
196NS_IMETHODIMP nsStringInputStream::Available(PRUint32 *aLength)
197{
198 NS_PRECONDITION(aLength != nsnull, "null ptr");
199 if (!aLength)
200 return NS_ERROR_NULL_POINTER;
201 *aLength = LengthRemaining();
202 return NS_OK;
203}
204
205NS_IMETHODIMP nsStringInputStream::Read(char* aBuf, PRUint32 aCount,
206 PRUint32 *aReadCount)
207{
208 NS_PRECONDITION(aBuf != nsnull, "null ptr");
209 if (!aBuf)
210 return NS_ERROR_NULL_POINTER;
211 NS_PRECONDITION(aReadCount != nsnull, "null ptr");
212 if (!aReadCount)
213 return NS_ERROR_NULL_POINTER;
214 if (NS_FAILED(mLastResult))
215 return mLastResult;
216
217 PRInt32 bytesRead;
218 PRInt32 maxCount = mLength - mOffset;
219 if ((PRInt32)aCount > maxCount)
220 bytesRead = maxCount;
221 else
222 bytesRead = aCount;
223
224 memcpy(aBuf, mConstString + mOffset, bytesRead);
225 mOffset += bytesRead;
226
227 *aReadCount = bytesRead;
228 if (bytesRead < (PRInt32)aCount)
229 SetAtEOF(PR_TRUE);
230 return NS_OK;
231}
232
233
234NS_IMETHODIMP
235nsStringInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure,
236 PRUint32 aCount, PRUint32 * result)
237{
238 nsresult rv;
239 PRInt32 maxCount = mLength - mOffset;
240 if (maxCount == 0) {
241 *result = 0;
242 return NS_OK;
243 }
244 if ((PRInt32)aCount > maxCount)
245 aCount = maxCount;
246 rv = writer(this, closure, mConstString + mOffset,
247 0, aCount, result);
248 if (NS_SUCCEEDED(rv))
249 mOffset += *result;
250 // errors returned from the writer end here!
251 return NS_OK;
252}
253
254NS_IMETHODIMP
255nsStringInputStream::IsNonBlocking(PRBool *aNonBlocking)
256{
257 *aNonBlocking = PR_TRUE;
258 return NS_OK;
259}
260
261
262/////////
263// nsISeekableStream implementation
264/////////
265NS_IMETHODIMP nsStringInputStream::Seek(PRInt32 whence, PRInt64 offset)
266{
267 mLastResult = NS_OK; // reset on a seek.
268 const nsInt64 maxUint32 = PR_UINT32_MAX;
269 nsInt64 offset64(offset);
270 PRInt32 offset32;
271 LL_L2I(offset32, offset);
272
273 NS_ASSERTION(maxUint32 > offset64, "string streams only support 32 bit offsets");
274 mEOF = PR_FALSE; // reset on a seek.
275 PRInt32 fileSize = LengthRemaining();
276 PRInt32 newPosition=-1;
277 switch (whence)
278 {
279 case NS_SEEK_CUR: newPosition = mOffset + offset32; break;
280 case NS_SEEK_SET: newPosition = offset32; break;
281 case NS_SEEK_END: newPosition = fileSize + offset32; break;
282 }
283 if (newPosition < 0)
284 {
285 newPosition = 0;
286 mLastResult = NS_FILE_RESULT(PR_FILE_SEEK_ERROR);
287 }
288 if (newPosition >= fileSize)
289 {
290 newPosition = fileSize;
291 mEOF = PR_TRUE;
292 }
293 mOffset = newPosition;
294 return NS_OK;
295}
296
297
298NS_IMETHODIMP nsStringInputStream::Tell(PRInt64* outWhere)
299{
300 *outWhere = mOffset;
301 return NS_OK;
302}
303
304NS_IMETHODIMP nsStringInputStream::SetEOF()
305{
306 NS_NOTYETIMPLEMENTED("nsStringInputStream::SetEOF");
307 return NS_ERROR_NOT_IMPLEMENTED;
308}
309
310/////////
311// nsIRandomAccessStore implementation
312/////////
313NS_IMETHODIMP nsStringInputStream::GetAtEOF(PRBool* outAtEOF)
314{
315 *outAtEOF = mEOF;
316 return NS_OK;
317}
318
319NS_IMETHODIMP nsStringInputStream::SetAtEOF(PRBool inAtEOF)
320{
321 mEOF = inAtEOF;
322 return NS_OK;
323}
324
325// Factory method to get an nsInputStream from an nsAString. Result will
326// implement nsIStringInputStream and nsIRandomAccessStore
327extern "C" NS_COM nsresult
328NS_NewStringInputStream(nsIInputStream** aStreamResult,
329 const nsAString& aStringToRead)
330{
331 NS_PRECONDITION(aStreamResult, "null out ptr");
332
333 char* data = ToNewCString(aStringToRead);
334 if (!data)
335 return NS_ERROR_OUT_OF_MEMORY;
336
337 nsStringInputStream* stream = new nsStringInputStream();
338 if (! stream) {
339 nsMemory::Free(data);
340 return NS_ERROR_OUT_OF_MEMORY;
341 }
342
343 NS_ADDREF(stream);
344
345 nsresult rv = stream->AdoptData(data, aStringToRead.Length());
346 if (NS_FAILED(rv)) {
347 nsMemory::Free(data);
348 NS_RELEASE(stream);
349 return rv;
350 }
351
352 *aStreamResult = stream;
353 return NS_OK;
354}
355
356// Factory method to get an nsInputStream from an nsACString. Result will
357// implement nsIStringInputStream and nsIRandomAccessStore
358extern "C" NS_COM nsresult
359NS_NewCStringInputStream(nsIInputStream** aStreamResult,
360 const nsACString& aStringToRead)
361{
362 NS_PRECONDITION(aStreamResult, "null out ptr");
363
364 char* data = ToNewCString(aStringToRead);
365 if (!data)
366 return NS_ERROR_OUT_OF_MEMORY;
367
368 nsStringInputStream* stream = new nsStringInputStream();
369 if (! stream) {
370 nsMemory::Free(data);
371 return NS_ERROR_OUT_OF_MEMORY;
372 }
373
374 NS_ADDREF(stream);
375
376 nsresult rv = stream->AdoptData(data, aStringToRead.Length());
377 if (NS_FAILED(rv)) {
378 nsMemory::Free(data);
379 NS_RELEASE(stream);
380 return rv;
381 }
382
383 *aStreamResult = stream;
384 return NS_OK;
385}
386
387// Factory method to get an nsInputStream from a C string. Result will
388// implement nsIStringInputStream and nsIRandomAccessStore
389extern "C" NS_COM nsresult
390NS_NewCharInputStream(nsIInputStream** aStreamResult,
391 const char* aStringToRead)
392{
393 NS_PRECONDITION(aStreamResult, "null out ptr");
394
395 nsStringInputStream* stream = new nsStringInputStream();
396 if (! stream)
397 return NS_ERROR_OUT_OF_MEMORY;
398
399 NS_ADDREF(stream);
400
401 nsresult rv = stream->ShareData(aStringToRead, -1);
402
403 if (NS_FAILED(rv)) {
404 NS_RELEASE(stream);
405 return rv;
406 }
407
408 *aStreamResult = stream;
409 return NS_OK;
410}
411
412// Factory method to get an nsInputStream from a byte array. Result will
413// implement nsIStringInputStream and nsIRandomAccessStore
414extern "C" NS_COM nsresult
415NS_NewByteInputStream(nsIInputStream** aStreamResult,
416 const char* aStringToRead,
417 PRInt32 aLength)
418{
419 NS_PRECONDITION(aStreamResult, "null out ptr");
420
421 nsStringInputStream* stream = new nsStringInputStream();
422 if (! stream)
423 return NS_ERROR_OUT_OF_MEMORY;
424
425 NS_ADDREF(stream);
426
427 nsresult rv = stream->ShareData(aStringToRead, aLength);
428
429 if (NS_FAILED(rv)) {
430 NS_RELEASE(stream);
431 return rv;
432 }
433
434 *aStreamResult = stream;
435 return NS_OK;
436}
437
438// factory method for constructing a nsStringInputStream object
439NS_METHOD
440nsStringInputStreamConstructor(nsISupports *outer, REFNSIID iid, void **result)
441{
442 *result = nsnull;
443
444 if (outer)
445 return NS_ERROR_NO_AGGREGATION;
446
447 nsStringInputStream *inst;
448 NS_NEWXPCOM(inst, nsStringInputStream);
449 if (!inst)
450 return NS_ERROR_OUT_OF_MEMORY;
451
452 NS_ADDREF(inst);
453 nsresult rv = inst->QueryInterface(iid, result);
454 NS_RELEASE(inst);
455
456 return rv;
457}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use