Dmitriy,

This new external string API is meant to make nsIStringService unnecessary. It actually provides a very similar API. For example, I could implement the methods you propose using this new API.


Dmitriy B. wrote:


I am using nsIStringServive as a factory of nsAString objects.



nsIStringService was removed from the source tree not long ago. It was never made an official Gecko API. I hope its removal doesn't complicate things for you.



Would be great if this service become a part of String API.

NS_IMETHOD NS_CreateAString(const PRUnichar *aString, PRInt32 aLength,
nsAString * *_retval)
NS_IMETHOD NS_CreateACString(const char *aString, PRInt32 aLength,
nsACString * *_retval);
NS_IMETHOD NS_DeleteAString(nsAString* str);
NS_IMETHOD NS_DeleteACString(nsACString* str);




Here's how these methods could be implemented:


NS_CreateAString(const PRUnichar *aString, PRInt32 aLength, nsAString **_retval)
{
nsStringContainer *sc = new nsStringContainer;
NS_StringContainerInit(*sc);
NS_StringSetData(*sc, aString, aLength);
*_retval = sc;
}


NS_DeleteAString(nsAString *str)
{
 nsStringContainer *sc = (nsStringContainer *) str;
 NS_StringContainerFinish(*sc);
 delete sc;
}

NOTE: I don't think these methods are ideal. Let me show you how I would write SetBlah using the new external string API.


NS_METHOD SetBlah(const nsAString &aBlah);
   void MyCode()
   {
     nsAString* sc;
     if (NS_CreateAString(sc, '', 0))
     {
     const PRUnichar kData[] = {'x','y','z','\0'};
      NS_StringSetData(*sc, kData, sizeof(kData)-1);
       SetBlah(*sc);
       NS_DeleteString(sc);
     }
   }




NS_METHOD SetBlah(const nsAString &aBlah);


void MyCode()
{
 nsStringContainer sc;
 NS_StringContainerInit(sc);

 const PRUnichar kData[] = {'x','y','z','\0'};
 NS_StringSetData(sc, kData, sizeof(kData)-1);

SetBlah(sc);

 NS_StringContainerFinish(sc);
}

But an even easier solution that is exactly equivalent would be to use nsEmbedString, like this:

void MyCode()
{
 const PRUnichar kData[] = {'x','y','z','\0'};

nsEmbedString str(kData, sizeof(kData)-1);

 SetBlah(str);
}

Notice that you don't have to worry about calling NS_StringContainerFinish, and the resulting code is much simpler.

-Darin


PS> Sorry for my English.

"Darin Fisher" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]


Here you go:

( I've also attached the header files: nsStringAPI.h and


nsEmbedString.h )


-----------------------------
New External String API Notes
-----------------------------

The methods are:

 NS_C?StringContainerInit
 NS_C?StringContainerFinish
 NS_C?StringGetData
 NS_C?StringSetData
 NS_C?StringSetDataRange
 NS_C?StringCopy

Here's an overview of these methods (showing the wide versions only):

NS_StringContainerInit(nsStringContainer& aString)

Given a reference to a nsStringContainer struct, this function
initializes the struct for use as a nsAString to be used with XPCOM
methods. This acts like a constructor for |aString|. This method
provides external code with the ability to create a string object.


The


nsStringContainer struct can be allocated in any way the caller sees
fit. (It turns out that nsStringContainer is large enough to hold a
nsString, and NS_StringContainerInit simply calls the C++ placement


new


   operator to construct a nsString into the given nsStringContainer.)
   nsStringContainer can be passed to any function expecting a nsAString.

NS_StringContainerFinish(nsStringContainer& aString)

   Given a reference to a nsStringContainer struct, this function
   finalizes the struct.  This acts like a destructor for |aString|.
   This method does not free the |aString| reference, it only frees
   any data pointers stored in the |aString| members.

 PRUint32
 NS_StringGetData(const nsAString& aString,
                  const PRUnichar** aData,
                  PRBool *aIsTerminated)

Given a reference to a nsAString, this function returns the length of
the string buffer, a pointer to the string buffer, and optionally a
boolean indicating whether or not the string buffer is


null-terminated.


This function can be used to access the data of any nsAString.

 NS_StringSetData(nsAString& aString,
                  const PRUnichar* aData,
                  PRUint32 aDataLength);

   Given a reference to a nsAString, this functions sets the contents of
   the internal string buffer to a copy of |aData|.

 NS_StringSetDataRange(nsAString& aString,
                       PRUint32 aCutOffset,
                       PRUint32 aCutLength,
                       const PRUnichar* aData,
                       PRUint32 aDataLength)

   Given a reference to a nsAString, this functions sets a range of
   characters in the internal string buffer to the given values.  This
   function allows the caller to append, insert, or replace characters in
   the nsAString.  There are inline wrapper functions that simplify these
   tasks.

NS_StringCopy(nsAString& aDest, const nsAString& aSrc)

   Given references to two nsAString objects, this function copies the
   value of |aSrc| to |aDest|.  This function exists to take advantage of
   the copy-on-write feature of the new string classes.



-Darin


Dmitriy B. wrote:




