зеркало из https://github.com/mozilla/pjs.git
Fix RFC 822 quoting for LDAP autocompleted display names (bug 89198). Fix works by creating a new "formatter" interface and implementing an addressbook-specific version of it which uses the mailnews quoting code to fix it up. Also provides infrastructure for setting the LDAP autocomplete dropdown comment field, and fixes some error-handling issues in the compose window code for setting up LDAP autocompletion. r=leif@netscape.com (backend changes), srilatha@netscape.com (compose window changes); sr=bienvenu@netscape.com
This commit is contained in:
Родитель
dc55c2cbd2
Коммит
b509c90431
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Dan Mosedale <dmose@netscape.com> (Original Author)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsILDAPMessage.idl"
|
||||
|
||||
interface nsIAutoCompleteItem;
|
||||
|
||||
/**
|
||||
* An interface to allow different users of nsILDAPAutoCompleteSession to
|
||||
* format each nsILDAPMessage into an nsIAutoCompleteItem as it sees fit.
|
||||
*/
|
||||
[scriptable, uuid(cbec617c-22d2-4286-8308-0ef8bf57c0ce)]
|
||||
interface nsILDAPAutoCompFormatter : nsISupports {
|
||||
|
||||
/**
|
||||
* Returns an nsIAutoCompleteItem generated from the data in
|
||||
* the given nsILDAPMessage.
|
||||
*
|
||||
* @param aMessage message to be formatted
|
||||
* @return resulting nsIAutoCompleteItem
|
||||
*/
|
||||
nsIAutoCompleteItem format(in nsILDAPMessage aMessage);
|
||||
|
||||
/**
|
||||
* Gets a list of all the LDAP attributes that should be requested
|
||||
* from the LDAP server when a lookup is done. This avoids
|
||||
* wasting server time, bandwidth, and client time processing
|
||||
* unused attributes.
|
||||
*
|
||||
* Note that this is only required to be called by the
|
||||
* nsILDAPAutoCompleteSession implementation when the
|
||||
* nsILDAPAutoCompleteSession::formatter IDL attribute is set. .
|
||||
* So if for some reason, the LDAP attributes to be returned by
|
||||
* searches has to change (eg because the user changed a
|
||||
* preference), the nsILDAPAutoCompleteSession::formatter IDL
|
||||
* attribute should be re-set to the same object to force a new
|
||||
* getAttributes() call.
|
||||
*
|
||||
* @param aCount number of attributes in the array
|
||||
* @param aAttrs list of LDAP attributes to request
|
||||
*/
|
||||
void getAttributes(out unsigned long aCount,
|
||||
[retval, array, size_is(aCount)] out string aAttrs);
|
||||
};
|
|
@ -23,7 +23,10 @@
|
|||
|
||||
#include "nsIAutoCompleteSession.idl"
|
||||
|
||||
interface nsILDAPURL; // forward decl
|
||||
// forward decls
|
||||
//
|
||||
interface nsILDAPURL;
|
||||
interface nsILDAPAutoCompFormatter;
|
||||
|
||||
/**
|
||||
* Extends nsIAutoCompleteSession to have various LDAP-specific parameters.
|
||||
|
@ -50,32 +53,6 @@ interface nsILDAPAutoCompleteSession : nsIAutoCompleteSession {
|
|||
*/
|
||||
attribute wstring filterTemplate;
|
||||
|
||||
/**
|
||||
* A template string for formatting the autocompletion results.
|
||||
*
|
||||
* Required attributes are delimited by curly braces, and optional
|
||||
* attributes are determined by brackets. Backslash escapes any
|
||||
* character, including itself.
|
||||
*
|
||||
* If outputFormat is not set, or is set to the empty string,
|
||||
* the component implementing this interface should set the outputFormat
|
||||
* to a reasonable default.
|
||||
*
|
||||
* As an example, the "@mozilla.org/autocompleteSession;1?type=ldap"
|
||||
* implementation currently happens to use a default of "[cn] <{mail}>",
|
||||
* without the quotes. This will generate autocomplete items of the
|
||||
* form "John Doe <john.doe@foo.com>", or, if the cn is not found,
|
||||
* " <john.doe@foo.com>". This latter form is suboptimal, in that
|
||||
* the space and angle brackets are a bit ugly, but should work as an
|
||||
* email address. See bug 81961.
|
||||
*
|
||||
* @exception NS_ERROR_NULL_POINTER getter: NULL pointer passed in
|
||||
* @exception NS_ERROR_OUT_OF_MEMORY getter/setter: allocation error
|
||||
* @exception NS_ERROR_ILLEGAL_VALUE setter: invalid template specified
|
||||
* @exception NS_ERROR_UNEXPECTED setter: probably a bug
|
||||
*/
|
||||
attribute wstring outputFormat;
|
||||
|
||||
/**
|
||||
* At most this many nsIAutoCompleteItems will be returned. This
|
||||
* is useful for keeping bandwidth usage over slow-speed
|
||||
|
@ -112,4 +89,10 @@ interface nsILDAPAutoCompleteSession : nsIAutoCompleteSession {
|
|||
* @exception NS_ERROR_NULL_POINTER NULL pointer passed to getter
|
||||
*/
|
||||
attribute nsILDAPURL serverURL;
|
||||
|
||||
/**
|
||||
* Callback used to format an individual LDAP message into an
|
||||
* nsIAutoCompleteItem.
|
||||
*/
|
||||
attribute nsILDAPAutoCompFormatter formatter;
|
||||
};
|
||||
|
|
|
@ -117,19 +117,8 @@ nsLDAPAutoCompleteSession::OnStartLookup(const PRUnichar *searchString,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// if mOutputFormat is unset, set it to our default, using the
|
||||
// XPCOM setter so that the internal array will be built up
|
||||
//
|
||||
if (mOutputFormat.IsEmpty()) {
|
||||
rv = SetOutputFormat(NS_LITERAL_STRING("[cn] <{mail}>").get());
|
||||
if (NS_FAILED(rv)) {
|
||||
// if we got here, we've either hit a bug or run out of memory
|
||||
// in either case, we're screwed. In a debug build, something
|
||||
// will have already been logged. Time to bail out.
|
||||
FinishAutoCompleteLookup(nsIAutoCompleteStatus::failed);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(mFormatter, "nsLDAPAutoCompleteSession::OnStartLookup(): "
|
||||
"formatter attribute has not been set");
|
||||
|
||||
// see if this is a narrow search that we could potentially do locally
|
||||
//
|
||||
|
@ -461,8 +450,6 @@ nsLDAPAutoCompleteSession::OnLDAPBind(nsILDAPMessage *aMessage)
|
|||
nsresult
|
||||
nsLDAPAutoCompleteSession::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
|
||||
{
|
||||
nsresult rv; // temporary for return vals
|
||||
|
||||
PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG,
|
||||
("nsLDAPAutoCompleteSession::OnLDAPSearchEntry entered\n"));
|
||||
|
||||
|
@ -473,43 +460,22 @@ nsLDAPAutoCompleteSession::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
|
|||
"nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
|
||||
"mResultsArrayItems is uninitialized");
|
||||
|
||||
nsAutoString value;
|
||||
rv = ProcessOutputFormat(mOutputFormat, aMessage, &value, 0);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Something went wrong lower down the stack; a message should have
|
||||
// already been logged there. Return an error (which ultimately gets
|
||||
// ignored, since this is being called through an async proxy). But
|
||||
// the important thing is that we're bailing out here rather than
|
||||
// trying to generate a bogus nsIAutoCompleteItem
|
||||
//
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Errors in this method return an error (which ultimately gets
|
||||
// ignored, since this is being called through an async proxy).
|
||||
// But the important thing is that we're bailing out here rather
|
||||
// than trying to generate a bogus nsIAutoCompleteItem. Also note
|
||||
// that FinishAutoCompleteLookup is _NOT_ being called here, because
|
||||
// this error may just have to do with this particular item.
|
||||
|
||||
// create an nsIAutoCompleteItem to hold the returned value
|
||||
// generate an autocomplete item from this message by calling the
|
||||
// formatter
|
||||
//
|
||||
nsCOMPtr<nsIAutoCompleteItem> item = do_CreateInstance(
|
||||
NS_AUTOCOMPLETEITEM_CONTRACTID, &rv);
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteItem> item;
|
||||
nsresult rv = mFormatter->Format(aMessage, getter_AddRefs(item));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchEntry couldn't"
|
||||
" create " NS_AUTOCOMPLETEITEM_CONTRACTID "\n");
|
||||
|
||||
// don't call FinishAutoCompleteLookup(), as this could conceivably
|
||||
// be an anomaly, and perhaps the next message will be ok. if this
|
||||
// really was a problem, this search should eventually get
|
||||
// reaped by a timeout (once that code gets implemented).
|
||||
//
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// just use the first value for the email attribute; subsequent values
|
||||
// are ignored. XXXdmose should do better than this; bug 76595.
|
||||
//
|
||||
rv = item->SetValue(value);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
|
||||
"item->SetValue failed");
|
||||
|
||||
PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG,
|
||||
("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
|
||||
"mFormatter->Format() failed"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -527,267 +493,6 @@ nsLDAPAutoCompleteSession::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// parse and process the outputFormat attribute. If aStringArray is
|
||||
// non-NULL, return a list of the attributes from mOutputFormat in
|
||||
// aStringArray. Otherwise, generate an autocomplete value from the
|
||||
// information in aMessage and append it to aValue. Any errors
|
||||
// (including failure to find a required attribute while building up aValue)
|
||||
// return an NS_ERROR_* up the stack so that the caller doesn't try and
|
||||
// generate an nsIAutoCompleteItem from this.
|
||||
//
|
||||
nsresult
|
||||
nsLDAPAutoCompleteSession::ProcessOutputFormat(
|
||||
nsAReadableString &aOutputFormat, nsILDAPMessage *aMessage,
|
||||
nsAWritableString *aValue, nsCStringArray *aAttrs)
|
||||
{
|
||||
nsresult rv; // temp for return values
|
||||
|
||||
// get some iterators to parse aOutputFormat
|
||||
//
|
||||
nsReadingIterator<PRUnichar> iter, iterEnd;
|
||||
aOutputFormat.BeginReading(iter);
|
||||
aOutputFormat.EndReading(iterEnd);
|
||||
|
||||
// get the console service for error logging
|
||||
//
|
||||
nsCOMPtr<nsIConsoleService> consoleSvc =
|
||||
do_GetService("@mozilla.org/consoleservice;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsLDAPAutoCompleteSession::ProcessOutputFormat(): "
|
||||
"couldn't get console service");
|
||||
}
|
||||
|
||||
PRBool attrRequired = PR_FALSE; // is this attr required or optional?
|
||||
nsCAutoString attrName; // current attr to get
|
||||
|
||||
// parse until we hit the end of the string
|
||||
//
|
||||
while (iter != iterEnd) {
|
||||
|
||||
switch (*iter) { // process the next char
|
||||
|
||||
case PRUnichar('{'):
|
||||
|
||||
attrRequired = PR_TRUE; // this attribute is required
|
||||
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
case PRUnichar('['):
|
||||
|
||||
rv = ParseAttrName(iter, iterEnd, attrRequired, consoleSvc,
|
||||
attrName);
|
||||
if ( NS_FAILED(rv) ) {
|
||||
|
||||
// something unrecoverable happened; stop parsing and
|
||||
// propagate the error up the stack
|
||||
//
|
||||
return rv;
|
||||
}
|
||||
|
||||
// if we're building an array
|
||||
if ( aAttrs ) {
|
||||
|
||||
// and it doesn't already contain this string
|
||||
if (aAttrs->IndexOfIgnoreCase(attrName) == -1) {
|
||||
|
||||
// add it
|
||||
if (!aAttrs->AppendCString(attrName)) {
|
||||
|
||||
// current AppendCString always returns PR_TRUE;
|
||||
// if we hit this error, something has changed in
|
||||
// that code
|
||||
//
|
||||
NS_ERROR(
|
||||
"nsLDAPAutoCompleteSession::ProcessOutputFormat():"
|
||||
" aAttrs->AppendCString(attrName) failed");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// otherwise, append the first value of this attr to aValue
|
||||
|
||||
rv = AppendFirstAttrValue(attrName, aMessage, attrRequired,
|
||||
*aValue);
|
||||
if ( NS_FAILED(rv) ) {
|
||||
|
||||
// something unrecoverable happened; stop parsing and
|
||||
// propagate the error up the stack
|
||||
//
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
attrName.Truncate(); // clear out for next pass
|
||||
attrRequired = PR_FALSE; // reset to the default for the next pass
|
||||
|
||||
break;
|
||||
|
||||
case PRUnichar('\\'):
|
||||
|
||||
// advance the iterator and be sure we haven't run off the end
|
||||
//
|
||||
++iter;
|
||||
if (iter == iterEnd) {
|
||||
|
||||
// abort; missing escaped char
|
||||
//
|
||||
if (consoleSvc) {
|
||||
consoleSvc->LogStringMessage(
|
||||
NS_LITERAL_STRING(
|
||||
"LDAP autocomplete session: error parsing outputFormat: premature end of string after \\ escape").get());
|
||||
|
||||
NS_ERROR("LDAP autocomplete session: error parsing "
|
||||
"outputFormat: premature end of string after \\ "
|
||||
"escape");
|
||||
}
|
||||
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
default:
|
||||
|
||||
// if we're not just building an array of attribute names, append
|
||||
// this character to the item we're generating.
|
||||
//
|
||||
if (!aAttrs) {
|
||||
|
||||
// this character gets treated as a literal
|
||||
//
|
||||
(*aValue).Append(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
++iter; // advance the iterator
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLDAPAutoCompleteSession::ParseAttrName(
|
||||
nsReadingIterator<PRUnichar> &aIter, // iterators for mOutputString
|
||||
nsReadingIterator<PRUnichar> &aIterEnd,
|
||||
PRBool aAttrRequired, // required? or just optional?
|
||||
nsCOMPtr<nsIConsoleService> &aConsoleSvc, // no need to reacquire this
|
||||
nsAWritableCString &aAttrName) // attribute token
|
||||
{
|
||||
// reset attrname, and move past the opening brace
|
||||
//
|
||||
++aIter;
|
||||
|
||||
// get the rest of the attribute name
|
||||
//
|
||||
do {
|
||||
|
||||
// be sure we haven't run off the end
|
||||
//
|
||||
if (aIter == aIterEnd) {
|
||||
|
||||
// abort; missing closing delimiter
|
||||
//
|
||||
if (aConsoleSvc) {
|
||||
aConsoleSvc->LogStringMessage(
|
||||
NS_LITERAL_STRING(
|
||||
"LDAP autocomplete session: error parsing outputFormat: missing } or ]").get());
|
||||
|
||||
NS_ERROR("LDAP autocomplete session: error parsing "
|
||||
"outputFormat: missing } or ]");
|
||||
}
|
||||
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
} else if ( (aAttrRequired && *aIter == PRUnichar('}')) ||
|
||||
(!aAttrRequired && *aIter == PRUnichar(']')) ) {
|
||||
|
||||
// done with this attribute
|
||||
//
|
||||
break;
|
||||
|
||||
} else {
|
||||
|
||||
// this must be part of the attribute name
|
||||
//
|
||||
aAttrName.Append(char(*aIter));
|
||||
}
|
||||
|
||||
++aIter;
|
||||
|
||||
} while (1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLDAPAutoCompleteSession::AppendFirstAttrValue(
|
||||
nsAReadableCString &aAttrName, // attr to get
|
||||
nsILDAPMessage *aMessage, // msg to get values from
|
||||
PRBool aAttrRequired, // is this a required value?
|
||||
nsAWritableString &aValue)
|
||||
{
|
||||
// get the attribute values for the field which will be used
|
||||
// to fill in nsIAutoCompleteItem::value
|
||||
//
|
||||
PRUint32 numVals;
|
||||
PRUnichar **values;
|
||||
|
||||
nsresult rv;
|
||||
rv = aMessage->GetValues(PromiseFlatCString(aAttrName).get(), &numVals,
|
||||
&values);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
||||
switch (rv) {
|
||||
case NS_ERROR_LDAP_DECODING_ERROR:
|
||||
// this may not be an error, per se; it could just be that the
|
||||
// requested attribute does not exist in this particular message,
|
||||
// either because we didn't request it with the search operation,
|
||||
// or because it doesn't exist on the server.
|
||||
//
|
||||
PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_WARNING,
|
||||
("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
|
||||
"couldn't decode '%s' attribute",
|
||||
PromiseFlatCString(aAttrName).get()));
|
||||
break;
|
||||
|
||||
case NS_ERROR_OUT_OF_MEMORY:
|
||||
case NS_ERROR_UNEXPECTED:
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
|
||||
"unexpected return code from aMessage->getValues()");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// if this was a required attribute, don't append anything to aValue
|
||||
// and return the error code
|
||||
//
|
||||
if (aAttrRequired) {
|
||||
return rv;
|
||||
} else {
|
||||
// otherwise forget about this attribute, but return NS_OK, which
|
||||
// will cause our caller to continue processing outputFormat in
|
||||
// order to generate an nsIAutoCompleteItem.
|
||||
//
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// append the value to our string; then free the array of results
|
||||
//
|
||||
aValue.Append(values[0]);
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numVals, values);
|
||||
|
||||
// if this attribute wasn't required, we fall through to here, and return
|
||||
// ok
|
||||
//
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLDAPAutoCompleteSession::OnLDAPSearchResult(nsILDAPMessage *aMessage)
|
||||
{
|
||||
|
@ -1315,74 +1020,6 @@ nsLDAPAutoCompleteSession::SetFilterTemplate(const PRUnichar * aFilterTemplate)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// attribute wstring outputFormat;
|
||||
NS_IMETHODIMP
|
||||
nsLDAPAutoCompleteSession::GetOutputFormat(PRUnichar * *aOutputFormat)
|
||||
{
|
||||
if (!aOutputFormat) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aOutputFormat = mOutputFormat.ToNewUnicode();
|
||||
if (!*aOutputFormat) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsLDAPAutoCompleteSession::SetOutputFormat(const PRUnichar * aOutputFormat)
|
||||
{
|
||||
// set up an array of search attributes to be used in any calls to
|
||||
// nsLDAPOperation::SearchExt(). This also allows any errors in
|
||||
// aOutputFormat to be caught sooner, rather than later.
|
||||
//
|
||||
nsCStringArray searchAttrs;
|
||||
nsresult rv = ProcessOutputFormat(nsDependentString(aOutputFormat), 0, 0,
|
||||
&searchAttrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsLDAPAutoCompleteSession::SetOutputFormat(): "
|
||||
"ProcessOutputFormat() failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// build up the raw XPCOM array that we'll be passing to
|
||||
// SearchExt()
|
||||
//
|
||||
PRUint32 count = searchAttrs.Count(); // size of XPCOM array we'll need
|
||||
PRUint32 rawSearchAttrsSize = 0; // grown as XPCOM array is built
|
||||
char **rawSearchAttrs =
|
||||
NS_STATIC_CAST(char **, nsMemory::Alloc(count * sizeof(char *)));
|
||||
if (!rawSearchAttrs) {
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::SetOutputFormat: out of memory");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Loop through the string array, and build up the C-array.
|
||||
//
|
||||
while (rawSearchAttrsSize < count) {
|
||||
if (!(rawSearchAttrs[rawSearchAttrsSize] =
|
||||
(searchAttrs.CStringAt(rawSearchAttrsSize))->ToNewCString())) {
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(rawSearchAttrsSize,
|
||||
rawSearchAttrs);
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::SetOutputFormat: out of "
|
||||
"memory");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rawSearchAttrsSize++;
|
||||
}
|
||||
|
||||
// ok, we've succeed in building up the new array. deallocate the
|
||||
// old array as necessary, then assign in the new member vars.
|
||||
//
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mSearchAttrsSize, mSearchAttrs);
|
||||
|
||||
mSearchAttrsSize = rawSearchAttrsSize;
|
||||
mSearchAttrs = rawSearchAttrs;
|
||||
mOutputFormat = aOutputFormat;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// attribute long maxHits;
|
||||
NS_IMETHODIMP
|
||||
|
@ -1414,8 +1051,7 @@ nsLDAPAutoCompleteSession::GetServerURL(nsILDAPURL * *aServerURL)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aServerURL = mServerURL;
|
||||
NS_IF_ADDREF(*aServerURL);
|
||||
NS_IF_ADDREF(*aServerURL = mServerURL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1511,6 +1147,41 @@ nsLDAPAutoCompleteSession::IsMessageCurrent(nsILDAPMessage *aMessage,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// attribute nsILDAPAutoCompFormatter formatter
|
||||
NS_IMETHODIMP
|
||||
nsLDAPAutoCompleteSession::GetFormatter(nsILDAPAutoCompFormatter* *aFormatter)
|
||||
{
|
||||
if (! aFormatter ) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aFormatter = mFormatter);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsLDAPAutoCompleteSession::SetFormatter(nsILDAPAutoCompFormatter* aFormatter)
|
||||
{
|
||||
if (! aFormatter ) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mState == UNBOUND || mState == BOUND,
|
||||
"nsLDAPAutoCompleteSession::SetFormatter was called when "
|
||||
"mState was set to something other than BOUND or UNBOUND");
|
||||
|
||||
mFormatter = aFormatter;
|
||||
|
||||
// get and cache the attributes that will be used to do lookups
|
||||
//
|
||||
nsresult rv = mFormatter->GetAttributes(&mSearchAttrsSize, &mSearchAttrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPAutoCompleteSession::SetFormatter(): "
|
||||
" mFormatter->GetAttributes failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "nsILDAPConnection.h"
|
||||
#include "nsILDAPMessageListener.h"
|
||||
#include "nsILDAPAutoCompleteSession.h"
|
||||
#include "nsILDAPAutoCompFormatter.h"
|
||||
#include "nsILDAPURL.h"
|
||||
#include "nsString.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
@ -60,13 +61,16 @@ class nsLDAPAutoCompleteSession : public nsILDAPMessageListener,
|
|||
nsCOMPtr<nsISupportsArray> mResultsArray; // cached, to avoid re-gets
|
||||
nsString mSearchString; // autocomplete this string
|
||||
nsString mFilterTemplate; // search filter template
|
||||
nsString mOutputFormat; // how to format output
|
||||
nsCOMPtr<nsILDAPURL> mServerURL; // URL for the directory to search
|
||||
PRInt32 mMaxHits; // return at most this many entries
|
||||
PRUint32 mMinStringLength; // strings < this size are ignored
|
||||
char **mSearchAttrs; // outputFormat search attrs for SearchExt call
|
||||
PRUint32 mSearchAttrsSize; // size of above array
|
||||
|
||||
// used to format the ldap message into an nsIAutoCompleteItem
|
||||
//
|
||||
nsCOMPtr<nsILDAPAutoCompFormatter> mFormatter;
|
||||
|
||||
// stopgap until nsLDAPService works
|
||||
nsresult InitConnection();
|
||||
|
||||
|
@ -76,25 +80,6 @@ class nsLDAPAutoCompleteSession : public nsILDAPMessageListener,
|
|||
// add to the results set
|
||||
nsresult OnLDAPSearchEntry(nsILDAPMessage *aMessage);
|
||||
|
||||
// parse and process outputFormat
|
||||
nsresult ProcessOutputFormat(nsAReadableString & aOutputFormat,
|
||||
nsILDAPMessage *aMessage,
|
||||
nsAWritableString *aValue,
|
||||
nsCStringArray *aAttrs);
|
||||
|
||||
// process a single attribute while parsing outputFormat
|
||||
nsresult ParseAttrName(nsReadingIterator<PRUnichar> & aIter,
|
||||
nsReadingIterator<PRUnichar> & aIterEnd,
|
||||
PRBool aAttrRequired,
|
||||
nsCOMPtr<nsIConsoleService> & aConsoleSvc,
|
||||
nsAWritableCString & aAttrName);
|
||||
|
||||
// append the first value associated with aAttrName in aMessage to aValue
|
||||
nsresult AppendFirstAttrValue(nsAReadableCString &aAttrName,
|
||||
nsILDAPMessage *aMessage,
|
||||
PRBool aAttrRequired,
|
||||
nsAWritableString &aValue);
|
||||
|
||||
// all done; call OnAutoComplete
|
||||
nsresult OnLDAPSearchResult(nsILDAPMessage *aMessage);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче