List of products.

Here you will find examples to use ProductList.

List of products of type Product.

A product list can contain any number of products. The list contains references of the products as they are generated with product::alloc or product::clone. No copies of the products are created.

When allocating objects like String, ItemRef, Library as well as Product and ProductList, the objects are registered in the script engine. And if they are not released already, they are automatically released at the end of the script.

Products in a product list would be deleted twice under this circumstances: once through the script and once through the list - a double free that leads to an immediate program crash. To prevent from this you must determine whether the product should belong to a list or not. This information is made via a memory hint when creating the product:

Products in lists must not be deleted without removing them from the list before. To delete the products, the same memory hint must be used.

The products of globally defined lists like gProducts are all of type kListOwner.

Use kListOwner (or kGlobalStack) for all products to be inserted into lists.

Please avoid inserting products with kScriptOwner into product lists (although that works and would be semantically correct). The problems are double frees caused by the two releases of the product: One from the list and one from the script engine! But if you clear the list with no element releases, ... up to you.

All entries of gProducts are of type kListOwner.

Products with memory hint kListOwner are released in the following situations:

  1. The product is part of a product list and the list is cleared using productlist::clear (pli, 1).
  2. The product is part of a product list and the list is released using productlist::release (pli, 1).
  3. The product is part of a product list and the end of the script is reached.
  4. The product is not in a list and will be released using product::release (p, kListOwner).

In the following situations, the products remain in memory and can lead to stack overflows:

The following situations could cause serious program corruptions and may crash in InDesign®:

Products that are not inserted into product lists are created with the memory hint kScriptOwner (or kScriptStack).

The usage of products without product list for special cases only. You may need this to compare all elements of a list with one product for example.

Please avoid inserting products with kScriptOwner into product lists (although that works and would be semantically correct). The problems are double frees caused by the two releases of the product: One from the list and one from the script engine! But if you clear the list with no element releases, ... up to you.

Products with the memory hint kScriptOwner are released in the following situations:

  1. Calls to product::release (p, kScriptOwner)
  2. End of script is reached

Products with the memory hint kScriptOwner do not create memory leaks. But please read, however, the notes on the risks of falling in the next paragraph.

The following situations could cause serious program corruption and may crash in InDesign®:

Preconditions
#include "internal/types.h"
#include "internal/products.h"

To copy products from one product list to another, the product::clone function can be used to be used with kListOwner.

#include "internal/types.h"
#include "internal/products.h"
int main() { ProductList sourcePl = productlist::alloc(); ProductList targetPl = productlist::alloc(); Product p;
sourcePl = productlist::get ("watched [pageitemid > 0 ? level < 1]");
for (p = productlist::first(sourcePl); p; p = productlist::next(sourcePl)) { // // ⇒ double free // ⇒ Crash // // productlist::append(targetPl, p);
// // THIS WORKS // Clone the product! // productlist::append(targetPl, product::clone(p, kListOwner)); }
return 0; }

Products included in several lists, must be deleted before deleting the additional lists (or before the end of the script) without deleting its elements!

#include "internal/types.h"
#include "internal/products.h"
int main() { ProductList sourcePl = productlist::alloc(); ProductList targetPl = productlist::alloc(); Product p;
sourcePl = productlist::get ("watched [pageitemid > 0 ? level < 1]");
for (p = productlist::first(sourcePl); p; p = productlist::next(sourcePl)) { // // clear targetPl before end of script! // productlist::append(targetPl, p);
}
productlist::clear (targetPl, 0); // 0 is important!
return 0; }

Since
Version 1.2.2, 24. November 2005
See Also
productlist
product

Alphabetic index HTML hierarchy of classes or Java