Hello.
In my opinion that is realy cool to have StringAPI to use in embeded
application.
I would like to see this API. Is it available already?
What happen with nsIStringService? Does it has any changes?

Best regards, Dmitriy

PS> Sorry for my English.

"Darin Fisher" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]




-------------------------------
UPCOMING MOZILLA STRING CHANGES
-------------------------------


The Mozilla string code will be undergoing extensive revision following the release of Mozilla 1.7 alpha. The changes will be mostly transparent, having very little affect on the string API. This change will be made first thing during the 1.7 beta cycle.

The work is being tracked here:
http://bugzilla.mozilla.org/show_bug.cgi?id=231995


The major API-level changes include:


 (1) nsAC?String will no longer be able to represent multi-fragment
     strings.  This allows all implementations of nsAC?String to be
     unified, resulting in a significant reduction of code.

 (2) nsReadingIterator and nsWritingIterator will be limited to
     iterating over a contiguous buffer.  Previously, operator++ was
     forced to "normalize" the iterator forward to the next fragment.
     This added additional code to every consumer of iterators that
     was almost never needed since multi-fragment strings are very
     uncommon.

 (3) nsA?String methods are now all non-virtual.  This is possible
     since there is now only one implementation of nsAC?String.  This
     helps reduce code at the call sites and improves performance.
     ABI compatibility with the existing vtable is maintained (more
     on this later).  It is important to note that any external
     components that use multi-fragment strings will be broken, but
     passing multi-fragment strings in external components was
     forbidden anyway (although the prohibition was poorly
     documented) and none of our implementations of multi-fragment
     strings were ever frozen for component developers to use outside
     of the Mozilla codebase.

 (4) A simplified string API is introduced for embedders and external
     component developers.  nsAC?String's methods are now meant to be
     used only within the Mozilla code base.  The nsEmbedC?String
     class is now implemented in terms of the simplified string API.

(5) The following string classes have been eliminated:

nsSharableC?String

       nsC?String will now allocate a sharable buffer by default.  It
       implements thread-safe reference counting, enabling copy-on-
       write semantics for most strings.  Since very little code
       referenced nsSharableC?String, this class name has been
       eliminated.

nsDependentSingleFragmentC?Substring

       This is now equivalent to nsDependentC?Substring.  Since very
       little code referenced nsDependentSingleFragmentC?Substring,
       this class name has been eliminated.

nsDependentC?Concatenation

       Since nsA?CString can no longer represent a multi-fragment
       string, nsDependentC?Concatenation could no longer inherit
       from nsAC?String.  Therefore, this class no longer exists.
       However, efficient string concatenation is still implemented
       using a very similar mechanism.  More on this later.

(6) nsStringFwd.h now forward declares all string classes.

 (7) nsC?Substring has been added to the string hierarchy.  It will
     be the core string class from which all other strings inherit.
     It behaves much like the old nsSingleFragmentA?CString, except
     that it does not reference the nsAC?String vtable to satisfy any
     of its methods.  Many of the "getter"-functions are inlined for
     performance.


The revised string hierarchy is depicted below:


             nsAC?String
                  |
                  |
                  |
            nsC?Substring
                  |
                  |-------- nsDependentC?Substring
                  |
              nsC?String
                  |
                  |------------.----------.----------.
                  |            |          |          |
          nsDepedentC?String   |          |          |
                               |          |          |
                         nsC?AutoString   |          |
                                          |          |
                                   nsXPIDLC?String   |
                                                     |
                                           nsPromiseFlatC?String


Class overview:


nsAC?String

   This class is designed to be subclassed.  It is never directly
   instantiated.  This class exists only to provide backwards
   compatibility with the former string class API.  It is essentially
   equivalent to nsC?Substring.  However, unlike nsC?Substring,
   nsAC?String might be implemented by an external XPCOM component or
   embedding application that has not yet migrated to the new
   (simpler) embedding string API provided by XPCOM.

nsC?Substring

   This class is designed to be subclassed.  It is never directly
   instantiated.  It represents a string fragment that may or may not
   be null-terminated.  It has methods to access and manipulate the
   string buffer.  It has all of the code to manage the various
   different buffer allocation schemes used by the string classes.
   In many ways, the subclasses of nsC?Substring simply provide
   specialized constructors that select the corresponding memory
   allocation scheme.  If nsC?Substring needs to re-allocate the
   buffer, it will allocate a null-terminated, sharable buffer.

nsC?String

   This class is designed to be instantiated directly.  It is the
   main string class.  It provides a heap allocated string buffer.
   It also provides compatibility methods with the "obsolete" string
   API that used to live in xpcom/string/obsolete (i.e., the "Rick
   G." string API).  It always allocates a sharable buffer.

nsDependentC?String

   This class is designed to be instantiated directly.  It provides a
   mechanism to construct a nsC?String that simply stores a raw
   pointer to an externally allocated buffer.  This class depends on
   the user of the class to ensure that the buffer remains valid for
   the lifetime of the nsDependentC?String.  This class can only wrap
   a null-terminated buffer.

nsAutoC?String

   This class is designed to be instantiated directly.  It provides a
   mechanism to construct a nsC?String that optionally uses a fixed-
   size, stack-based buffer.  This class is designed to be allocated
   on the stack.  Allocating this class on the heap is usually a bad
   idea ;-)

nsXPIDLC?String

   This class is designed to be instantiated directly.  It provides
   support for the getter_Copies mechanism.  It also provides support
   for a null buffer.  Unlike nsC?String classes, the result of
   nsXPIDLC?String::get() may return null if the nsXPIDLC?String is
   uninitialized or was told to adopt a null-valued string buffer.
   This class can also be cast automatically to |const char_type*|
   for backwards compatibility.  Use this class when working with
   XPCOM getter methods that return |string| or |wstring|.

nsPromiseFlatC?String

This class is designed to be instantiated via the
PromiseFlatC?String family of functions. PromiseFlatC?String
takes a nsAC?String and returns a nsPromiseFlatC?String, which
"promises" to be null-terminated. PromiseFlatC?String will
allocate a copy of the given string if necessary in order to


fulfill


it's promise of a null-terminated string. The "flat" adjective
comes from the old string API that supported multi-fragment


strings.


With these current string changes, PromiseFlatC?String is still


very


useful for ensuring null-terminated storage. This is usually only
important when you need to pass a nsC?Substring to an API that


takes


a raw character pointer.

nsDependentC?Substring

   This class is designed to be instantiated via the Substring family
   of functions.  It represents an array of characters that are not
   null-terminated.  Much like nsDependentC?String, this class
   depends on an externally allocated string buffer.  Use this class
   to create a nsC?Substring that wraps a pair of raw character
   pointers, a pair of nsReadingIterator<char_type>'s, or a section
   of an existing nsC?Substring.


Concatenations in the new world:


 For the most part, string concatenation will continue to work just
 as they always have.  They continue to be the preferred way to
 compose a new string from several other strings.  The only
 difference in the new world is that the string concatenation class
 no longer inherits from nsAC?String, so it cannot be passed to
 functions expecting a nsAC?String.  However, for compatibility with
 existing code, a concatenation of strings will automatically flatten
 itself into a nsC?String when necessary.

For example:

   void foo( const nsAString& s )
   {
     nsCAutoString buf;
     buf = NS_LITERAL_STRING("prefix") + e;
     ...
   }

 In this case, the two strings "prefix" and |e| are written directly
 to the buffer owned by |buf|.

Here's another example:

void bar( const nsAString& s );

   {
     nsString a, b;
     ...
     bar( a + b );
   }

 In this case, a temporary nsString is created to hold the result of
 the concatenation of |a| and |b| prior to calling |bar|.  This
 temporary nsString would not have been generated with the previous
 string implementation that supported multi-fragment nsAStrings.
 However, there was a serious bug in the older implementation that
 made doing this kind of thing crash-prone (especially if the
 definition of |bar| looked something like the definition of |foo| in
 the previous example).  See bug 231995 for more details.

 The main point here is that string concatenations will continue to
 work as they have in the past, with a few minor exceptions.

For example, code such as the following will no longer compile:

   {
     nsString a, b;
     ...
     const nsAString& s = a + b;
     ...
   }

Such code is uncommon. It should be rewritten like this:

   {
     nsString a, b;
     ...
     nsString r( a + b );
     ...
   }

 |r| could also be declared a nsAutoString to avoid heap-allocating
 the result of the concatenation.  However, since nsString allocates
 a sharable buffer, the programmer should consider nsString if it is
 expected that |r| might need to be copied elsewhere.


Maintaining string ABI compatibility:


nsA?CString exists for backwards compatibility with the frozen
nsAC?String vtable. ABI compatibility is maintained even though
nsAC?String's methods are all non-virtual. While this sounds like a
contradiction, compatibility exists by having nsAC?String (in the
new world) store a pointer to an implementation of the old vtable.
The vtable methods all cast |this| to nsC?Substring and invoke the
corresponding methods on nsC?Substring. (Yes, we are utilizing
knowledge of how the compiler implements virtual functions, but


that's


not unfamiliar territory -- xpconnect!) This allows a new


nsAC?String


 to have the same binary signature as an old nsAC?String.  Likewise,
 every method on the new nsAC?String must first check the value of its
 vtable pointer to determine if |this| is really a nsC?Substring
 derived class or actually some other nsAC?String implementation (such
 as the old nsEmbedC?String).

 An advantage of this approach is that it eliminates virtual function
 calls in most cases (especially for internal Gecko code).  Common
 nsAC?String methods like BeginReading and Length are made much
 faster by avoiding virtual function calls.  Code at the callsite is
 also reduced since there is no need to dereference the |this|
 pointer and the vtable pointer in order to gain access to the
 address of the virtual function.  Now, the callsites make DSO/DLL
 calls which are significantly less costly in terms of codesize and
 runtime.


