-cdef class GTFProxy:
- '''Proxy class for access to GTF fields.
-
- This class represents a GTF entry for fast read-access.
- Write-access has been added as well, though some care must
- be taken. If any of the string fields (contig, source, ...)
- are set, the new value is tied to the lifetime of the
- argument that was supplied.
-
- The only exception is the attributes field when set from
- a dictionary - this field will manage its own memory.
-
- '''
-
- cdef:
- char * contig
- char * source
- char * feature
- uint32_t start
- uint32_t end
- char * score
- char * strand
- char * frame
- char * attributes
- int nbytes
- char * data
- cdef bint isModified
- cdef bint hasOwnAttributes
-
- def __cinit__(self ):
- self.data = NULL
- self.isModified = False
- self.hasOwnAttributes = False
-
- cdef take( self, char * buffer, size_t nbytes ):
- '''start presenting buffer.
-
- Take ownership of the pointer.
- '''
- self.data = buffer
- self.update( buffer, nbytes )
- self.isModified = False
-
- cdef present( self, char * buffer, size_t nbytes ):
- '''start presenting buffer.
-
- Do not take ownership of the pointer.
- '''
- self.update( buffer, nbytes )
- self.isModified = False
-
- cdef copy( self, char * buffer, size_t nbytes ):
- '''start presenting buffer.
-
- Take a copy of buffer.
- '''
- cdef int s
- # +1 for '\0'
- s = sizeof(char) * (nbytes + 1)
- self.data = <char*>malloc( s )
- memcpy( <char*>self.data, buffer, s )
- self.update( self.data, nbytes )
- self.isModified = False
-
- cdef update( self, char * buffer, size_t nbytes ):
- '''update internal data.
-
- nbytes does not include the terminal '\0'.
- '''
- cdef int end
- cdef char * cstart, * cend, * cscore
- self.contig = buffer
- self.nbytes = nbytes
- cdef char * pos
-
- if buffer[nbytes] != 0:
- raise ValueError( "incomplete line at %s" % buffer )
-
- pos = strchr( buffer, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.source = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.feature = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- cstart = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- cend = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.score = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.strand = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.frame = pos
-
- pos = strchr( pos, '\t' )
- if pos == NULL: raise ValueError( "malformatted entry at %s" % buffer )
- pos[0] = '\0'
- pos += 1
- self.attributes = pos
- self.start = atoi( cstart ) - 1
- self.end = atoi( cend )
-
- property contig:
- '''contig of feature.'''
- def __get__( self ): return self.contig
- def __set__( self, value ):
- self.isModified = True
- self.contig = value
-
- property feature:
- '''feature name.'''
- def __get__( self ): return self.feature
- def __set__( self, value ):
- self.isModified = True
- self.feature = value
-
- property source:
- '''feature source.'''
- def __get__( self ): return self.source
- def __set__( self, value ):
- self.isModified = True
- self.source = value
-
- property start:
- '''feature start (in 0-based open/closed coordinates).'''
- def __get__( self ): return self.start
- def __set__( self, value ):
- self.isModified = True
- self.start = value
-
- property end:
- '''feature end (in 0-based open/closed coordinates).'''
- def __get__( self ): return self.end
- def __set__( self, value ):
- self.isModified = True
- self.end = value
-
- property score:
- '''feature score.'''
- def __get__( self ):
- if self.score[0] == '.' and self.score[1] == '\0' :
- return None
- else:
- return atof(self.score)
- def __set__( self, value ):
- self.isModified = True
- self.score = value
-
- property strand:
- '''feature strand.'''
- def __get__( self ): return self.strand
- def __set__( self, value ):
- self.isModified = True
- self.strand = value
-
- property frame:
- '''feature frame.'''
- def __get__( self ): return self.frame
- def __set__( self, value ):
- self.isModified = True
- self.frame = value
-
- property attributes:
- '''feature attributes (as a string).'''
- def __get__( self ): return self.attributes
- def __set__( self, value ):
- self.isModified = True
- self.attributes = value
-
- def asDict( self ):
- """parse attributes - return as dict