ó
    �®žj//  ã                   ó®  • S r SSKrSSKrSSKrSSKJr  SSKJr  SSKJ	r	  SSK
JrJr  SSKJrJrJrJrJr  SSKJr  SS	KJr  SS
KJrJrJrJrJr  SSKJr  SSKJ r   SSK!J"r"  \RF                  " \$5      r%Sr&\RN                  " S5      r(\)" SS15      r*\\+\,\4   r- " S S\"5      r. " S S5      r/ " S S5      r0 " S S\5      r1S\S\2\2\+      S\4S jr3g)a3  Backend for mainframe EBCDIC data files.

EBCDIC files carry no self-describing structure: the byte stream is a sequence
of fixed-width records whose fields are only meaningful together with the COBOL
copybook that produced them. The copybook is therefore supplied as an
`EbcdicLayout` through `EbcdicBackendOptions`, and this backend turns each
record schema into one table of the resulting `DoclingDocument`.

Decoding is pure Python: character data goes through the standard library
EBCDIC codecs, and the COBOL numeric usages are unpacked from their nibbles.
é    N)ÚDecimal)ÚBytesIO)ÚPath)ÚCallableÚUnion)ÚDocItemLabelÚDoclingDocumentÚDocumentOriginÚ	TableCellÚ	TableData)Úoverride)ÚDeclarativeDocumentBackend)ÚEbcdicBackendOptionsÚEbcdicFieldÚEbcdicFieldTypeÚEbcdicLayoutÚEbcdicRecordLayout)ÚInputFormat)ÚInputDocument)ÚDocumentLoadErrorzapplication/x-ebcdicz[\x00-\x1f\x7f-\x9f]é   é   c                   ó   • \ rS rSrSrSrg)ÚEbcdicDecodeErroré<   z8A field could not be decoded with the configured layout.© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r   ó    Ú[/home/mande/repo/quber/.venv/lib/python3.13/site-packages/docling/backend/ebcdic_backend.pyr   r   <   s   † ÜBr#   r   c                   ó®   • \ rS rSrSrS\S\SS4S jrS\S	\	S\
4S
 jrS\S\4S jr\S\S\S\4S j5       r\S\S\4S j5       r\S\S\4S j5       rSrg)Ú_FieldDecoderé@   z/Decode single EBCDIC fields into Python values.ÚencodingÚstrip_control_charactersÚreturnNc           
      óŒ  ^ •  [         R                  " U5      T l        UT l        [        R                  T R                  [        R                  U 4S j[        R                  U 4S j[        R                  T R                  [        R                  T R                  0T l        g ! [         a  n[	        SU< S35      UeS nAff = f)NzUnknown EBCDIC codec Ú.c                 ó$   >• TR                  U SS9$ )NT©Úsigned©Ú_binary©ÚdataÚselfs    €r$   Ú<lambda>Ú(_FieldDecoder.__init__.<locals>.<lambda>K   s   ø€ °$·,±,¸tÈD°,Ñ2Qr#   c                 ó$   >• TR                  U SS9$ )NFr.   r0   r2   s    €r$   r5   r6   L   s   ø€ ¸4¿<¹<Ø˜Uð <Hñ <r#   )ÚcodecsÚ
getdecoderÚ_decode_textÚLookupErrorr   Ú_strip_control_charactersr   ÚSTRINGÚ_stringÚINTEGERÚUNSIGNED_INTEGERÚPACKED_DECIMALÚ_packed_decimalÚZONED_DECIMALÚ_zoned_decimalÚ	_decoders)r4   r(   r)   Úexcs   `   r$   Ú__init__Ú_FieldDecoder.__init__C   sª   ø€ ð	TÜ &× 1Ò 1°(Ó ;ˆDÔð *BˆÔ&ä×"Ñ" D§L¡LÜ×#Ñ#Ô%QÜ×,Ñ,ô /ô ×*Ñ*¨D×,@Ñ,@Ü×)Ñ)¨4×+>Ñ+>ðS
ˆ�øô ó 	TÜ#Ð&;¸H¹<ÀqÐ$IÓJÐPSÐSûð	Tús   ƒB# Â#
CÂ-B>Â>Cr3   Úfieldc           
      ó¨  •  U R                   UR                     " U5      n[        U[        5      (       a6  UR                  (       a%  [        U5      R                  UR                  * 5      $ U$ ! [        [        [        [
        4 aI  n[        SUR                  < SUR                  R                   SUR                  5       < S35      UeSnAff = f)z9Decode the bytes of one field as described by its layout.zCannot decode field z	 of type z from r,   N)rE   ÚtypeÚArithmeticErrorr;   ÚUnicodeErrorÚ
ValueErrorr   ÚnameÚvalueÚhexÚ
isinstanceÚintÚscaler   Úscaleb)r4   r3   rI   rP   rF   s        r$   ÚdecodeÚ_FieldDecoder.decodeS   s´   € ð	Ø—N‘N 5§:¡:Ò.¨tÓ4ˆEô �eœS×!Ñ! e§k§kÜ˜5“>×(Ñ(¨%¯+©+¨Ó6Ð6Øˆøô  ¤¬l¼JÐGó 	Ü#Ø& u§z¡z¡n°I¸e¿j¹j×>NÑ>NÐ=Oð PØŸ™›
‘~ Qð(óð ðûð	ús   ‚A. Á.CÂACÃCc                 ó–   • U R                  U5      u  p#U R                  (       a  [        R                  SU5      nUR	                  5       $ )NÚ )r:   r<   Ú_CONTROL_CHARACTERSÚsubÚstrip)r4   r3   ÚtextÚ_s       r$   r>   Ú_FieldDecoder._string`   s;   € Ø×#Ñ# DÓ)‰ˆØ×)×)Ü&×*Ñ*¨2¨tÓ4ˆDØ�z‰z‹|Ðr#   r/   c                 ó,   • [         R                  U SUS9$ )NÚbig)Ú	byteorderr/   )rS   Ú
from_bytes)r3   r/   s     r$   r1   Ú_FieldDecoder._binaryf   s   € ä�~‰~˜d¨e¸Fˆ~ÐCÐCr#   c                 óˆ   • U R                  5       n[        USS =(       d    S5      n[        US   S5      [        ;   a  U* $ U$ )z@Unpack COMP-3: two digits per byte, sign in the trailing nibble.NéÿÿÿÿÚ0é   )rQ   rS   Ú_NEGATIVE_SIGNS)r3   ÚnibblesÚdigitss      r$   rB   Ú_FieldDecoder._packed_decimalj   sC   € ð —(‘(“*ˆÜ�W˜S˜b�\×( SÓ)ˆÜ˜g b™k¨2Ó.´/ÓA�ˆwÐMÀvÐMr#   c                 ó  • U  Vs/ s H  oS-  PM	     nn[        S U 5       5      (       a  [        U R                  5        S35      e[        SR	                  S U 5       5      5      nU S   S-	  [
        ;   a  U* $ U$ s  snf )z:Unpack a signed display numeric: one digit per low nibble.é   c              3   ó*   #   • U  H	  oS :„  v •  M     g7f)é	   Nr   ©Ú.0Únibbles     r$   Ú	<genexpr>Ú/_FieldDecoder._zoned_decimal.<locals>.<genexpr>u   s   é € Ð0ª˜f˜Žzªùs   ‚z holds a non-decimal digitrY   c              3   ó8   #   • U  H  n[        U5      v •  M     g 7f©N)Ústrrq   s     r$   rt   ru   w   s   é € Ð?²w¨VœS Ÿ[˜[²wùs   ‚rf   é   )ÚanyrN   rQ   rS   Újoinri   )r3   Úbyterj   rk   s       r$   rD   Ú_FieldDecoder._zoned_decimalq   s~   € ñ ,0Ó0ª4 4˜$”;©4ˆÐ0ÜÑ0©Ó0×0Ñ0Ü §¡£
