o
    „s¢Y$  ã                   @   sx   d Z 	 ddd… Zddd… ZdgZddlZddlZddlZddlZddlZd	d
l	m
Z
 d	dlmZ G dd„ deƒZdS )zDBF header definition.

TODO:
  - handle encoding of the character fields
    (encoding information stored in the DBF header)

z$Revision: 1.6 $é   éþÿÿÿz$Date: 2010/09/16 05:06:39 $é   Ú	DbfHeaderé    Né   )Úfields)ÚgetDatec                   @   s¸   e Zd ZdZdZ		d$dd„Zd	d
„ ZeeƒZdd„ ZeeƒZe	dd„ ƒZ
e	dd„ ƒZe	dd„ ƒZdd„ Ze	dd„ edd�Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ ZdS )%r   a|  Dbf header definition.

    For more information about dbf header format visit
    `http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT`

    Examples:
        Create an empty dbf header and add some field definitions:
            dbfh = DbfHeader()
            dbfh.addField(("name", "C", 10))
            dbfh.addField(("date", "D"))
            dbfh.addField(DbfNumericFieldDef("price", 5, 2))
        Create a dbf header with field definitions:
            dbfh = DbfHeader([
                ("name", "C", 10),
                ("date", "D"),
                DbfNumericFieldDef("price", 5, 2),
            ])

    )Ú	signaturer   Ú
lastUpdateÚrecordLengthÚrecordCountÚheaderLengthÚchangedÚ_ignore_errorsNr   é   Fc                 C   sR   || _ |du rg | _nt|ƒ| _t|ƒ| _|| _|| _|| _|| _t	| jƒ| _
dS )aÖ  Initialize instance.

        Arguments:
            fields:
                a list of field definitions;
            recordLength:
                size of the records;
            headerLength:
                size of the header;
            recordCount:
                number of records stored in DBF;
            signature:
                version number (aka signature). using 0x03 as a default meaning
                "File without DBT". for more information about this field visit
                ``http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_NOTE_1_TARGET``
            lastUpdate:
                date of the DBF's update. this could be a string ('yymmdd' or
                'yyyymmdd'), timestamp (int or float), datetime/date value,
                a sequence (assuming (yyyy, mm, dd, ...)) or an object having
                callable ``ticks`` field.
            ignoreErrors:
                error processing mode for DBF fields (boolean)

        N)r	   r   Úlistr   r
   r   r   r   ÚignoreErrorsÚboolr   )Úselfr   r   r   r   r	   r
   r   © r   úO/var/www/html/env/lib/python3.10/site-packages/tablib/packages/dbfpy3/header.pyÚ__init__:   s   

zDbfHeader.__init__c                 C   s   |   t t|ƒ¡¡S )z.Return header instance from the string object.)Ú
fromStreamÚioÚStringIOÚstr)ÚclsÚstringr   r   r   Ú
fromStringd   s   zDbfHeader.fromStringc              
   C   sò   |  d¡ | d¡}t|ƒtkrt|t ¡ ƒ}|}t d|dd… ¡\}}}|d }|dk r3|d7 }n|d	7 }| d
||||d ||d |d fƒ}d}	| d¡}|dkrw|| d¡7 }t 	|d ¡ 
||	¡}
| |
¡ |
j}	| d¡}|dksT|S )z%Return header object from the stream.r   é    z<I2Hé   é   r   éP   iÐ  él  Né   r   ó   é   r   )ÚseekÚreadÚtypeÚbytesÚsysÚgetfilesystemencodingÚstructÚunpackr   Ú	lookupForr   Ú	_addFieldÚend)r   ÚstreamÚfirst_32Ú_dataÚ_cntÚ_hdrLenÚ_recLenÚ_yearÚ_objÚ_posÚ_fldr   r   r   r   j   s.   


ÿ


ûzDbfHeader.fromStreamc                 C   ó   | j jS ©N)r
   Úyear©r   r   r   r   Ú<lambda>Œ   ó    zDbfHeader.<lambda>c                 C   r<   r=   )r
   Úmonthr?   r   r   r   r@   �   rA   c                 C   r<   r=   )r
   Údayr?   r   r   r   r@   Ž   rA   c                 C   s$   t |ƒ | _}| jD ]}||_q