New string API for XPCOM component developers:


 Going forward, external components and embedding applications should
 not call methods directly on nsA?CString.  These classes should be
 viewed as opaque references to string objects.  This is important
 because it will allow Gecko more flexibility to improve its string
 implementation in the future.

 The new external string API consists of a small set of functions
 exported from the XPCOM library as well as a number of inline helper
 functions.  Include nsStringAPI.h to use these functions.

 nsEmbedString has been re-implemented in terms of this new external
 string API.  For Gecko embedders and XPCOM component authors, the
 XPCOM glue provides stub implementations of the new external string
 API.  All one needs to do to use these functions in external code is
 link to the XPCOM glue standalone library (xpcomglue_s).

 If a component is developed against this new API, then it will only
 work in versions of Mozilla that support this new API (obviously).
 This means that component authors interested in compatibility with
 Mozilla 1.4 (for example) will need to develop their components
 against Mozilla 1.4 instead of the later versions of Mozilla.  New
 versions of Mozilla will continue to be binary compatible with
 FROZEN interfaces defined by older versions of Mozilla (see
 "Maintaining string ABI compatibility" above).


So, are we supposed to stop using nsAString?


 The answer is that it depends.  AString in XPIDL will continue to
 map to nsAString.  Gecko interfaces make extensive use of AString,
 ACString, and AUTF8String, and this isn't going to change.  So,
 nsAC?String will continue to be very important to code that
 interacts with XPCOM interfaces.  However, when it makes sense
 nsC?Substring should be used to pass around string references inside
 the Mozilla codebase.  nsC?Substring unlike nsAC?String can be more
 efficient since it does not need to inspect and possibly jump
 through the vtable on each method call.

 Moving code from nsA?CString to nsC?Substring is consistent with the
 overall strategy of deCOMification that is on-going within Gecko.
 If it ever happens that we are able to break binary compatibility
 with Mozilla 1.0, then we would want to equate nsAC?String to
 nsC?Substring.  Of course, I'm not counting on this happening
 anytime soon.

 Embedders and external component developers should treat nsAC?String
 as an opaque handle to a string object.  They should use the new
 external string API and nsEmbedC?String to work with Mozilla
 strings.  <= I'm repeating myself here ;-)


I've tried to minimize the impact of these changes. I don't expect Mozilla hackers to have to re-learn a new string API. If you are writing an external XPCOM component, I hope you will find the new API easier to work with. I should add that my goal is to freeze the new external string API for Mozilla 1.7 final.

Please let me know if you have any questions or concerns about these
changes.


Darin Fisher ([EMAIL PROTECTED]) 2004-02-17




_______________________________________________
Mozilla-seamonkey mailing list
[EMAIL PROTECTED]
http://mail.mozilla.org/listinfo/mozilla-seamonkey








----------------------------------------------------------------------------
----




/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset:


4 -*- */


/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 a small implementation of the nsAString and


nsACString.


*
* The Initial Developer of the Original Code is
* Peter Annema <[EMAIL PROTECTED]>.
*
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <[EMAIL PROTECTED]>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"),


or


* the GNU Lesser General Public License Version 2.1 or later (the


"LGPL"),


* in which case the provisions of the GPL or the LGPL are applicable


instead


* of those above. If you wish to allow use of your version of this file


only


* under the terms of either the GPL or the LGPL, and not to allow others


to


* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the


notice


* and other provisions required by the GPL or the LGPL. If you do not


delete


* the provisions above, a recipient may use your version of this file


under


* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#ifndef nsEmbedString_h___
#define nsEmbedString_h___

#include "nsStringAPI.h"

class nsEmbedString : public nsStringContainer
 {
   public:
     typedef PRUnichar        char_type;
     typedef nsEmbedString    self_type;
     typedef nsAString        abstract_string_type;
     typedef PRUint32         size_type;
     typedef PRUint32         index_type;

     nsEmbedString()
       {
         NS_StringContainerInit(*this);
       }

     nsEmbedString(const self_type& aString)
       {
         NS_StringContainerInit(*this);
         NS_StringCopy(*this, aString);
       }

     explicit
     nsEmbedString(const abstract_string_type& aReadable)
       {
         NS_StringContainerInit(*this);
         NS_StringCopy(*this, aReadable);
       }

explicit
nsEmbedString(const char_type* aData, size_type aLength =


PR_UINT32_MAX)


       {
         NS_StringContainerInit(*this);
         NS_StringSetData(*this, aData, aLength);
       }

     ~nsEmbedString()
       {
         NS_StringContainerFinish(*this);
       }

     const char_type* get() const
       {
         const char_type* data;
         NS_StringGetData(*this, &data);
         return data;
       }

     size_type Length() const
       {
         const char_type* data;
         return NS_StringGetData(*this, &data);
       }

void Assign(const self_type& aString)
{
NS_StringCopy(*this, aString);
}
void Assign(const abstract_string_type& aReadable)
{
NS_StringCopy(*this, aReadable);
}
void Assign(const char_type* aData, size_type aLength =


PR_UINT32_MAX)


       {
         NS_StringSetData(*this, aData, aLength);
       }
     void Assign(char_type aChar)
       {
         NS_StringSetData(*this, &aChar, 1);
       }

self_type& operator=(const self_type& aString) {


Assign(aString); return *this; }


self_type& operator=(const abstract_string_type& aReadable) {


Assign(aReadable); return *this; }


self_type& operator=(const char_type* aPtr) {


Assign(aPtr); return *this; }


self_type& operator=(char_type aChar) {


Assign(aChar); return *this; }


void Replace( index_type cutStart, size_type cutLength, const


char_type* data, size_type length = size_type(-1) )


{
NS_StringSetDataRange(*this, cutStart, cutLength, data, length);
}
void Replace( index_type cutStart, size_type cutLength, char_type


c )


{
Replace(cutStart, cutLength, &c, 1);
}
void Replace( index_type cutStart, size_type cutLength, const


abstract_string_type& readable )


{
const char_type* data;
PRUint32 dataLen = NS_StringGetData(readable, &data);
NS_StringSetDataRange(*this, cutStart, cutLength, data,


dataLen);


}

void Append( char_type c )


{ Replace(size_type(-1), 0, c); }


void Append( const char_type* data, size_type length =


size_type(-1) ) { Replace(size_type(-1), 0, data,
length); }


void Append( const abstract_string_type& readable )


{ Replace(size_type(-1), 0, readable); }


self_type& operator+=( char_type c )


{ Append(c); return *this; }


self_type& operator+=( const char_type* data )


{ Append(data); return *this; }


self_type& operator+=( const abstract_string_type& readable )


{ Append(readable); return *this; }


void Insert( char_type c, index_type pos )


{ Replace(pos, 0, c); }


void Insert( const char_type* data, index_type pos, size_type length


= size_type(-1) ) { Replace(pos, 0, data, length); }


void Insert( const abstract_string_type& readable, index_type pos )


{ Replace(pos, 0, readable); }


void Cut( index_type cutStart, size_type cutLength )


{ Replace(cutStart, cutLength, nsnull, 0); }


};

