line.Append(buf);
PRInt32			aLength; if (untruncated)	aLength = strlen(buf); else			aLength = sizeof(buf);  if (mUnicodeDecoder) { char			*aBuffer = buf; PRInt32			unicharBufLen = 0; mUnicodeDecoder->GetMaxLength(aBuffer, aLength, &unicharBufLen); PRUnichar		*unichars = new PRUnichar [ unicharBufLen+1 ]; do { PRInt32		srcLength = aLength; PRInt32		unicharLength = unicharBufLen; rv = mUnicodeDecoder->Convert(aBuffer, &srcLength, unichars, &unicharLength); unichars[unicharLength]=0;     for(PRInt32 i=0;i<unicharLength;i++) if(0x0000 == unichars[i])	unichars[i] = 0x0020;   line.Append(unichars, unicharLength);   if(NS_FAILED(rv)) { mUnicodeDecoder->Reset(); line.Append( (PRUnichar)0xFFFD); if(((PRUint32) (srcLength + 1)) > aLength) srcLength = aLength; else srcLength++; aBuffer += srcLength; aLength -= srcLength; } } while (NS_FAILED(rv) && (aLength > 0)); delete [] unichars; unichars = nsnull; } else { line.Append(buf, aLength); }
BookmarkParser::Parse(nsIRDFResource* aContainer, nsIRDFResource *nodeType){	// tokenize the input stream.	// XXX this needs to handle quotes, etc. it'd be nice to use the real parser for this...	nsRandomAccessInputStream	in(*mStream);	nsresult			rv;	nsCOMPtr<nsIRDFContainer> container;	rv = nsComponentManager::CreateInstance(kRDFContainerCID,						nsnull,						nsIRDFContainer::GetIID(),						getter_AddRefs(container));	if (NS_FAILED(rv)) return rv;	rv = container->Init(mDataSource, aContainer);	if (NS_FAILED(rv)) return rv;	nsCOMPtr<nsIRDFResource>	bookmarkNode = aContainer;	nsAutoString			line, description;	PRBool				inDescription = PR_FALSE;	while (NS_SUCCEEDED(rv) && !in.eof() && !in.failed())	{		line.Truncate();		while (PR_TRUE)		{			char	buf[256];			PRBool untruncated = in.readline(buf, sizeof(buf));			// in.readline() return PR_FALSE if there was buffer overflow,			// or there was a catastrophe. Check to see if we're here			// because of the latter...			NS_ASSERTION (! in.failed(), "error reading file");			if (in.failed()) return NS_ERROR_FAILURE;			// XXX Bug 5871. What charset conversion should we be			// applying here?			line.Append(buf);			if (untruncated)				break;		}		PRInt32	offset;				if (inDescription == PR_TRUE)		{			offset = line.FindChar('<');			if (offset < 0)			{				if (description.Length() > 0)				{					description += "\n";				}				description += line;				continue;			}			Unescape(description);			if (bookmarkNode)			{				nsCOMPtr<nsIRDFLiteral>	descLiteral;				if (NS_SUCCEEDED(rv = gRDF->GetLiteral(description.GetUnicode(), getter_AddRefs(descLiteral))))				{					rv = mDataSource->Assert(bookmarkNode, kNC_Description, descLiteral, PR_TRUE);				}			}			inDescription = PR_FALSE;			description.Truncate();		}		if ((offset = line.Find(kHREFEquals, PR_TRUE)) >= 0)		{			rv = ParseBookmark(line, container, nodeType, getter_AddRefs(bookmarkNode));		}		else if ((offset = line.Find(kOpenHeading, PR_TRUE)) >= 0 &&			 nsString::IsDigit(line.CharAt(offset + 2)))		{			// XXX Ignore <H1> so that bookmarks root _is_ <H1>			if (line.CharAt(offset + 2) != PRUnichar('1'))				rv = ParseBookmarkHeader(line, container, nodeType);		}		else if ((offset = line.Find(kSeparator, PR_TRUE)) >= 0)		{			rv = ParseBookmarkSeparator(line, container);		}		else if ((offset = line.Find(kCloseUL, PR_TRUE)) >= 0 ||			 (offset = line.Find(kCloseMenu, PR_TRUE)) >= 0 ||			 (offset = line.Find(kCloseDL, PR_TRUE)) >= 0)		{			return ParseHeaderEnd(line);		}		else if ((offset = line.Find(kOpenUL, PR_TRUE)) >= 0 ||			 (offset = line.Find(kOpenMenu, PR_TRUE)) >= 0 ||			 (offset = line.Find(kOpenDL, PR_TRUE)) >= 0)		{			rv = ParseHeaderBegin(line, container);		}		else if ((offset = line.Find(kOpenDD, PR_TRUE)) >= 0)		{			inDescription = PR_TRUE;			line.Cut(0, offset+sizeof(kOpenDD)-1);			description = line;		}		else		{			// XXX Discard the line?		}	}	return(rv);}