˜|Ð+EÐFÓGÐGÜ�R—W‘WÑ?±wÓ?Ó?Ó@ˆØ˜r™( a™-¬?Ó:�ˆwÐFÀÐFùò	 1s   …A>)r:   rE   r<   )r   r   r   r    r!   rx   ÚboolrG   Úbytesr   Ú_DecodedValuerV   r>   ÚstaticmethodrS   r1   rB   rD   r"   r   r#   r$   r&   r&   @   sÆ   † Ù9ð
 ð 
Àð 
Èô 
ð ˜5ð ¨ð ¸ô ð˜Eð  cô ð ðD�eð D Tð D¨có Dó ðDð ðN˜eð N¨ó Nó ðNð ðG˜Uð G só Gó óGr#   r&   c                   óÒ   • \ rS rSrSrS\S\SS4S jrS\S	\	\
S4   S\\\\\      4   4S
 jrS\S\
S\
S\\\
\
4   4S jr\S\S\
S\
S\
S\S\4S j5       rS\S\S\\   4S jrSrg)Ú_RecordParseré{   z1Split an EBCDIC byte stream into decoded records.ÚlayoutÚdecoderr*   Nc                 ó   • Xl         X l        g rw   )Ú_layoutÚ_decoder)r4   r…   r†   s      r$   rG   Ú_RecordParser.__init__~   s   € ØŒØ�r#   r3   Úmax_recordsc                 ó  • U R                   R                   Vs0 s H  o3R                  / _M     nn[        U5      U R                   R                  -
  nU R                   R
                  nSnXe:  a€  Ub  Xr:  ax  U R                  XU5      u  p8nU R                  XX…UR                  5      n	XCR                     R                  U R                  X95      5        Xh-  nUS-  nXe:  a  Uc  Mq  Xr:  a  Mx  [        R                  SU5        U$ s  snf )zEReturn the decoded rows of every record schema, keyed by schema name.r   é   zDecoded %d EBCDIC records)rˆ   ÚrecordsrO   ÚlenÚfooter_sizeÚheader_sizeÚ_read_prefixÚ_takeÚappendÚ_decode_recordÚ_logÚdebug)