class nsEmbedCString : public nsCStringContainer
 {
   public:
     typedef char             char_type;
     typedef nsEmbedCString   self_type;
     typedef nsACString       abstract_string_type;
     typedef PRUint32         size_type;
     typedef PRUint32         index_type;

     nsEmbedCString()
       {
         NS_CStringContainerInit(*this);
       }

     nsEmbedCString(const self_type& aString)
       {
         NS_CStringContainerInit(*this);
         NS_CStringCopy(*this, aString);
       }

     explicit
     nsEmbedCString(const abstract_string_type& aReadable)
       {
         NS_CStringContainerInit(*this);
         NS_CStringCopy(*this, aReadable);
       }

explicit
nsEmbedCString(const char_type* aData, size_type aLength =


PR_UINT32_MAX)


       {
         NS_CStringContainerInit(*this);
         NS_CStringSetData(*this, aData, aLength);
       }

     ~nsEmbedCString()
       {
         NS_CStringContainerFinish(*this);
       }

     const char_type* get() const
       {
         const char_type* data;
         NS_CStringGetData(*this, &data);
         return data;
       }

     size_type Length() const
       {
         const char_type* data;
         return NS_CStringGetData(*this, &data);
       }

void Assign(const self_type& aString)
{
NS_CStringCopy(*this, aString);
}
void Assign(const abstract_string_type& aReadable)
{
NS_CStringCopy(*this, aReadable);
}
void Assign(const char_type* aData, size_type aLength =


PR_UINT32_MAX)


       {
         NS_CStringSetData(*this, aData, aLength);
       }
     void Assign(char_type aChar)
       {
         NS_CStringSetData(*this, &aChar, 1);
       }

self_type& operator=(const self_type& aString) {


Assign(aString); return *this; }


self_type& operator=(const abstract_string_type& aReadable) {


Assign(aReadable); return *this; }


self_type& operator=(const char_type* aPtr) {


Assign(aPtr); return *this; }


self_type& operator=(char_type aChar) {


Assign(aChar); return *this; }


void Replace( index_type cutStart, size_type cutLength, const


char_type* data, size_type length = size_type(-1) )


{
NS_CStringSetDataRange(*this, cutStart, cutLength, data,


length);


}
void Replace( index_type cutStart, size_type cutLength, char_type


c )


{
Replace(cutStart, cutLength, &c, 1);
}
void Replace( index_type cutStart, size_type cutLength, const


abstract_string_type& readable )


{
const char_type* data;
PRUint32 dataLen = NS_CStringGetData(readable, &data);
NS_CStringSetDataRange(*this, cutStart, cutLength, data,


dataLen);


}

void Append( char_type c )


{ Replace(size_type(-1), 0, c); }


void Append( const char_type* data, size_type length =


size_type(-1) ) { Replace(size_type(-1), 0, data,
length); }


void Append( const abstract_string_type& readable )


{ Replace(size_type(-1), 0, readable); }


self_type& operator+=( char_type c )


{ Append(c); return *this; }


self_type& operator+=( const char_type* data )


{ Append(data); return *this; }


self_type& operator+=( const abstract_string_type& readable )


{ Append(readable); return *this; }


void Insert( char_type c, index_type pos )


{ Replace(pos, 0, c); }


void Insert( const char_type* data, index_type pos, size_type length


= size_type(-1) ) { Replace(pos, 0, data, length); }


void Insert( const abstract_string_type& readable, index_type pos )


{ Replace(pos, 0, readable); }


void Cut( index_type cutStart, size_type cutLength )


{ Replace(cutStart, cutLength, nsnull, 0); }


};

