Renamed version4 to flaim and version5 to xflaim
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
233
flaim/src/gdcopy.cpp
Normal file
233
flaim/src/gdcopy.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
//-------------------------------------------------------------------------
|
||||
// Desc: Copy GEDCOM tree
|
||||
// Tabs: 3
|
||||
//
|
||||
// Copyright (c) 1990-2000,2003-2006 Novell, Inc. All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the GNU General Public
|
||||
// License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, contact Novell, Inc.
|
||||
//
|
||||
// To contact Novell about this file by physical or electronic mail,
|
||||
// you may find current contact information at www.novell.com
|
||||
//
|
||||
// $Id: gdcopy.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include "flaimsys.h"
|
||||
|
||||
/**************************************************************************
|
||||
Name : GedNodeCopy
|
||||
Area : GEDCOM
|
||||
Desc : Allocates a new node, value, and tag and copies from the old node
|
||||
its attached child(ren) and sibling(s).
|
||||
Notes:
|
||||
****************************************************************************/
|
||||
NODE * GedNodeCopy(
|
||||
POOL * pPool,
|
||||
NODE * node,
|
||||
NODE * childList,
|
||||
NODE * sibList)
|
||||
{
|
||||
NODE * newNd;
|
||||
FLMUINT bias;
|
||||
FLMBYTE * vp;
|
||||
RCODE rc;
|
||||
HFDB hDb;
|
||||
FLMUINT uiContainer;
|
||||
FLMUINT uiRecId;
|
||||
|
||||
// If the node has source information, we need to copy it
|
||||
|
||||
if( RC_OK( GedGetRecSource( node, &hDb, &uiContainer, &uiRecId)))
|
||||
{
|
||||
// The passed in node contains record source information,
|
||||
// so create a GEDCOM record source node
|
||||
|
||||
if( RC_BAD( gedCreateSourceNode( pPool, GedTagNum( node), hDb,
|
||||
uiContainer, uiRecId, &newNd)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a normal (non-source) GEDCOM node
|
||||
|
||||
if( (newNd = GedNodeMake( pPool, GedTagNum( node), &rc)) == NULL)
|
||||
{
|
||||
return( NULL);
|
||||
}
|
||||
}
|
||||
|
||||
newNd->prior = NULL;
|
||||
newNd->next = childList;
|
||||
GedNodeLevelSet( newNd, 0);
|
||||
|
||||
if( (vp = (FLMBYTE *)GedAllocSpace( pPool, newNd, GedValType( node),
|
||||
GedValLen( node), node->ui32EncId, GedEncLen( node))) != NULL)
|
||||
{
|
||||
f_memcpy( vp, GedValPtr( node), GedValLen( node));
|
||||
|
||||
if (node->ui32EncFlags & FLD_HAVE_ENCRYPTED_DATA)
|
||||
{
|
||||
f_memcpy( GedEncPtr( newNd), GedEncPtr( node), GedEncLen( node));
|
||||
}
|
||||
|
||||
newNd->ui32EncFlags = node->ui32EncFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
return( NULL);
|
||||
}
|
||||
|
||||
if( childList)
|
||||
{
|
||||
childList->prior = newNd;
|
||||
for( /* find end of sub-tree */
|
||||
bias = GedNodeLevel( childList) - 1
|
||||
/* 1st child level should be 1 */
|
||||
; childList->next /* continue to last in list */
|
||||
; GedNodeLevelSub( childList, bias), /* correct relative level */
|
||||
childList = childList->next /* follow list */
|
||||
);
|
||||
GedNodeLevelSub( childList, bias); /* correct last node in list */
|
||||
childList->next = sibList;
|
||||
}
|
||||
else
|
||||
childList = newNd; /* no child(ren)--sib(s) link to newNd */
|
||||
|
||||
if( sibList) /* attach sibling(s) */
|
||||
{
|
||||
sibList->prior = childList;
|
||||
childList->next = sibList;
|
||||
for( /* find end of sibList */
|
||||
bias = GedNodeLevel( sibList) /* sib must be level 0 too */
|
||||
; sibList->next
|
||||
; GedNodeLevelSub( sibList, bias), /* correct relative level */
|
||||
sibList = sibList->next
|
||||
);
|
||||
GedNodeLevelSub( sibList, bias); /* correct last node in list */
|
||||
}
|
||||
|
||||
return( newNd);
|
||||
}
|
||||
|
||||
/*API~*********************************************************************
|
||||
Desc: Copies the entire contents of a tree.
|
||||
****************************************************************************/
|
||||
NODE * GedCopy(
|
||||
POOL * pPool,
|
||||
FLMUINT cnt,
|
||||
NODE * tree)
|
||||
{
|
||||
NODE * oldNd;
|
||||
NODE * newNd;
|
||||
NODE * newRoot;
|
||||
FLMUINT baseLevel;
|
||||
|
||||
if( tree)
|
||||
{
|
||||
newRoot = newNd = GedNodeCopy( pPool, tree, NULL, NULL);
|
||||
if( newRoot)
|
||||
{
|
||||
for(
|
||||
baseLevel = GedNodeLevel( tree)
|
||||
; (tree = tree->next) != NULL && /* follow linked list */
|
||||
(
|
||||
GedNodeLevel( tree) > baseLevel || /* process sub-tree */
|
||||
(
|
||||
GedNodeLevel( tree) == baseLevel && /* if sibling in forest AND */
|
||||
--cnt /* count not expired, do next tree */
|
||||
)
|
||||
)
|
||||
;
|
||||
)
|
||||
{
|
||||
oldNd = newNd; /* save for linking below */
|
||||
if( (newNd = GedNodeCopy( pPool, tree, NULL, NULL)) != NULL)
|
||||
{
|
||||
oldNd->next = newNd; /* link up */
|
||||
newNd->prior = oldNd;
|
||||
GedNodeLevelSet( newNd, GedNodeLevel( tree) - baseLevel);
|
||||
}
|
||||
else
|
||||
return( NULL);
|
||||
}
|
||||
}
|
||||
return( newRoot);
|
||||
}
|
||||
|
||||
return( NULL);
|
||||
}
|
||||
|
||||
/*API~***********************************************************************
|
||||
Name : GedClip
|
||||
Area : GEDCOM/LINK
|
||||
Desc : Unlinks a node or sub-tree from its parent and/or siblings.
|
||||
Notes: Starting at the node specified by self, treeCnt sibling trees will
|
||||
be unlinked from their parent node (if any), as well as from their
|
||||
previous and next sibling nodes (if any). If the clipped siblings
|
||||
had a previous sibling and a next sibling, the previous sibling and
|
||||
the next sibling are reconnected as siblings. If the clipped
|
||||
siblings had a parent, a next sibling, but no previous sibling, the
|
||||
next sibling be reconnected to the parent as the parent's first
|
||||
child.
|
||||
*END************************************************************************/
|
||||
NODE *
|
||||
// A pointer to the input node/sub-tree (self) is returned. This
|
||||
// allows GedClip to be used a a parameter to other functions which
|
||||
// require a NODE * parameter.
|
||||
GedClip(
|
||||
FLMUINT treeCnt,
|
||||
// [IN] Number of sibling trees to unlink.
|
||||
NODE * self)
|
||||
// [IN] Pointer to the node or sub-tree which is to be unlinked.
|
||||
{
|
||||
NODE * next;
|
||||
|
||||
if( self)
|
||||
{
|
||||
FLMUINT oldLevel = GedNodeLevel( self);
|
||||
|
||||
GedNodeLevelSet( self, 0); /* clipped tree now at level 0 */
|
||||
|
||||
for( /* skip to next sub-tree */
|
||||
next = self->next;
|
||||
next && /* stop at end of sub-tree */
|
||||
(
|
||||
GedNodeLevel( next) > oldLevel || /* continue if child level */
|
||||
(
|
||||
GedNodeLevel( next) == oldLevel && /* if forest sibling, --treeCnt */
|
||||
--treeCnt /* continue if treeCnt != 0 */
|
||||
)
|
||||
)
|
||||
; GedNodeLevelSub( next, oldLevel), // Adjust levels relative to new root
|
||||
next = next->next)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if( self->prior)
|
||||
{
|
||||
self->prior->next = next; /* re-link the gap in old tree/forest */
|
||||
}
|
||||
|
||||
if( next)
|
||||
{
|
||||
next->prior->next = NULL; /* clipped tree's end must be made null*/
|
||||
next->prior = self->prior; /* re-link the gap in old tree/forest */
|
||||
}
|
||||
self->prior = NULL; /* clipped tree's head must now be root */
|
||||
}
|
||||
return( self);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user