home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / libs / xaes_new.lzh / TREECOPY.C < prev    next >
C/C++ Source or Header  |  1994-12-04  |  8KB  |  67 lines

  1. /* * treecopy.c * * (c) 1994 by Thomas Binder (binder@rbg.informatik.th-darmstadt.de), * Johann-Valentin-May-Stra₧e 7, 64665 Alsbach-Hähnlein, Germany
  2.  *
  3.  * Modifications by Ken Hollis (khollis@chatlink.com) * * Contains a routine that dublicates an AES-object-tree. * * Permission is granted to spread this routine, but only the .c- and * the .h-file together, *unchanged*. Permission is also granted to * use this routine in own productions, as long as it's mentioned that * the routine was used and that it was written by me. * * I can't be held responsible for the correct function of this routine, * nor for any damage that occurs after the correct or incorrect use of * this routine. USE IT AT YOUR OWN RISK! * * If you find any bugs or have suggestions, please contact me! * * History: * 10/30/94: Creation
  4.  * 12/04/94: Modifications to make sure objects are complient to their
  5.  *             original object type, and verbose error message if the
  6.  *             copy didn't work.  Formatted source to look better. */#include "xaes.h"
  7. #include "treecopy.h"/* * tree_copy * * Copy a complete object-tree including all substructures (optional). *
  8.  * CAUTION: The object-tree *must* have the LASTOB-flag (0x20) set in * it's physically last member. *
  9.  * BUG: Up to now tree_copy won't copy the color-icon-structure, * because I'm too lazy ;) Maybe I'll do that one day. If you need it * urgently, contact me and force me to work... Btw, this doesn't mean * that G_CICONs won't be copied at all, but the copied tree will * share the CICONBLKs with the original. * * Input: * tree: Pointer to tree which should be copied * what: Specifies what substructures should be copied, too (see the *       C_xxx-definitions in tree-copy.h for details) * * Output: * NULL: Tree couldn't be copied (due to lack of memory) * otherwise: Pointer to copied tree, use free to dealloc it's memory */OBJECT *tree_copy(OBJECT *tree, WORD what){    WORD    i, objects;    size_t    to_malloc, size;    OBJECT    *new_tree;    char    *area;/* Make sure that C_xxxPOINTER implies C_xxx */    if (what & C_TEDINFOPOINTER)        what |= C_TEDINFO;
  10.     if (what & C_ICONBLKPOINTER)        what |= C_ICONBLK;
  11.     if (what & C_BITBLKPOINTER)        what |= C_BITBLK;
  12. /* Calculate the number of bytes we need for the new tree */    to_malloc = (size_t) 0;    for (i = 0;;) {
  13. /* Size of the OBJECT-structure itself */        to_malloc += sizeof(OBJECT);
  14.         switch (tree[i].ob_type & 0xff)    {            case G_TEXT:            case G_BOXTEXT:            case G_FTEXT:            case G_FBOXTEXT:                if (what & C_TEDINFO)
  15. /* Size of a TEDINFO-structure */                    to_malloc += sizeof(TEDINFO);
  16.                 if (what & C_TEDINFOPOINTER) {/* Sizes of the strings in the TEDINFO-structure */
  17.                     to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_txtlen;                    to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_txtlen;                    to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_tmplen;                }                break;
  18.             case G_IMAGE:                if (what & C_BITBLK)
  19. /* Size of the BITBLK-structure */                    to_malloc += sizeof(BITBLK);
  20.                 if (what & C_BITBLKPOINTER) {/* Size of the image-data in the BITBLK-structure */
  21.                     to_malloc += (size_t)((LONG)tree[i].ob_spec.bitblk->bi_wb *
  22.                                           (LONG)tree[i].ob_spec.bitblk->bi_hl);                }                break;            case G_USERDEF:                if (what & C_USERBLK)
  23. /* Size of the USERBLK-structure */                    to_malloc += sizeof(USERBLK);                break;
  24.             case G_BUTTON:            case G_STRING:            case G_TITLE:                if (what & C_TITLEBUTTONSTRING) {
  25. /* Size of the string (with one null character at the end) */                    to_malloc += strlen(tree[i].ob_spec.free_string) + 1L;                }                break;
  26.             case G_ICON:                if (what & C_ICONBLK)
  27. /* Size of the ICONBLK-structure */                    to_malloc += sizeof(BITBLK);
  28.                 if (what & C_ICONBLKPOINTER) {
  29. /* Sizes of icon-data, icon-mask and icon-text */                    to_malloc += (size_t)((LONG)tree[i].ob_spec.iconblk->ib_wicon *
  30.                                           (LONG)tree[i].ob_spec.iconblk->ib_hicon /
  31.                                                 4L + 1L + (LONG)strlen(tree[i].ob_spec.iconblk->ib_ptext));                }                break;        }
  32. /* If the size is odd, make it even */        if ((LONG)to_malloc & 1)            to_malloc++;
  33. /* Exit if we've reached the last object in the tree */        if (tree[i].ob_flags & LASTOB)            break;
  34.         i++;    }
  35.     objects = i + 1;
  36. /* If there's not enough memory left for the new tree, return NULL */    if ((new_tree = (OBJECT *) malloc(to_malloc)) == NULL) {
  37.         form_alert(1, "[3][Sorry, there is no available|memory for this copy!][ OK ]");        return(NULL);
  38.     }
  39. /* * area contains a pointer to the area where we copy the structures to */    area = (char *)((LONG)new_tree + (LONG)objects * (LONG)sizeof(OBJECT));
  40.     for (i = 0; i < objects; i++) {
  41. /* Copy the contents of the OBJECT-structure */        new_tree[i] = tree[i];
  42.  
  43. /* This was added to assure true copies of the object type */
  44.         new_tree[i].ob_type = tree[i].ob_type;
  45.         switch (tree[i].ob_type & 0xff) {            case G_TEXT:            case G_BOXTEXT:            case G_FTEXT:            case G_FBOXTEXT:                if (what & C_TEDINFO) {
  46. /* Copy the contents of the TEDINFO-structure */                    *(TEDINFO *)area = *tree[i].ob_spec.tedinfo;                    new_tree[i].ob_spec.tedinfo = (TEDINFO *)area;                    area += sizeof(TEDINFO);                }
  47.                 if (what & C_TEDINFOPOINTER) {
  48. /* Copy the strings in the TEDINFO-structure */                    strncpy(area, tree[i].ob_spec.tedinfo->te_ptext, tree[i].ob_spec.tedinfo->te_txtlen);                    new_tree[i].ob_spec.tedinfo->te_ptext = area;                    area += tree[i].ob_spec.tedinfo->te_txtlen;                    strncpy(area, tree[i].ob_spec.tedinfo->te_ptmplt, tree[i].ob_spec.tedinfo->te_tmplen);                    new_tree[i].ob_spec.tedinfo->te_ptmplt = area;                    area += tree[i].ob_spec.tedinfo->te_tmplen;                    strncpy(area, tree[i].ob_spec.tedinfo->te_pvalid, tree[i].ob_spec.tedinfo->te_txtlen);                    new_tree[i].ob_spec.tedinfo->te_pvalid = area;                    area += tree[i].ob_spec.tedinfo->te_txtlen;                }                break;
  49.             case G_IMAGE:                if (what & C_BITBLK) {
  50. /* Copy the contents of the BITBLK-structure */                    *(BITBLK *)area = *tree[i].ob_spec.bitblk;                    new_tree[i].ob_spec.bitblk = (BITBLK *)area;                    area += sizeof(BITBLK);                }
  51.                 if (what & C_BITBLKPOINTER) {
  52. /* Copy the image-data */                    size = (size_t)((LONG)tree[i].ob_spec.bitblk->bi_wb *
  53.                                      (LONG)tree[i].ob_spec.bitblk->bi_hl);                    memcpy(area, tree[i].ob_spec.bitblk->bi_pdata, size);                    new_tree[i].ob_spec.bitblk->bi_pdata = (WORD *)area;                    area += size;                }                break;
  54.             case G_USERDEF:
  55.                 if (what & C_USERBLK) {
  56. /* Copy the contents of the USERBLK-structure */                    *(USERBLK *)area = *tree[i].ob_spec.userblk;                    new_tree[i].ob_spec.userblk = (USERBLK *)area;                    area += sizeof(USERBLK);                }                break;
  57.             case G_BUTTON:            case G_STRING:            case G_TITLE:                if (what & C_TITLEBUTTONSTRING) {
  58. /* Copy the string */                    size = strlen(tree[i].ob_spec.free_string) + 1L;                    strcpy(area, tree[i].ob_spec.free_string);                    new_tree[i].ob_spec.free_string = area;                    area += size;                }                break;
  59.             case G_ICON:                if (what & C_ICONBLK) {
  60. /* Copy the contents of the ICONBLK-structure */                    *(ICONBLK *)area = *tree[i].ob_spec.iconblk;                    new_tree[i].ob_spec.iconblk = (ICONBLK *)area;                    area += sizeof(ICONBLK);                }
  61.                 if (what & C_ICONBLKPOINTER) {                    size = (size_t)((LONG)tree[i].ob_spec.iconblk->ib_wicon *
  62.                                     (LONG)tree[i].ob_spec.iconblk->ib_hicon /
  63.                                     8L);/* Copy the mask-data */                    memcpy(area, tree[i].ob_spec.iconblk->ib_pmask, size);                    new_tree[i].ob_spec.iconblk->ib_pmask =    (WORD *)area;                    area += size;
  64. /* Copy the icon-data */                    memcpy(area, tree[i].ob_spec.iconblk->ib_pdata, size);                    new_tree[i].ob_spec.iconblk->ib_pdata = (WORD *)area;                    area += size;                    size = strlen(tree[i].ob_spec.iconblk->ib_ptext) + 1L;
  65. /* Copy the icon-string */                    strcpy(area, tree[i].ob_spec.iconblk->ib_ptext);                    new_tree[i].ob_spec.iconblk->ib_ptext = area;                    area += size;                }                break;        }
  66. /* Assure that area contains an even address */        if ((LONG)area & 1)            area++;    }
  67.     return(new_tree);}/* EOF */