#endif // !defined(nsEmbedString_h___)





----------------------------------------------------------------------------
----




/* vim:set ts=2 sw=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <[EMAIL PROTECTED]>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"),


or


* the GNU Lesser General Public License Version 2.1 or later (the


"LGPL"),


* in which case the provisions of the GPL or the LGPL are applicable


instead


* of those above. If you wish to allow use of your version of this file


only


* under the terms of either the GPL or the LGPL, and not to allow others


to


* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the


notice


* and other provisions required by the GPL or the LGPL. If you do not


delete


* the provisions above, a recipient may use your version of this file


under


* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#ifndef nsStringAPI_h__
#define nsStringAPI_h__

/**
* nsStringAPI.h
*
* This file describes a minimal API for working with XPCOM's abstract
* string classes.  It divorces the consumer from having any run-time
* dependency on the implementation details of the abstract string types.
*/

#include "nscore.h"
#define NS_STRINGAPI(x) extern "C" NS_COM x




/* -------------------------------------------------------------------------
*/


/**
* These are dummy class definitions for the abstract string types used in
* XPIDL generated header files.  Do not count on the structure of these
* classes, and do not try to mix these definitions with the internal
* definition of these classes used within the mozilla codebase.
*/

#ifndef nsAString_external
#define nsAString_external nsAString
#endif

class nsAString_external
{
private:
 void *v;
};

#ifndef nsACString_external
#define nsACString_external nsACString
#endif

class nsACString_external
{
private:
 void *v;
};




/* -------------------------------------------------------------------------
*/


/**
* nsStringContainer
*
* This is an opaque data type that is large enough to hold the canonical
* implementation of nsAString. The binary structure of this class is an
* implementation detail.
*
* The string data stored in a string container is always single fragment
* and null-terminated.
*
* Typically, string containers are allocated on the stack for temporary
* use. However, they can also be malloc'd if necessary. In either case,
* a string container is not useful until it has been initialized with a
* call to NS_StringContainerInit. The following example shows how to use
* a string container to call a function that takes a |nsAString &|


out-param.


*
* NS_METHOD GetBlah(nsAString &aBlah);
*
* void MyCode()
* {
* nsStringContainer sc;
* if (NS_StringContainerInit(sc))
* {
* nsresult rv = GetBlah(sc);
* if (NS_SUCCEEDED(rv))
* {
* const PRUnichar *data = NS_StringGetDataPtr(sc);
* //
* // |data| now points to the result of the GetBlah function
* //
* }
* NS_StringContainerFinish(sc);
* }
* }
*
* The following example show how to use a string container to pass a


string


* parameter to a function taking a |const nsAString &| in-param.
*
*   NS_METHOD SetBlah(const nsAString &aBlah);
*
*   void MyCode()
*   {
*     nsStringContainer sc;
*     if (NS_StringContainerInit(sc))
*     {
*       const PRUnichar kData[] = {'x','y','z','\0'};
*       NS_StringSetData(sc, kData, sizeof(kData)-1);
*
*       SetBlah(sc);
*
*       NS_StringContainerFinish(sc);
*     }
*   }
*/
class nsStringContainer : public nsAString_external
{
private:
 void     *d1;
 PRUint32  d2;
 void     *d3;

public:
 nsStringContainer() {} // MSVC6 needs this
};

/**
* NS_StringContainerInit
*
* @param aContainer string container reference
* @return true if string container successfully initialized
*
* This function may allocate additional memory for aContainer. When
* aContainer is no longer needed, NS_StringContainerFinish should be


called.


*/
NS_STRINGAPI(PRBool)
NS_StringContainerInit(nsStringContainer &aContainer);

/**
* NS_StringContainerFinish
*
* @param aContainer    string container reference
*
* This function frees any memory owned by aContainer.
*/
NS_STRINGAPI(void)
NS_StringContainerFinish(nsStringContainer &aContainer);




/* -------------------------------------------------------------------------
*/


/**
* NS_StringGetData
*
* This function returns a const character pointer to the string's


internal


* buffer, the length of the string, and a boolean value indicating


whether


* or not the buffer is null-terminated.
*
* @param aStr abstract string reference
* @param aData out param that will hold the address of aStr's
* internal buffer
* @param aTerminated if non-null, this out param will be set to


indicate


*                      whether or not aStr's internal buffer is null-
*                      terminated
* @return              length of aStr's internal buffer
*/
NS_STRINGAPI(PRUint32)
NS_StringGetData
 (const nsAString &aStr, const PRUnichar **aData,
  PRBool *aTerminated = nsnull);

/**
* NS_StringSetData
*
* This function copies aData into aStr.
*
* @param aStr abstract string reference
* @param aData character buffer
* @param aDataLength number of characters to copy from source string


(pass


* PR_UINT32_MAX to copy until end of aData,


designated by


* a null character)
*
* This function does not necessarily null-terminate aStr after copying


data


* from aData. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its


data


* will be null-terminated by this function.
*/
NS_STRINGAPI(void)
NS_StringSetData
 (nsAString &aStr, const PRUnichar *aData,
  PRUint32 aDataLength = PR_UINT32_MAX);

