o
    „s¢Y¬$  ã                   @   s�   d Z 	 ddd… Zddd… ZdgZzddlZW n ey%   ddlZY nw 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)Úutilsc                   @   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   sT   || _ |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   ÚgetDater
   r   r   r   ÚignoreErrorsÚboolr   )Úselfr   r   r   r   r	   r
   r   © r   úN/var/www/html/env/lib/python3.10/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Ú	cStringIOÚStringIOÚstr)ÚclsÚstringr   r   r   Ú
fromStringg   s   zDbfHeader.fromStringc           
      C   sì   |  d¡ | d¡}t d|dd… ¡\}}}t|d ƒ}|dk r&|d7 }n|d	7 }| d
|||t|d ƒ|t|d ƒt|d ƒfƒ}d}| d¡}|d dvrt|| d¡7 }t |d ¡ ||¡}	| |	¡ |	j	}| d¡}|d dvsO|S )z%Return header object from the stream.r   é    z<I2Hé   é   r   éP   iÐ  él  Né   r   )úÚ
é   r   )
ÚseekÚreadÚstructÚunpackÚordr   Ú	lookupForr   Ú	_addFieldÚend)
r   ÚstreamÚ_dataÚ_cntÚ_hdrLenÚ_recLenÚ_yearÚ_objÚ_posÚ_fldr   r   r   r   m   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>   ‘   r?   c                 C   r:   r;   )r
   Údayr=   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 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
r'   c                 S   s   g | ]}d |  ¡  ‘qS )z%10s %4s %3s %3s)Ú	fieldInfo©Ú.0r9   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Ú_defr7   Ú_nameÚ_typeÚ_lenÚ_decÚ_clsr   r   r   r/   ¶   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   r/   Úlenr   r   r   )r   rQ   Ú_oldLenr   r   r   ÚaddField×   s   
zDbfHeader.addFieldc                 C   sL   |  d¡ | |  ¡ ¡ | d dd„ | jD ƒ¡¡ | tdƒ¡ d| _dS )z&Encode and write header to the stream.r   Ú c                 S   s   g | ]}|  ¡ ‘qS r   )ÚtoStringrF   r   r   r   rH   ó   s    z#DbfHeader.write.<locals>.<listcomp>é   FN)r)   Úwriter^   rI   r   Úchrr   )r   r1   r   r   r   r`   ï   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$   z                    )	r+   Úpackr	   r<   r@   rA   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)rL   Ú
basestringÚupperr   ÚnameÚKeyError)r   ÚitemrU   rC   r   r   r   Ú__getitem__  s   


ÿ
zDbfHeader.__getitem__)Nr   r   r   r   NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   r   Úclassmethodr   Úpropertyr<   r@   rA   r   rK   r/   r\   r`   r^   rf   rl   r   r   r   r   r   #   s4    
ÿ*ý!)rp   Ú__version__Ú__date__Ú__all__r   ÚImportErrorÚiorc   r+   Útimer]   r   r   Úobjectr   r   r   r   r   Ú<module>   s     	þ