U
    yag’$  ã                   @   sh   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 ddd… Zdd	d… Z	d
gZ
G dd
„ d
ƒZdS )é    Né   )Úfields)ÚgetDatez$Revision: 1.6 $é   éþÿÿÿz$Date: 2010/09/16 05:06:39 $é   Ú	DbfHeaderc                   @   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k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   úP/var/www/html/myvenv/lib/python3.8/site-packages/tablib/packages/dbfpy/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   Ú
fromStringc   s    zDbfHeader.fromStringc              
   C   sì   |  d¡ | d¡}t|ƒtkr.t|t ¡ ƒ}|}t d|dd… ¡\}}}|d }|dk rf|d7 }n|d	7 }| d
||||d ||d |d fƒ}d}	| d¡}|dkrè|| d¡7 }t 	|d ¡ 
||	¡}
| |
¡ |
j}	| d¡}q |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   ÚstreamZfirst_32Ú_dataZ_cntZ_hdrLenZ_recLenZ_yearÚ_objÚ_posÚ_fldr   r   r   r   i   s,    


ÿ

zDbfHeader.fromStreamc                 C   s   | j jS ©N)r
   Úyear©r   r   r   r   Ú<lambda>‹   ó    zDbfHeader.<lambda>c                 C   s   | j jS r7   )r
   Úmonthr9   r   r   r   r:   Œ   r;   c                 C   s   | j jS r7   )r
   Údayr9   r   r   r   r:   �   r;   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 r7   )r   r9   r   r   r   r:   •   r;   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)Z	fieldInfo©Ú.0r6   r   r   r   Ú
<listcomp>¬   s     z&DbfHeader.__repr__.<locals>.<listcomp>)r	   r
   r   r   r   Újoinr   )r   Z_rvr   r   r   Ú__repr__    s     ÿÿzDbfHeader.__repr__c                 G   s‚   g }d}|D ]b}t |tjƒr"|}n8t|ƒ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   ZDbfFieldDefÚtupler/   r   ÚlengthÚappend)r   ÚdefsZ_defsZ_recordLengthZ_defr4   Ú_nameÚ_typeÚ_lenZ_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   rK   Z_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   )ÚtoStringrB   r   r   r   rD   î   s     z#DbfHeader.write.<locals>.<listcomp>Ú r%   FN)	r'   ÚwriterR   r   rE   Úencoder+   r,   r   )r   r2   r   r   r   r   rT   ê   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	   r8   r<   r=   r   r   r   r9   r   r   r   rR   ó   s    ùùzDbfHeader.toStringc                 C   s   t j ¡ | _dS )z9Update ``self.lastUpdate`` field with current date value.N)ÚdatetimeÚdateÚtodayr
   r9   r   r   r   ÚsetCurrentDateÿ   s    zDbfHeader.setCurrentDatec                 C   sH   t |tƒr:| ¡ }| jD ]}|j|kr|  S qt|ƒ‚n
| j| S dS )z9Return a field definition by numeric index or name stringN)rG   r   Úupperr   ÚnameÚKeyError)r   ÚitemrL   r?   r   r   r   Ú__getitem__  s    




zDbfHeader.__getitem__)Nr   r   r   r   NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   r   Úclassmethodr   Úpropertyr8   r<   r=   r   rF   r0   rQ   rT   rR   rZ   r_   r   r   r   r   r       s8           ÿ
)ý 	)rW   r   r-   r+   rS   r   Úutilsr   Ú__version__Ú__date__Ú__all__r   r   r   r   r   Ú<module>   s   