/**
* NS_StringSetDataRange
*
* This function copies aData into a section of aStr. As a result it can


be


* used to insert new characters into the string.
*
* @param aStr abstract string reference
* @param aCutOffset starting index where the string's existing data
* is to be overwritten (pass PR_UINT32_MAX to cause
* aData to be appended to the end of aStr, in which
* case the value of aCutLength is ignored).
* @param aCutLength number of characters to overwrite starting at
* aCutOffset (pass PR_UINT32_MAX to overwrite until


the


* end of aStr).
* @param aData character buffer (pass null to cause this function
* to simply remove the "cut" range)
* @param aDataLength number of characters to copy from source string


(pass


* PR_UINT32_MAX to copy until end of aData,


designated by


* a null character)
*
* This function does not necessarily null-terminate aStr after copying


data


* from aData. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its


data


* will be null-terminated by this function.
*/
NS_STRINGAPI(void)
NS_StringSetDataRange
 (nsAString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength,
  const PRUnichar *aData, PRUint32 aDataLength = PR_UINT32_MAX);

/**
* NS_StringCopy
*
* This function makes aDestStr have the same value as aSrcStr. It is
* provided as an optimization.
*
* @param aDestStr abstract string reference to be modified
* @param aSrcStr abstract string reference containing source string
*
* This function does not necessarily null-terminate aDestStr after


copying


* data from aSrcStr. The behavior depends on the implementation of the
* abstract string, aDestStr. If aDestStr is a reference to a
* nsStringContainer, then its data will be null-terminated by this


function.


*/
NS_STRINGAPI(void)
NS_StringCopy
 (nsAString &aDestStr, const nsAString &aSrcStr);

/**
* NS_StringAppendData
*
* This function appends data to the existing value of aStr.
*
* @param aStr abstract string reference to be modified
* @param aData character buffer
* @param aDataLength number of characters to append (pass PR_UINT32_MAX


to


* append until a null-character is encountered)
*
* This function does not necessarily null-terminate aStr upon completion.
* The behavior depends on the implementation of the abstract string,


aStr.


* If aStr is a reference to a nsStringContainer, then its data will be


null-


* terminated by this function.
*/
inline void
NS_StringAppendData(nsAString &aStr, const PRUnichar *aData,
                   PRUint32 aDataLength = PR_UINT32_MAX)
{
 NS_StringSetDataRange(aStr, PR_UINT32_MAX, 0, aData, aDataLength);
}

/**
* NS_StringInsertData
*
* This function inserts data into the existing value of aStr at the


specified


* offset.
*
* @param aStr abstract string reference to be modified
* @param aOffset specifies where in the string to insert aData
* @param aData character buffer
* @param aDataLength number of characters to append (pass PR_UINT32_MAX


to


* append until a null-character is encountered)
*
* This function does not necessarily null-terminate aStr upon completion.
* The behavior depends on the implementation of the abstract string,


aStr.


* If aStr is a reference to a nsStringContainer, then its data will be


null-


* terminated by this function.
*/
inline void
NS_StringInsertData(nsAString &aStr, PRUint32 aOffset, const PRUnichar


*aData,


                   PRUint32 aDataLength = PR_UINT32_MAX)
{
 NS_StringSetDataRange(aStr, aOffset, 0, aData, aDataLength);
}

/**
* NS_StringCutData
*
* This function shortens the existing value of aStr, by removing


characters


* at the specified offset.
*
* @param aStr abstract string reference to be modified
* @param aCutOffset specifies where in the string to insert aData
* @param aCutLength number of characters to remove
*/
inline void
NS_StringCutData(nsAString &aStr, PRUint32 aCutOffset, PRUint32


aCutLength)


{
 NS_StringSetDataRange(aStr, aCutOffset, aCutLength, nsnull, 0);
}




/* -------------------------------------------------------------------------
*/


/**
* nsCStringContainer
*
* This is an opaque data type that is large enough to hold the canonical
* implementation of nsACString.  The binary structure of this class is an
* implementation detail.
*
* The string data stored in a string container is always single fragment
* and null-terminated.
*
* @see nsStringContainer for use cases and further documentation.
*/
class nsCStringContainer : public nsACString_external
{
private:
 void    *d1;
 PRUint32 d2;
 void    *d3;

public:
 nsCStringContainer() {} // MSVC6 needs this
};

/**
* NS_CStringContainerInit
*
* @param aContainer string container reference
* @return true if string container successfully initialized
*
* This function may allocate additional memory for aContainer. When
* aContainer is no longer needed, NS_CStringContainerFinish should be


called.


*/
NS_STRINGAPI(PRBool)
NS_CStringContainerInit(nsCStringContainer &aContainer);

/**
* NS_CStringContainerFinish
*
* @param aContainer    string container reference
*
* This function frees any memory owned by aContainer.
*/
NS_STRINGAPI(void)
NS_CStringContainerFinish(nsCStringContainer &aContainer);




/* -------------------------------------------------------------------------
*/


/**
* NS_CStringGetData
*
* This function returns a const character pointer to the string's


internal


* buffer, the length of the string, and a boolean value indicating


whether


* or not the buffer is null-terminated.
*
* @param aStr abstract string reference
* @param aData out param that will hold the address of aStr's
* internal buffer
* @param aTerminated if non-null, this out param will be set to


indicate


*                      whether or not aStr's internal buffer is null-
*                      terminated
* @return              length of aStr's internal buffer
*/
NS_STRINGAPI(PRUint32)
NS_CStringGetData
 (const nsACString &aStr, const char **aData,
  PRBool *aTerminated = nsnull);

/**
* NS_CStringSetData
*
* This function copies aData into aStr.
*
* @param aStr abstract string reference
* @param aData character buffer
* @param aDataLength number of characters to copy from source string


(pass


* PR_UINT32_MAX to copy until end of aData,


designated by


* a null character)
*
* This function does not necessarily null-terminate aStr after copying


data


* from aData. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its


data


* will be null-terminated by this function.
*/
NS_STRINGAPI(void)
NS_CStringSetData
 (nsACString &aStr, const char *aData,
  PRUint32 aDataLength = PR_UINT32_MAX);

/**
* NS_CStringSetDataRange
*
* This function copies aData into a section of aStr. As a result it can


be


* used to insert new characters into the string.
*
* @param aStr abstract string reference
* @param aCutOffset starting index where the string's existing data
* is to be overwritten (pass PR_UINT32_MAX to cause
* aData to be appended to the end of aStr, in which
* case the value of aCutLength is ignored).
* @param aCutLength number of characters to overwrite starting at
* aCutOffset (pass PR_UINT32_MAX to overwrite until


the


* end of aStr).
* @param aData character buffer (pass null to cause this function
* to simply remove the "cut" range)
* @param aDataLength number of characters to copy from source string


(pass


* PR_UINT32_MAX to copy until end of aData,


designated by


* a null character)
*
* This function does not necessarily null-terminate aStr after copying


data


* from aData. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its


data


* will be null-terminated by this function.
*/
NS_STRINGAPI(void)
NS_CStringSetDataRange
 (nsACString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength,
  const char *aData, PRUint32 aDataLength = PR_UINT32_MAX);

/**
* NS_CStringCopy
*
* This function makes aDestStr have the same value as aSrcStr. It is
* provided as an optimization.
*
* @param aDestStr abstract string reference to be modified
* @param aSrcStr abstract string reference containing source string
*
* This function does not necessarily null-terminate aDestStr after


copying


* data from aSrcStr. The behavior depends on the implementation of the
* abstract string, aDestStr. If aDestStr is a reference to a
* nsStringContainer, then its data will be null-terminated by this


function.


*/
NS_STRINGAPI(void)
NS_CStringCopy
 (nsACString &aDestStr, const nsACString &aSrcStr);

/**
* NS_CStringAppendData
*
* This function appends data to the existing value of aStr.
*
* @param aStr abstract string reference to be modified
* @param aData character buffer
* @param aDataLength number of characters to append (pass PR_UINT32_MAX


to


* append until a null-character is encountered)
*
* This function does not necessarily null-terminate aStr upon completion.
* The behavior depends on the implementation of the abstract string,


aStr.


* If aStr is a reference to a nsStringContainer, then its data will be


null-


* terminated by this function.
*/
inline void
NS_CStringAppendData(nsACString &aStr, const char *aData,
                   PRUint32 aDataLength = PR_UINT32_MAX)
{
 NS_CStringSetDataRange(aStr, PR_UINT32_MAX, 0, aData, aDataLength);
}

/**
* NS_CStringInsertData
*
* This function inserts data into the existing value of aStr at the


specified


* offset.
*
* @param aStr abstract string reference to be modified
* @param aOffset specifies where in the string to insert aData
* @param aData character buffer
* @param aDataLength number of characters to append (pass PR_UINT32_MAX


to


* append until a null-character is encountered)
*
* This function does not necessarily null-terminate aStr upon completion.
* The behavior depends on the implementation of the abstract string,


aStr.


* If aStr is a reference to a nsStringContainer, then its data will be


null-


* terminated by this function.
*/
inline void
NS_CStringInsertData(nsACString &aStr, PRUint32 aOffset, const char


*aData,


                   PRUint32 aDataLength = PR_UINT32_MAX)
{
 NS_CStringSetDataRange(aStr, aOffset, 0, aData, aDataLength);
}

/**
* NS_CStringCutData
*
* This function shortens the existing value of aStr, by removing


characters


* at the specified offset.
*
* @param aStr abstract string reference to be modified
* @param aCutOffset specifies where in the string to insert aData
* @param aCutLength number of characters to remove
*/
inline void
NS_CStringCutData(nsACString &aStr, PRUint32 aCutOffset, PRUint32


aCutLength)


{
 NS_CStringSetDataRange(aStr, aCutOffset, aCutLength, nsnull, 0);
}

#endif // nsStringAPI_h__





_______________________________________________
Mozilla-seamonkey mailing list
[EMAIL PROTECTED]
http://mail.mozilla.org/listinfo/mozilla-seamonkey



_______________________________________________ Mozilla-xpcom mailing list [EMAIL PROTECTED] http://mail.mozilla.org/listinfo/mozilla-xpcom

Reply via email to