r4   r3   r‹   ÚrecordÚrowsÚendÚoffsetÚcountÚsizeÚbodys
             r$   ÚparseÚ_RecordParser.parse‚   s÷   € ð
 +/¯,©,×*>Ò*>ó,
Ú*> �K‰K˜ŠOÑ*>ð 	ð ,
ô �$‹i˜$Ÿ,™,×2Ñ2Ñ2ˆØ—‘×)Ñ)ˆØˆà‹l Ñ 3°uÓ7JØ#'×#4Ñ#4°TÀ3Ó#GÑ ˆF˜&Ø—:‘:˜d¨D°v·{±{ÓCˆDØ—‘Ñ×$Ñ$ T×%8Ñ%8¸Ó%FÔGØ‰NˆFØ�Q‰JˆEð ‹l Ó 3°uÕ7Jô 	�
‰
Ð.°Ô6Øˆùò,
s   ™Dr›   rš   c                 ó�  • U R                   nSnSnUR                  =nbY  U R                  XUR                  X7R                  5      n[        U R                  R                  X‡5      5      nX'R                  -  nUR                  =nbY  U R                  XUR                  X7R                  5      n[        U R                  R                  X‡5      5      nX'R                  -  nUR                  U5      n	U	c  [        SU< S35      eUc  U	R                  OXTR                  -
  n
U
S:  a  [        SU SUR                   S35      eXšU4$ )z?Consume the record prefix and resolve the schema and body size.Nz%No record layout matches record type r,   r   zRecord length z is shorter than the z-byte record prefix.)rˆ   Úrecord_length_fieldr“   r�   rO   rS   r‰   rV   Úrecord_type_fieldrx   Úselectr   Úprefix_size)r4   r3   r›   rš   r…   ÚlengthÚrecord_typerI   Úchunkr˜   r�   s              r$   r’   Ú_RecordParser._read_prefix—   s<  € ð —‘ˆØ#'ˆØ(,ˆà×/Ñ/Ð/ˆEÑ<Ø—J‘J˜t¨U¯Z©Z¸¿j¹jÓIˆEÜ˜Ÿ™×-Ñ-¨eÓ;Ó<ˆFØ—j‘jÑ ˆFØ×-Ñ-Ð-ˆEÑ:Ø—J‘J˜t¨U¯Z©Z¸¿j¹jÓIˆEÜ˜dŸm™m×2Ñ2°5Ó@ÓAˆKØ—j‘jÑ ˆFà—‘˜{Ó+ˆØ‰>Ü#Ø7¸±ÀaÐHóð ð %™nˆv�{Š{°&×;MÑ;MÑ2MˆØ�!‹8Ü#Ø   Ð(=Ø×%Ñ%Ð&Ð&:ð<óð ð ˜VÐ#Ð#r#   r�   rO   c           	      óN   • X-   U:”  a  [        SU< SX1-
   SU S35      eXX-    $ )NzInput ends inside z: z of z bytes left.)r   )r3   r›   r�   rš   rO   s        r$   r“   Ú_RecordParser._take¶   sB   € à‰=˜3ÓÜ#Ø$ T¡H¨B¨s©|¨n¸DÀÀÀlÐSóð ð ˜V™]Ð+Ð+r#   r˜   rž   c           	      ó  • / nSnUR                    Hs  nX$XER                  -    nXER                  -  nUR                  [        R                  Ld  M@  UR                  [        U R                  R                  Xe5      5      5        Mu     U$ )Nr   )	Úfieldsr�   rK   r   ÚSKIPr”   rx   r‰   rV   )r4   r˜   rž   Úvaluesr›   rI   r¨   s          r$   r•   Ú_RecordParser._decode_record¾   sp   € ØˆØˆØ—]”]ˆEØ &¯:©:Ñ"5Ð6ˆEØ—j‘jÑ ˆFØ�z‰z¤×!5Ñ!5Ô5Ø—‘œc $§-¡-×"6Ñ"6°uÓ"DÓEÖFñ	 #ð
 ˆr#   )r‰   rˆ   )r   r   r   r    r!   r   r&   rG   r   r   rS   Údictrx   ÚlistrŸ   Útupler   r’   r�   r“   r•   r"   r   r#   r$   rƒ   rƒ   {   sæ   † Ù;ð ˜|ð  °mð  Èô  ðØðØ(-¨c°4¨iÑ(8ðà	ˆc�4˜˜S™	‘?Ð"Ñ	#ôð*$Øð$Ø#&ð$Ø-0ð$à	Ð! 3¨Ð+Ñ	,ô$ð> ð,�Eð , 3ð ,¨cð ,¸ð ,À3ð ,È5ó ,ó ð,ðÐ%7ð ¸uð ÈÈcÉ÷ r#   rƒ   c            
       ó  ^ • \ rS rSr% Sr\\S'   \\S'   \\S'   \	 SS\
S\\\4   S\\S4   S	S4U 4S
 jjj5       rS	\4S jr\	S	\4S j5       r\\	S	\4S j5       5       r\\	S	\\   4S j5       5       r\	S	\4S j5       rSrU =r$ )ÚEbcdicDocumentBackendéÉ   a8  Declarative backend converting EBCDIC data files to `DoclingDocument`.

The layout is mandatory and comes from `EbcdicBackendOptions`, either
inline as an `EbcdicLayout` or as a JSON file. Each record schema becomes
one table whose header row holds the field names; `skip` fields are
consumed but never emitted.
ÚoptionsÚcontentr…   NÚin_docÚpath_or_streamr*   c                 óD  >• Uc
  [        5       n[        TU ]	  XU5        U R                  5       U l         [        U[        5      (       a  UR                  5       OUR                  5       U l	        g ! [        [        4 a  n[        SU R                   S35      UeS nAff = f)Nz;Could not initialize the EBCDIC backend for file with hash r,   )r   ÚsuperrG   Ú_resolve_layoutr…   rR   r   ÚgetvalueÚ
read_bytesr¸   ÚOSErrorrN   r   Údocument_hash)r4   r¹   rº   r·   rF   Ú	__class__s        €r$   rG   ÚEbcdicDocumentBackend.__init__Ö   s¥   ø€ ð ‰?Ü*Ó,ˆGÜ‰Ñ˜°Ô9à×*Ñ*Ó,ˆŒð	ô
 ˜n¬g×6Ñ6ð ×'Ñ'Ô)à#×.Ñ.Ó0ð �Løô
 œÐ$ó 	Ü#ØMØ×%Ñ%Ð& að)óð ðûð	ús   µ:A0 Á0BÂ BÂBc                 óŠ  • U R                   R                  b  U R                   R                  $ U R                   R                  c  [        S5      e [        R
                  " U R                   R                  R                  5       5      $ ! [        [        4 a)  n[        SU R                   R                   S35      UeS nAff = f)NznThe EBCDIC backend needs a layout: set either EbcdicBackendOptions.layout or EbcdicBackendOptions.layout_file.z!Could not read the EBCDIC layout r,   )	r·   r…   Úlayout_filer   r   Úmodel_validate_jsonr¿   rÀ   rN   )r4   rF   s     r$   r½   Ú%EbcdicDocumentBackend._resolve_layoutð   s±   € Ø�<‰<×ÑÑ*Ø—<‘<×&Ñ&Ð&Ø�<‰<×#Ñ#Ñ+Ü#ðSóð ð	Ü×3Ò3Ø—‘×(Ñ(×3Ñ3Ó5óð øô œÐ$ó 	Ü#Ø3°D·L±L×4LÑ4LÐ3MÈQÐOóàðûð	ús   Á7B	 Â	CÂ$B=Â=Cc                 ó,   • [        U R                  5      $ rw   )r~   r¸   )r4   s    r$   Úis_validÚEbcdicDocumentBackend.is_valid  s   € ä�D—L‘LÓ!Ð!r#   c                 ó   • g)NFr   ©Úclss    r$   Úsupports_paginationÚ)EbcdicDocumentBackend.supports_pagination  s   € ð r#   c                 ó$   • [         R                  1$ rw   )r   ÚEBCDICrÌ   s    r$   Úsupported_formatsÚ'EbcdicDocumentBackend.supported_formats
  s   € ô ×"Ñ"Ð#Ð#r#   c                 óÌ  • U R                  5       (       d  [        SU R                   S35      e[        U R                  R
                  =(       d    S[        U R                  S9n[        U R                  R                  =(       d    SUS9nU R                  R                  (       a2  UR                  [        R                  U R                  R                  S9  [        U R                  R                   U R                  R"                  5      n[%        U R                  U5      R'                  U R(                  U R                  R*                  5      nU R                  R,                   Hy  nXER
                     (       d  M  [/        U R                  R,                  5      S:”  a  UR1                  UR
                  S	9  UR3                  [5        XTUR
                     5      S
9  M{     U$ )z7Parse the EBCDIC data into one table per record schema.zCannot convert doc with z$ because the backend failed to init.zfile.ebc)ÚfilenameÚmimetypeÚbinary_hashÚfile)rO   Úorigin)Úlabelr]   r�   )r]   )r3   )rÉ   r   rÁ   r
   rØ   rO   Ú
_MIME_TYPEr	   Ústemr…   ÚdescriptionÚadd_textr   ÚTEXTr&   r·   r(   r)   rƒ   rŸ   r¸   r‹   rŽ   r�   Úadd_headingÚ	add_tableÚ_build_table)r4   rÙ   Údocr†   r™   r˜   s         r$   ÚconvertÚEbcdicDocumentBackend.convert  sf  € ð �}‰}�‰Ü#Ø*¨4×+=Ñ+=Ð*>ð ?*ð *óð ô
  Ø—Y‘Y—^‘^×1 zÜØ×*Ñ*ñ
ˆô
  4§9¡9§>¡>×#;°VÀFÑKˆØ�;‰;×"×"Ø�L‰Lœ|×0Ñ0°t·{±{×7NÑ7NˆLÑOäØ�L‰L×!Ñ! 4§<¡<×#HÑ#Hó
ˆô ˜TŸ[™[¨'Ó2×8Ñ8Ø�L‰L˜$Ÿ,™,×2Ñ2ó
ˆð —k‘k×)Ô)ˆFØŸ™×$ÙÜ�4—;‘;×&Ñ&Ó'¨!Ó+Ø—‘ V§[¡[�Ñ1Ø�M‰Mœ|¨F¸¿¹Ñ4EÓFˆMÓGñ *ð ˆ
r#   )r¸   r…   rw   )r   r   r   r    r!   r   Ú__annotations__r   r   r   r   r   r   r   rG   r½   r~   rÉ   ÚclassmethodrÎ   Úsetr   rÒ   r	   rä   r"   Ú__classcell__)rÂ   s   @r$   rµ   rµ   É   sù   ø‡ ñð "Ó!ØƒNØÓàð
 6:ñ	àðð ˜g t˜mÑ,ðð Ð+¨TÐ1Ñ2ð	ð
 
÷ó ðð2 ô ð" ð"˜$ó "ó ð"ð Øð Dó ó ó ðð Øð$ # kÑ"2ó $ó ó ð$ð ð˜ó ó ör#   rµ   r˜   r™   r*   c                 óŽ  • U R                    Vs/ s H-  o"R                  [        R                  Ld  M!  UR                  PM/     nn[        [        U5      S-   [        U5      / S9n[        U/UQ5       HI  u  pV[        U5       H5  u  pxUR                  R                  [        UUUS-   UUS-   US:H  S95        M7     MK     U$ s  snf )zDLay the decoded records out as a table with a field-name header row.r�   )Únum_rowsÚnum_colsÚtable_cellsr   )r]   Ústart_row_offset_idxÚend_row_offset_idxÚstart_col_offset_idxÚend_col_offset_idxÚcolumn_header)r­   rK   r   r®   rO   r   r�   Ú	enumeraterí   r”   r   )	r˜   r™   rI   ÚheaderÚtableÚrow_idxÚrowÚcol_idxrP   s	            r$   râ   râ   2  sÃ   € ð !'§¢óÚ -�u·±Ä?×CWÑCWÐ1W‹
ˆ�
Œ
¡ð ð ô œs 4›y¨1™}´s¸6³{ÐPRÑS€EÜ! 6 /¨D /Ö2‰ˆÜ'¨žn‰NˆGØ×Ñ×$Ñ$ÜØØ)0Ø'.°¡{Ø)0Ø'.°¡{Ø")¨Q¡,ñö	ó -ñ 3ð €Lùò!s
   � C³C)4r!   r8   ÚloggingÚreÚdecimalr   Úior   Úpathlibr   Útypingr   r   Údocling_core.types.docr   r	   r
   r   r   Útyping_extensionsr   Ú docling.backend.abstract_backendr   Ú!docling.datamodel.backend_optionsr   r   r   r   r   Údocling.datamodel.base_modelsr   Údocling.datamodel.documentr   Údocling.exceptionsr   Ú	getLoggerr   r–   rÛ   ÚcompilerZ   Ú	frozensetri   rx   rS   r€   r   r&   rƒ   rµ   r²   râ   r   r#   r$   Ú<module>r	     sì   ðñ
ó Û Û 	Ý Ý Ý ß "÷õ õ 'å G÷õ õ 6Ý 4Ý 0à×Ò˜Ó"€à#€
ð —j’jÐ!8Ó9Ð ñ ˜S #˜JÓ'€à�c˜3 Ð'Ñ(€ôCÐ)ô C÷8Gñ 8G÷vKñ Kô\fÐ6ô fðRÐ+ð °4¸¸S¹	±?ð Àyõ r#   