/* JAMLIB - A JAM subroutine library Copyright (C) 1999 Björn Stenberg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Changes made by Johan Billing 2000-04-16: - Fixed broken JAM_GetSubfield() - #includes stdlib.h instead of malloc.h and memory.h Changes made by Johan Billing 2000-09-17: - Added JAM_GetSubfield_R() Backported changes from JAMLIB 1.4.7 made by Johan Billing 2003-10-22 - JAM_NewSubPacket() and JAM_PutSubField() would give memory leaks under low memory conditions. Fixed. Other changes made by Johan Billing 2003-10-22 - Fixed comparison between signed and unsigned variable in JAM_DelSubPacket() and JAM_GetSubField() */ /*********************************************************************** ** ** SUBPACKET.C -- Subfield packet handling ** ** Author: Bj”rn Stenberg (bjorn.stenberg@sth.frontec.se) ** ***********************************************************************/ #include #include #include #include #include "jam.h" /*********************************************************************** ** ** JAM_NewSubPacket - Create a new subfield packet ** ***********************************************************************/ s_JamSubPacket* JAM_NewSubPacket( void ) { s_JamSubPacket* Sub_PS; /* allocate packet struct */ Sub_PS = (s_JamSubPacket*) malloc( sizeof( s_JamSubPacket ) ); if ( !Sub_PS ) return NULL; Sub_PS->NumAlloc = 20; Sub_PS->NumFields = 0; /* allocate pointer array */ Sub_PS->Fields = (s_JamSubfield**) calloc( Sub_PS->NumAlloc, sizeof( s_JamSubfield* ) ); if ( !Sub_PS->Fields ) { free (Sub_PS); return NULL; } return Sub_PS; } /*********************************************************************** ** ** JAM_DelSubPacket - Free the data associated with a subfield packet ** ***********************************************************************/ int JAM_DelSubPacket( s_JamSubPacket* SubPack_PS ) { uint32_t i; if (!SubPack_PS) return JAM_BAD_PARAM; for ( i=0; i < SubPack_PS->NumFields; i++ ) { s_JamSubfield* Field_PS = SubPack_PS->Fields[i]; if ( Field_PS->Buffer ) free( Field_PS->Buffer ); free( Field_PS ); } free( SubPack_PS->Fields ); free( SubPack_PS ); return 0; } /*********************************************************************** ** ** JAM_GetSubfield -- Get first/next subfield from a subfield packet ** (not reentrant) ** ***********************************************************************/ s_JamSubfield* JAM_GetSubfield( s_JamSubPacket* SubPack_PS ) { static s_JamSubPacket* LastPack_PS = NULL; static uint32_t NextIndex_I = 0; if ( SubPack_PS ) { LastPack_PS = SubPack_PS; NextIndex_I = 0; } if ( NextIndex_I < LastPack_PS->NumFields ) return LastPack_PS->Fields[ NextIndex_I++ ]; return NULL; } /*********************************************************************** ** ** JAM_GetSubfield_R -- Get first/next subfield from a subfield packet ** (reentrant) ** ***********************************************************************/ s_JamSubfield* JAM_GetSubfield_R( s_JamSubPacket* SubPack_PS , uint32_t* Count_PI) { if ( *Count_PI < SubPack_PS->NumFields ) return SubPack_PS->Fields[ (*Count_PI)++ ]; return NULL; } /*********************************************************************** ** ** JAM_PutSubfield -- Add a subfield to a subfield packet ** ***********************************************************************/ int JAM_PutSubfield( s_JamSubPacket* SubPack_PS, s_JamSubfield* Field_PS ) { s_JamSubfield* NewField_PS; char* NewBuf_PC; /* do we have to expand the array? */ if ( SubPack_PS->NumFields == SubPack_PS->NumAlloc ) { s_JamSubfield** Fields_PPS; SubPack_PS->NumAlloc *= 2; Fields_PPS = (s_JamSubfield**) realloc( SubPack_PS->Fields, SubPack_PS->NumAlloc * sizeof( s_JamSubfield* ) ); if ( !Fields_PPS ) return JAM_NO_MEMORY; SubPack_PS->Fields=Fields_PPS; } /* ** Copy the passed subfield */ /* allocate a new subfield */ NewField_PS = (s_JamSubfield*) malloc( sizeof( s_JamSubfield ) ); if ( !NewField_PS ) return JAM_NO_MEMORY; /* allocate a new buffer */ if ( Field_PS->DatLen ) { NewBuf_PC = (char*) malloc( Field_PS->DatLen ); if ( !NewBuf_PC ) { free (NewField_PS); return JAM_NO_MEMORY; } memcpy( NewBuf_PC, Field_PS->Buffer, Field_PS->DatLen ); } else NewBuf_PC = NULL; /* copy field struct */ NewField_PS->LoID = Field_PS->LoID; NewField_PS->HiID = Field_PS->HiID; NewField_PS->DatLen = Field_PS->DatLen; NewField_PS->Buffer = NewBuf_PC; /* ** Update subfield packet */ SubPack_PS->Fields[ SubPack_PS->NumFields ] = NewField_PS; SubPack_PS->NumFields++; return 0; }