dS )z1Update `ignoreErrors` flag on self and all fieldsN)r   r   r   r   )r   ÚvalueÚ_fieldr   r   r   r   �   s   
ÿzDbfHeader.ignoreErrorsc                 C   s   | j S r=   )r   r?   r   r   r   r@   –   s    z¹Error processing mode for DBF field value conversion

        if set, failing field value conversion will return
        ``INVALID_VALUE`` instead of raising conversion error.

        )Údocc                 C   s:   d| j | j| j| j| jf }|d dd„ | jD ƒ¡7 }|S )Nz”Version (signature): 0x%02x
        Last update: %s
      Header length: %d
      Record length: %d
       Record count: %d
 FieldName Type Len Dec
Ú
c                 S   s   g | ]}d |  ¡  ‘qS )z%10s %4s %3s %3s)Ú	fieldInfo©Ú.0r;   r   r   r   Ú
<listcomp>¬   s    z&DbfHeader.__repr__.<locals>.<listcomp>)r	   r
   r   r   r   Újoinr   )r   Ú_rvr   r   r   Ú__repr__¡   s   ÿù	ÿzDbfHeader.__repr__c                 G   s‚   g }d}|D ]1}t |tjƒr|}nt|ƒd dd… \}}}}	t |¡}
|
|||	| jd�}||j7 }| |¡ q|  j|7  _|S )ah  Internal variant of the `addField` method.

        This method doesn't set `self.changed` field to True.

        Return value is a length of the appended records.
        Note: this method doesn't modify ``recordLength`` and
        ``headerLength`` fields. Use `addField` instead of this
        method if you don't exactly know what you're doing.

        r   )NNNNNr    )r   )Ú
isinstancer   ÚDbfFieldDefÚtupler/   r   ÚlengthÚappend)r   ÚdefsÚ_defsÚ_recordLengthÚ_defr9   Ú_nameÚ_typeÚ_lenÚ_decÚ_clsr   r   r   r0   ²   s   
ÿ
zDbfHeader._addFieldc                 G   sN   | j }|  j | j|Ž 7  _ |s|  j d7  _ ddt| jƒ  d | _d| _dS )a�  Add field definition to the header.

        Examples:
            dbfh.addField(
                ("name", "C", 20),
                dbf.DbfCharacterFieldDef("surname", 20),
                dbf.DbfDateFieldDef("birthdate"),
                ("member", "L"),
            )
            dbfh.addField(("price", "N", 5, 2))
            dbfh.addField(dbf.DbfNumericFieldDef("origprice", 5, 2))

        r   r   TN)r   r0   Úlenr   r   r   )r   rT   Ú_oldLenr   r   r   ÚaddFieldÓ   s   
zDbfHeader.addFieldc                 C   sV   |  d¡ | |  ¡ ¡ dd„ | jD ƒ}| d |¡ t ¡ ¡¡ | d¡ d| _dS )z&Encode and write header to the stream.r   c                 S   s   g | ]}|  ¡ ‘qS r   )ÚtoStringrI   r   r   r   rK   ï   s    z#DbfHeader.write.<locals>.<listcomp>Ú r%   FN)	r'   Úwriter`   r   rL   Úencoder+   r,   r   )r   r2   r   r   r   r   rb   ë   s   


zDbfHeader.writec              
   C   s.   t  d| j| jd | j| j| j| j| j¡d S )z4Returned 32 chars length string with encoded header.z<4BI2Hr#   s                       )	r-   Úpackr	   r>   rB   rC   r   r   r   r?   r   r   r   r`   ô   s   ùùzDbfHeader.toStringc                 C   s   t j ¡ | _dS )z9Update ``self.lastUpdate`` field with current date value.N)ÚdatetimeÚdateÚtodayr
   r?   r   r   r   ÚsetCurrentDate   s   zDbfHeader.setCurrentDatec                 C   sB   t |tƒr| ¡ }| jD ]}|j|kr|  S qt|ƒ‚| j| S )z9Return a field definition by numeric index or name string)rO   r   Úupperr   ÚnameÚKeyError)r   ÚitemrX   rE   r   r   r   Ú__getitem__  s   


ÿ
zDbfHeader.__getitem__)Nr   r   r   r   NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   r   Úclassmethodr   Úpropertyr>   rB   rC   r   rN   r0   r_   rb   r`   rh   rm   r   r   r   r   r       s4    
ÿ*ý!	)rq   Ú__version__Ú__date__Ú__all__r   re   r-   Útimer+   ra   r   Úutilsr   Úobjectr   r   r   r   r   Ú<module>   s    	