📄 pgpgroups.c
字号:
PGPFileOffset bufSize;
PGPValidateGroupSet( set );
PGPValidatePtr( buffer );
*buffer = NULL;
pgpEnterPGPErrorFunction();
err = PGPNewMemoryIO( PGPPeekContextMemoryMgr( set->context ),
(PGPMemoryIORef *) &io );
if ( IsntPGPError( err ) )
{
err = sWriteGroupSetToIO( set, (PGPIORef)io);
if ( IsntPGPError( err ) )
{
err = PGPIOSetPos( io,
0);
if ( IsntPGPError( err ) )
{
err = PGPIOGetEOF( io,
&bufSize);
if ( IsntPGPError( err ) )
{
tempBuffer = pgpContextMemAlloc( set->context,
(PGPSize)bufSize, kPGPMemoryMgrFlags_None );
if ( IsntNull( tempBuffer ) )
{
err = PGPIORead( io,
(PGPSize)bufSize,
tempBuffer,
bufferSize);
if ( IsntPGPError( err ) )
{
*buffer = tempBuffer;
tempBuffer = NULL;
}
if ( tempBuffer != NULL )
{
PGPFreeData( tempBuffer );
}
}
else
{
err = kPGPError_OutOfMemory;
}
}
}
}
PGPFreeIO( io );
}
return( err );
}
PGPError
PGPImportGroupSetFromBuffer(
PGPContextRef context,
void * buffer,
PGPSize bufSize,
PGPGroupSetRef * outSet)
{
PGPError err = kPGPError_NoErr;
PGPIORef io = NULL;
PGPValidateContext( context );
PGPValidatePtr( buffer );
PGPValidatePtr( outSet );
*outSet = NULL;
pgpEnterPGPErrorFunction();
err = PGPNewMemoryIOFixedBuffer( PGPPeekContextMemoryMgr( context ), buffer,
bufSize, (PGPMemoryIORef *) &io );
if ( IsntPGPError( err ) )
{
err = PGPNewGroupSet( context, outSet );
if ( IsntPGPError( err ) )
{
err = sReadGroupSetFromIO( (PGPIORef)io, *outSet);
if( IsPGPError( err ) )
{
PGPFreeGroupSet( *outSet );
*outSet = kInvalidPGPGroupSetRef;
}
}
PGPFreeIO( (PGPIORef)io );
}
return( err );
}
static void
sDeleteGroupsArray( PGPGroupSetRef set )
{
PGPContextRef context = set->context;
if ( IsntNull( set->groupArray ) )
{
PGPUInt32 groupIndex;
for( groupIndex = 0; groupIndex < set->numGroups; ++groupIndex )
{
PGPGroup * group;
group = &set->groupArray[ groupIndex ];
sDestroyGroup( group );
}
pgpContextMemFree( context, set->groupArray );
set->groupArray = NULL;
}
}
PGPError
PGPFreeGroupSet( PGPGroupSetRef set )
{
PGPError err = kPGPError_NoErr;
PGPContextRef context = set->context;
PGPValidateGroupSet( set );
pgpEnterPGPErrorFunction();
sDeleteGroupsArray( set );
pgpContextMemFree( context, set );
return( err );
}
PGPBoolean
PGPGroupSetNeedsCommit( PGPGroupSetRef set )
{
pgpAssert( PGPGroupSetIsValid( set ) );
if ( IsNull( set ) )
return( FALSE );
pgpEnterBooleanFunction( FALSE );
return( set->hasBeenModified );
}
static PGPGroupID
sGetNextAvailGroupID(PGPGroupSetRef set)
{
PGPGroupID id;
set->nextAvailGroupID += 1;
id = (PGPGroupID)set->nextAvailGroupID;
return( id );
}
static PGPInt32
sCompareGroupsProc(
PGPGroup * in1,
PGPGroup * in2,
void * userValue )
{
const PGPGroup * group1 = (const PGPGroup *)in1;
const PGPGroup * group2 = (const PGPGroup *)in2;
PGPInt32 result;
(void)userValue;
result = pgpCompareStringsIgnoreCase( group1->name, group2->name );
return( result );
}
#define InsertionSortName sInsertionSortGroups
#define InsertionSortItem PGPGroup
#include "pgpInsertionSort.h"
#undef InsertionSortName
#undef InsertionSortItem
static PGPError
sSortGroups( PGPGroupSetRef set )
{
sInsertionSortGroups( set->groupArray,
set->numGroups, sCompareGroupsProc, 0 );
return( kPGPError_NoErr );
}
#define InsertionSortName sInsertionSortGroupItems
#define InsertionSortItem PGPGroupItem
#include "pgpInsertionSort.h"
#undef InsertionSortName
#undef InsertionSortItem
PGPError
PGPSortGroupItems(
PGPGroupSetRef set,
PGPGroupID id,
PGPGroupItemCompareProc compareProc,
PGPUserValue userValue )
{
PGPError err = kPGPError_NoErr;
PGPGroup * group;
pgpEnterPGPErrorFunction();
err = sFindGroupByID( set, id, &group );
if ( IsntPGPError( err ) )
{
sInsertionSortGroupItems( group->itemsArray,
group->numItems, compareProc, userValue );
}
return( err );
}
PGPError
PGPSortGroupSet(
PGPGroupSetRef set,
PGPGroupItemCompareProc compareProc,
PGPUserValue userValue )
{
PGPUInt32 index;
PGPError err = kPGPError_NoErr;
pgpEnterPGPErrorFunction();
sSortGroups( set );
for( index = 0; index < set->numGroups; ++index )
{
err = PGPSortGroupItems( set,
set->groupArray[ index ].id, compareProc, userValue );
if ( IsPGPError( err ) )
break;
}
return( err );
}
/*____________________________________________________________________________
Add a group to the set. Caller has initialized the group.
____________________________________________________________________________*/
static PGPError
sAddGroup(
PGPGroupSetRef set,
PGPGroup const * group )
{
PGPError err = kPGPError_NoErr;
PGPContextRef context = set->context;
PGPSize newSize;
newSize = ( set->numGroups + 1 ) * sizeof( *group );
err = pgpContextMemRealloc( context, (void **) &set->groupArray,
newSize, 0);
if ( IsntPGPError( err ) )
{
(set->groupArray)[ set->numGroups ] = *group;
set->numGroups++;
}
return( err );
}
PGPError
PGPNewGroup(
PGPGroupSetRef set,
const char * name,
const char * description,
PGPGroupID * idOut )
{
PGPError err = kPGPError_NoErr;
PGPGroup newGroup;
PGPGroupID newID;
PGPGroup * dummyGroup;
PGPValidatePtr( idOut );
*idOut = kPGPInvalidGroupID;
PGPValidatePtr( name );
PGPValidatePtr( description );
PGPValidateParam( strlen( name ) <= kPGPMaxGroupNameLength );
PGPValidateParam( strlen( description ) <= kPGPMaxGroupDescriptionLength );
PGPValidateGroupSet( set );
pgpEnterPGPErrorFunction();
do
{
newID = sGetNextAvailGroupID( set );
}
while ( IsntPGPError( err = sFindGroupByID( set, newID, &dummyGroup ) ));
pgpAssert( newID != kPGPInvalidGroupID );
sInitGroup( set, newID, name, description, &newGroup );
err = sAddGroup( set, &newGroup );
if ( IsntPGPError( err ) )
{
*idOut = newID;
set->hasBeenModified = TRUE;
}
return( err );
}
/*____________________________________________________________________________
Eliminate any reference to the group with ID 'id' from 'group'.
____________________________________________________________________________*/
static PGPError
sEliminateGroupFromGroup(
PGPGroup * group,
PGPGroupID id )
{
PGPUInt32 index;
PGPError err = kPGPError_NoErr;
pgpAssert( IsntNull( group->set ) );
for (index = 0; index < group->numItems; ++index )
{
PGPGroupItem const * item;
item = &group->itemsArray[ index ];
if (item->type == kPGPGroupItem_Group &&
item->u.groupID == id )
{
err = PGPDeleteIndItemFromGroup( group->set, group->id, index );
/* it can only be in there once so we're done */
break;
}
}
return( err );
}
/*____________________________________________________________________________
Eliminate references to this group from everything.
____________________________________________________________________________*/
static PGPError
sEliminateReferencesToGroup(
PGPGroupSetRef set,
PGPGroupID id )
{
PGPUInt32 index;
PGPError err = kPGPError_NoErr;
for (index = 0; index < set->numGroups; ++index )
{
PGPGroup * group;
group = &set->groupArray[ index ];
err = sEliminateGroupFromGroup( group, id );
if ( IsPGPError( err ) )
break;
}
return( err );
}
/*____________________________________________________________________________
Determine if an item is already a member of the group
____________________________________________________________________________*/
static PGPBoolean
sIsGroupMember(
PGPGroup const * group,
PGPGroupItem const * item,
PGPUInt32 * outIndex )
{
PGPBoolean isMember = FALSE;
PGPUInt32 index;
*outIndex = ~(PGPUInt32)0;
for( index = 0; index < group->numItems; ++index )
{
PGPGroupItem const * indItem;
indItem = &group->itemsArray[ index ];
if ( indItem->type == item->type )
{
if ( indItem->type == kPGPGroupItem_Group )
{
if ( indItem->u.groupID == item->u.groupID )
{
*outIndex = index;
isMember = TRUE;
break;
}
}
else if ( indItem->type == kPGPGroupItem_KeyID )
{
if( PGPCompareKeyIDs( &indItem->u.keyID,
&item->u.keyID ) == 0 )
{
*outIndex = index;
isMember = TRUE;
break;
}
}
}
}
return( isMember );
}
/*____________________________________________________________________________
Delete a group. Since other groups may refer to it, search for and
eliminate all references to it.
____________________________________________________________________________*/
PGPError
PGPDeleteGroup(
PGPGroupSetRef set,
PGPGroupID id )
{
PGPError err = kPGPError_NoErr;
PGPUInt32 index;
PGPValidateGroupSet( set );
pgpEnterPGPErrorFunction();
/* find the group in our array */
err = sGetGroupIndexByID( set, id, &index );
if ( IsntPGPError( err ) )
{
PGPGroup * group;
PGPUInt32 bytesAfter;
set->hasBeenModified = TRUE;
/* destroy the group, the remove it from the array */
group = &set->groupArray[ index ];
sDestroyGroup( group );
/* shift bytes down */
bytesAfter = ( set->numGroups - index - 1 ) * sizeof( *group );
if ( bytesAfter != 0 )
{
pgpCopyMemory( group + 1, group, bytesAfter);
}
set->numGroups -= 1;
/* we don't shrink the array */
}
/* now eliminate this group from all other groups (yuck) */
sEliminateReferencesToGroup( set, id );
return( err );
}
/*____________________________________________________________________________
Delete an item from a group. The item may be of any valid kind.
Afterwards, there will be one less item in the group.
____________________________________________________________________________*/
PGPError
PGPDeleteIndItemFromGroup(
PGPGroupSetRef set,
PGPGroupID id,
PGPUInt32 index )
{
PGPGroup * group = NULL;
PGPError err = kPGPError_NoErr;
PGPValidateGroupSet( set );
pgpEnterPGPErrorFunction();
err = sFindGroupByID( set, id, &group );
if ( IsntPGPError( err ) )
{
PGPSize bytesAfter;
PGPGroupItem * item;
PGPValidateParam( index < group->numItems );
set->hasBeenModified = TRUE;
item = &group->itemsArray[ index ];
bytesAfter = ( group->numItems - index - 1 ) * sizeof( *item );
if ( bytesAfter != 0 )
{
pgpCopyMemory( item + 1, item, bytesAfter );
}
group->numItems -= 1;
/* don't bother shrinking, but if nothing left, get rid of it */
if ( group->numItems == 0 )
{
pgpContextMemFree( group->set->context, group->itemsArray );
group->itemsArray = NULL;
}
}
return( err );
}
PGPError
PGPDeleteItemFromGroup(
PGPGroupSetRef set,
PGPGroupID id,
PGPGroupItem const * item )
{
PGPGroup * group = NULL;
PGPError err = kPGPError_NoErr;
PGPValidateGroupSet( set );
PGPValidatePtr( item );
pgpEnterPGPErrorFunction();
err = sFindGroupByID( set, id, &group );
if ( IsntPGPError( err ) )
{
PGPUInt32 index;
if( sIsGroupMember( group, item, &index ) )
{
err = PGPDeleteIndItemFromGroup( set, id, index );
}
else
{
err = kPGPError_ItemNotFound;
}
}
return( err );
}
PGPError
PGPGetGroupInfo(
PGPGroupSetRef set,
PGPGroupID id,
PGPGroupInfo * info )
{
PGPError err = kPGPError_NoErr;
PGPGroup const * group = NULL;
PGPValidatePtr( info );
pgpClearMemory( info, sizeof( *info ) );
PGPValidateGroupSet( set );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -