
    9i                        S r SSKJrJrJr  SSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKJr  \R                   " \5      rSrSR)                  S \ 5       5      r\R,                  S   S:  r\(       a  \r\r\r\r\rO)\R@                  " 5         \!r\"r\!r\\#4r\\RH                  4r\
RJ                  r&\
RN                  r(S	 r)S
 r*S r+S r, " S S\-5      r. " S S\-5      r/ " S S\/5      r0 " S S\-5      r1S S jr2S S jr3S S jr4S S jr5\4r6\2r7 " S S\-5      r8 " S S\85      r9 " S S\85      r:\9\:/r;\S:X  a  SSK<r<\<Rz                  " 5         gg)!a!  
Python implementation of the Binary Structured Data Format (BSDF).

BSDF is a binary format for serializing structured (scientific) data.
See http://bsdf.io for more information.

This is the reference implementation, which is relatively relatively
sophisticated, providing e.g. lazy loading of blobs and streamed
reading/writing. A simpler Python implementation is available as
``bsdf_lite.py``.

This module has no dependencies and works on Python 2.7 and 3.4+.

Note: on Legacy Python (Python 2.7), non-Unicode strings are encoded as bytes.
    )absolute_importdivisionprint_functionN)BytesIO)      r   .c              #   8   #    U  H  n[        U5      v   M     g 7fN)str).0is     U/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/imageio/plugins/_bsdf.py	<genexpr>r   0   s     /w!s1vvws      c                 @    U S::  a  [        SU 5      $ [        SSU 5      $ )z?Encode an unsigned integer into a variable sized blob of bytes.   <B<BQ   )spack)xs    r   lencoder   J   s(     	CxT1~ UC##    c                     [        SU R                  S5      5      S   nUS:X  a  [        SU R                  S5      5      S   nU$ )z'Decode an unsigned integer from a file.r   r   r   r   <Q   )	strunpackread)fns     r   	lendecoder"   Y   s@    $q	"1%ACxdAFF1I&q)Hr   c                 ~    Ub9  UR                  S5      nU R                  5       [        [        U5      5      -   U-   $ U $ )z9Encode the type identifier, with or without extension id.UTF-8)encodeupperr   len)bext_idbbs      r   encode_type_idr+   a   s:    ]]7#wwy73r7++b00r   c                     [        U [        5      =(       aF    [        R                  " SU [        R                  5      =(       a    [        R                  " SU 5      SL $ )z8Use of str.isidentifier() for Legacy Python, but slower.z^\w+$z^[0-9]N)
isinstancestring_typesrematchUNICODE)ss    r   _isidentifierr3   j   sD     	1l# 	+HHXq"**-	+HHY"d*r   c                   f    \ rS rSrSrSS jr     SS jrS rS rS r	S	 r
S
 rS rS rS rSrg)BsdfSerializert   a"  Instances of this class represent a BSDF encoder/decoder.

It acts as a placeholder for a set of extensions and encoding/decoding
options. Use this to predefine extensions and options for high
performance encoding/decoding. For general use, see the functions
`save()`, `encode()`, `load()`, and `decode()`.

This implementation of BSDF supports streaming lists (keep adding
to a list after writing the main file), lazy loading of blobs, and
in-place editing of blobs (for streams opened with a+).

Options for encoding:

* compression (int or str): ``0`` or "no" for no compression (default),
  ``1`` or "zlib" for Zlib compression (same as zip files and PNG), and
  ``2`` or "bz2" for Bz2 compression (more compact but slower writing).
  Note that some BSDF implementations (e.g. JavaScript) may not support
  compression.
* use_checksum (bool): whether to include a checksum with binary blobs.
* float64 (bool): Whether to write floats as 64 bit (default) or 32 bit.

Options for decoding:

* load_streaming (bool): if True, and the final object in the structure was
  a stream, will make it available as a stream in the decoded object.
* lazy_blob (bool): if True, bytes are represented as Blob objects that can
  be used to lazily access the data, and also overwrite the data if the
  file is open in a+ mode.
Nc                     0 U l         0 U l        Uc  [        nU H  nU R                  U5        M     U R                  " S0 UD6  g )N )_extensions_extensions_by_clsstandard_extensionsadd_extension_parse_options)self
extensionsoptions	extensions       r   __init__BsdfSerializer.__init__   sF    "$,J#Iy) $&g&r   c                 (   [        U[        5      (       a&  SSSS.nUR                  UR                  5       U5      nUS;  a  [	        S5      eXl        [        U5      U l        [        U5      U l        [        U5      U l	        [        U5      U l
        g )Nr   r   r   )nozlibbz2)r   r   r   z3Compression must be 0, 1, 2, "no", "zlib", or "bz2")r-   r.   getlower	TypeError_compressionbool_use_checksum_float64_load_streaming
_lazy_blob)r>   compressionuse_checksumfloat64load_streaming	lazy_blobms          r   r=   BsdfSerializer._parse_options   s     k<00!A.A%% 1 1 3[AKi'TUU' ",/W  $N3y/r   c                    [        U[        5      (       a  [        U[        5      (       d  [	        S5      eU" 5       nUR
                  n[        U[        5      (       d  [	        S5      e[        U5      S:X  d  [        U5      S:  a  [        S5      eX0R                  ;   a  [        R                  SU-  5        UR                  nU(       d  / nO![        U[        [        45      (       a  UnOU/nU H#  n[        U[        5      (       a  M  [	        S5      e   U H  nX2R                   4U R"                  U'   M     X R                  U'   U$ )zqAdd an extension to this serializer instance, which must be
a subclass of Extension. Can be used as a decorator.
z*add_extension() expects a Extension class.Extension name must be str.r   r   z<Extension names must be nonempty and shorter than 251 chars.zABSDF warning: overwriting extension "%s", consider removing firstz Extension classes must be types.)r-   type
issubclass	ExtensionrJ   namer   r'   	NameErrorr9   loggerwarningclstuplelist
classtypesr%   r:   )r>   extension_classrA   r]   ra   clsss         r   r<   BsdfSerializer.add_extension   s-    --*_i2X2XHII#%	 ~~$$$9::t9>SY_Q  ###NN*,01 mmDeT]++D5DCc:.. BCC 
 C+/1A1A+AD##C( !*r   c                 R   [        U[        5      (       d  [        S5      eXR                  ;   a  U R                  R	                  U5        [        U R                  R                  5       5       H6  nU R                  U   S   U:X  d  M  U R                  R	                  U5        M8     g)z&Remove a converted by its unique name.rY   r   N)r-   r   rJ   r9   poprc   r:   keys)r>   r]   ra   s      r   remove_extensionBsdfSerializer.remove_extension   s    $$$9::###  &//4467C&&s+A.$6''++C0 8r   c                 D
   [         nUc  UR                  U" SU5      5        gUSL a  UR                  U" SU5      5        gUSL a  UR                  U" SU5      5        g[        U[        5      (       a\  SUs=::  a  S::  a)  O  O&UR                  U" S	U5      [	        S
U5      -   5        gUR                  U" SU5      [	        SU5      -   5        g[        U[
        5      (       a]  U R                  (       a&  UR                  U" SU5      [	        SU5      -   5        gUR                  U" SU5      [	        SU5      -   5        g[        U[        5      (       aP  UR                  S5      nUR                  U" SU5      [        [        U5      5      -   5        UR                  U5        g[        U[        [        45      (       aJ  UR                  U" SU5      [        [        U5      5      -   5        U H  nU R                  XUS5        M     g[        U[        5      (       a  UR                  U" SU5      [        [        U5      5      -   5        UR                  5        H  u  p[         (       a  UR#                  5       (       d   eO[%        U5      (       d   eUR                  S5      n	UR                  [        [        U	5      5      5        UR                  U	5        U R                  XUS5        M     g[        U[&        5      (       aH  UR                  U" SU5      5        [)        X R*                  U R,                  S9n
U
R/                  U5        g[        U[(        5      (       a*  UR                  U" SU5      5        UR/                  U5        g[        U[0        5      (       a  UR2                  S:w  a  [5        S5      e[        U[6        5      (       a'  UR                  U" SU5      [	        SSS5      -   5        O[9        S5      e[        U5      S:  a  [5        S5      eUR;                  U5        UR=                  XR                  U R>                  5        gUb  [5        SU-  5      eU R@                  RC                  URD                  S5      nUcJ  U RF                  R                  5        H*  u  pURI                  X5      (       d  M  XR                  4n  O   SnUb  Uu  pU R                  X" X5      X>5        gSn[9        UURD                  RJ                  -  5      e) zMain encoder function.N   vT   yF   ni i     hh   i<q   d<d   f<fr$      s   l   m   b)rQ   rR   wz$Cannot serialize a read-mode stream.r      r   zOnly ListStream is supportedz"Can only have one stream per file.zExtension %s wronfully encodes object to another extension object (though it may encode to a list/dict that contains other extension objects).zJClass %r is not a valid base BSDF type, nor is it handled by an extension.)&r+   writer-   integer_typesr   floatrN   unicode_typesr%   r   r'   rc   rb   _encodedictitemsPY3isidentifierr3   bytesBlobrK   rM   _to_file
BaseStreammode
ValueError
ListStreamrJ   append	_activate_decoder:   rH   	__class__r9   r0   __name__)r>   r    valuestreamsr)   r   r*   vkeyname_bblobexr]   cext_id2extension_encodets                    r   r   BsdfSerializer._encode   s
   =GGAdFO$d]GGAdFO$e^GGAdFO$}--'%'$%U*;;<$%e*<<=u%%}}$%e*<<=$%e*<<=}--g&BGGAdFOgc"g&667GGBKe}--GGAdFOgc%j&99:Q7D1 t$$GGAdFOgc%j&99:++-3++----(----G,F,-Q7D1 ( u%%GGAdFO$#4#44CUCUD MM!t$$GGAdFO$NN1z**zzS  !GHHE:..$%sA*>>? >?? 7|a !EFFNN5!OOA||T\\:! >@FG  ((,,U__dCBz#//557GDwwt++!88^  8
 B~,.)Q 0 =wP/   EOO$<$< <==r   c                    UR                  S5      nUR                  5       nU(       d
  [        5       eX#:w  a?  [        SUR                  S5      5      S   nUR                  U5      R	                  S5      nOSnUS:X  a  SnGOUS:X  a  SnGOUS	:X  a  S
nGOwUS:X  a   [        SUR                  S5      5      S   nGOQUS:X  a   [        SUR                  S5      5      S   nGO+US:X  a   [        SUR                  S5      5      S   nGOUS:X  a   [        SUR                  S5      5      S   nGOUS:X  ad  [        SUR                  S5      5      S   nUS:X  a  [        SUR                  S5      5      S   nUR                  U5      R	                  S5      nGOuUS:X  Ga;  [        SUR                  S5      5      S   nUS:  a  US:H  n[        SUR                  S5      5      S   nU R
                  (       a<  [        U(       a  UOS5      nUR                  XR                  U R                  5        GOU(       a+  [        U5       V	s/ s H  oR                  U5      PM     nn	GO/ n  UR                  U R                  U5      5        M"  US:X  a  [        SUR                  S5      5      S   n[        U5       V	s/ s H  oR                  U5      PM     nn	GO3US:X  a  [        5       n[        SUR                  S5      5      S   nUS:X  a  [        SUR                  S5      5      S   n[        U5       H  n	[        SUR                  S5      5      S   n
U
S:X  a  [        SUR                  S5      5      S   n
U
S:  d   eUR                  U
5      R	                  S5      nU R                  U5      Xk'   M     OQUS:X  a=  U R                  (       a  [        US45      nO,[        US
45      nUR                  5       nO[!        SU-  5      eUbJ  U R"                  R%                  US5      nUb  UR	                  X5      nU$ [&        R)                  SU-  5        U$ s  sn	f ! [         a     N`f = fs  sn	f ) zMain decoder function.r   r   r   r$   Nrn   ro   Trp   Frq   z<hr   rs   rt   r   rw   rx      ru   rv   ry   r   r   rz      rr{   r|   zParse error %rz'BSDF warning: no extension found for %r)r   rI   EOFErrorr   decoderO   r   r   r   r   ranger   r   rP   r   	get_bytesRuntimeErrorr9   rH   r_   r`   )r>   r    charr   r!   r)   r   n_sclosedr   n_namer]   r   rA   s                 r   r   BsdfSerializer._decodeD  s    vvayJJL *Y$q	*1-AVVAY%%g.FF9E$YE$YE$YdAFF1I.q1E$YdAFF1I.q1E$YdAFF1I.q1E$YdAFF1I.q1E$YD!&&),Q/CczaffQi03FF3K&&w/E$Y$q	*1-ACxcdAFF1I.q1''&Fq<EOOA||T\\B6;Ah?h\\!_hE?EE"!LLa9 # 8!$q	215A27(;(Qa(;$YFE$q	*1-ACxdAFF1I.q11X"43A6S=&tQVVAY7:Fz!zvvf~,,W5"ll1o  $YaYQJ'(/$677 ((,,VT:I$!((5  H6QRU @ $  <s   Q)#Q" =Q2"
Q/.Q/c                 X    [        5       nU R                  X!5        UR                  5       $ )zSave the given object to bytes.)r   savegetvalue)r>   obr    s      r   r%   BsdfSerializer.encode  s!    I		!zz|r   c                    UR                  S5        UR                  [        R                  " S[        S   5      5        UR                  [        R                  " S[        S   5      5        / nU R	                  XUS5        [        U5      S:  a/  US   nUR                  UR                  5       :w  a  [        S5      egg)z0Write the given object to the given file object.   BSDFr   r   r   Nz8The stream object must be the last object to be encoded.)	r   structpackVERSIONr   r'   
_start_postellr   )r>   r    r   r   streams        r   r   BsdfSerializer.save  s    		D'!*-.	D'!*-. QGT* w<!QZF  AFFH, Q  - r   c                 :    [        U5      nU R                  U5      $ )z@Load the data structure that is BSDF-encoded in the given bytes.)r   load)r>   r*   r    s      r   r   BsdfSerializer.decode  s    BKyy|r   c                    UR                  S5      nUS:w  a  [        SU-  5      e[        SUR                  S5      5      S   n[        SUR                  S5      5      S   nSX44-  nU[        S   :w  a  Sn[        U[        U4-  5      eU[        S   :  a   S	n[
        R                  U[        U4-  5        U R                  U5      $ )
z6Load a BSDF-encoded object from the given file object.r   r   z'This does not look like a BSDF file: %rr   r   r   z%i.%izLReading file with different major version (%s) from the implementation (%s).zWBSDF warning: reading file with higher minor version (%s) than the implementation (%s).)r   r   r   r   __version__r_   r`   r   )r>   r    f4major_versionminor_versionfile_versionr   s          r   r   BsdfSerializer.load  s     VVAY=H2MNN!$q	215!$q	215-!??GAJ&0  qK#>>??71:%0  NN1\::;||Ar   )rK   r9   r:   rN   rP   rO   rM   r   )r   FTFF)r   
__module____qualname____firstlineno____doc__rB   r=   r<   rk   r   r   r%   r   r   r   __static_attributes__r8   r   r   r5   r5   t   sO    <' *0)V1Y>vXt&
r   r5   c                   8    \ rS rSrSrSS jrS r\S 5       rSr	g)	r   i  zBase class for streams.c                     SU l         SU l        [        U[        5      (       a	  Xl        SnOUS:X  a  SU l        US;   d   eXl        S U l        SU l        g )Nr   r   r}   )r   r}   )_i_countr-   int_mode_fr   )r>   r   s     r   rB   BaseStream.__init__  sV    dC  KDS[DKz!!!
r   c                     U R                   b  [        S5      eXl         U R                   R                  5       U l        X l        X0l        g )Nz(Stream object cannot be activated twice?)r   IOErrorr   r   r   r   )r>   fileencode_funcdecode_funcs       r   r   BaseStream._activate  s8    77DEE'',,.""r   c                     U R                   $ )z$The mode of this stream: 'r' or 'w'.)r   r>   s    r   r   BaseStream.mode  s     zzr   )r   r   r   r   r   r   r   N)r}   )
r   r   r   r   r   rB   r   propertyr   r   r8   r   r   r   r     s#    !#  r   r   c                   Z    \ rS rSrSr\S 5       r\S 5       rS rSS jr	S r
S rS	 rS
rg)r   i  zbA streamable list object used for writing or reading.
In read mode, it can also be iterated over.
c                     U R                   $ )zTThe number of elements in the stream (can be -1 for unclosed
streams in read-mode).
r   r   s    r   countListStream.count  s    
 {{r   c                     U R                   $ )z/The current index of the element to read/write.)r   r   s    r   indexListStream.index  s     wwr   c                 Z   U R                   U R                  :w  a  [        S5      eU R                  c  [        S5      eU R                  R                  (       a  [        S5      eU R                  U R                  X/S5        U =R                  S-  sl        U =R                   S-  sl         g)zoAppend an item to the streaming list. The object is immediately
serialized and written to the underlying file.
z/Can only append items to the end of the stream.Nz.List stream is not associated with a file yet.zCannot stream to a close file.r   )r   r   r   r   r   r   )r>   items     r   r   ListStream.append  s}     ;;$''!KLL77?JKK77>>:;;TWWdFD11qr   c                 D   U R                   U R                  :w  a  [        S5      eU R                  c  [        S5      eU R                  R                  (       a  [        S5      eU R                  R                  5       nU R                  R                  U R                  S-
  S-
  5        U R                  R                  [        SU(       a  SOS	5      5        U R                  R                  [        S
U R                   5      5        U R                  R                  U5        g)zClose the stream, marking the number of written elements. New
elements may still be appended, but they won't be read during decoding.
If ``unstream`` is False, the stream is turned into a regular list
(not streaming).
z-Can only close when at the end of the stream.N-ListStream is not associated with a file yet.z&Cannot close a stream on a close file.r   r   r   r   r   r   )
r   r   r   r   r   r   seekr   r   r   )r>   unstreamr   s      r   closeListStream.close  s     ;;$''!IJJ77?IJJ77>>BCCGGLLNT__q(1,-eD#s;<eD$++./Qr   c                 6   U R                   S:w  a  [        S5      eU R                  c  [        S5      e[        U R                  SS5      (       a  [        S5      eU R                  S:  aT  U R
                  U R                  :  a
  [        5       eU =R
                  S-  sl        U R                  U R                  5      $  U R                  U R                  5      nU =R
                  S-  sl        U$ ! [         a    U R
                  U l        [        5       ef = f)	ziRead and return the next element in the streaming list.
Raises StopIteration if the stream is exhausted.
r   z$This ListStream in not in read mode.Nr   r   z'Cannot read a stream from a close file.r   r   )	r   r   r   getattrr   r   StopIterationr   r   )r>   ress     r   nextListStream.next,  s     ::@AA77?IJJ477Hd++CDD;;!ww$++%#o%GGqLG<<((&ll477+1
 &"gg#o%&s    1C2 2&Dc                 <    U R                   S:w  a  [        S5      eU $ )Nr   z/Cannot iterate: ListStream in not in read mode.)r   r   r   s    r   __iter__ListStream.__iter__E  s    ::KLLr   c                 "    U R                  5       $ r   )r   r   s    r   __next__ListStream.__next__J  s    yy{r   r   N)F)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r8   r   r   r   r     sH         (&2
r   r   c                   X    \ rS rSrSrSS jrS rS rS rS r	S r
S	 rS
 rS rS rSrg)r   iN  a(  Object to represent a blob of bytes. When used to write a BSDF file,
it's a wrapper for bytes plus properties such as what compression to apply.
When used to read a BSDF file, it can be used to read the data lazily, and
also modify the data if reading in 'r+' mode and the blob isn't compressed.
c                    [        U[        5      (       a>  S U l        U R                  X5      U l        X l        U R                  U-   U l        X@l        g [        U[        5      (       aX  [        U5      S:X  aI  [        US   S5      (       a5  Uu  U l        nS U l        U R                  U R                  U5        SU l        g [        S5      e)Nr   r   r   FzWrong argument to create Blob.)r-   r   r   _from_bytes
compressedrQ   	used_sizeallocated_sizerR   rb   r'   hasattr
_from_file	_modifiedrJ   )r>   r*   rQ   
extra_sizerR   
allow_seeks         r   rB   Blob.__init__X  s    b%  DG"..r?DO*"&..:"=D ,E""s2w!|1v8N8N"$DGZ"DOOODGGZ0"DN<==r   c                     US:X  a  UnOCUS:X  a  [         R                  " US5      nO%US:X  a  [        R                  " US5      nO S5       e[        U5      U l        [        U5      U l        U$ )z"When used to wrap bytes in a blob.r   r   	   r   zUnknown compression identifier)rF   compressrG   r'   	data_sizer   )r>   r   rQ   r   s       r   r   Blob._from_bytesg  sf    !JAua0JAeQ/J:::5UZr   c                    U R                   S::  a  U R                  S:X  ao  UR                  [        SU R                   5      5        UR                  [        SU R                  5      5        UR                  [        U R                  5      5        OrUR                  [        SSU R                   5      5        UR                  [        SSU R                  5      5        UR                  [        SSU R                  5      5        UR                  [        SU R                  5      5        U R                  (       aA  UR                  S[        R                  " U R                  5      R                  5       -   5        OUR                  S5        U R                  S:X  aI  S	UR                  5       S
-   S	-  -
  nUR                  [        SU5      5        UR                  SU-  5        OUR                  [        SS5      5        UR                  U R                  5        UR                  SU R                   U R                  -
  -  5        g)zBPrivate friend method called by encoder to write a blob to a file.r   r   r   r   r   B       r   r   N)r   rQ   r   r   r   r   r
  rR   hashlibmd5r   digestr   )r>   r    	alignments      r   r   Blob._to_filev  s    #%$*:*:a*?GGE$ 3 345GGE$/0GGGDNN+,GGE%d&9&9:;GGE%dnn56GGE%dnn56	c4++,-GGGgkk$//:AACCDGGGq QVVX\Q..IGGE$	*+GGGi'(GGE$N#	 	4..?@Ar   c                    [        SUR                  S5      5      S   nUS:X  a  [        SUR                  S5      5      S   n[        SUR                  S5      5      S   nUS:X  a  [        SUR                  S5      5      S   n[        SUR                  S5      5      S   nUS:X  a  [        SUR                  S5      5      S   n[        SUR                  S5      5      S   n[        SUR                  S5      5      S   nU(       a  UR                  S5      n[        SUR                  S5      5      S   n	UR                  U	5        U(       aH  UR                  5       U l        U R                  U-   U l        UR                  U R                  U-   5        O7SU l        SU l        UR                  U5      U l        UR                  X4-
  5        Xl        X`l        U(       a  WOSU l	        X@l
        X0l        XPl        g)	z(Used when a blob is read by the decoder.r   r   r   r   r   r      N)r   r   r   	start_posend_posr   r   r  rQ   rR   r   r   r
  )
r>   r    r  r   r   r
  rQ   has_checksumchecksumr  s
             r   r  Blob._from_file  s    #43A6S &tQVVAY7:NdAFF1I.q1	!$q	215IdAFF1I.q1	!$q	215IaffQi03 qvvay1!4vvbzHdAFF1I.q1		yVVXDN>>I5DLFF4>>N23!DNDLffY/DOFF>-."&(4H$","r   c                     U R                   c  [        S5      eUS:  a  U R                  U-   nUS:  d  XR                  :  a  [        S5      eU R                   R	                  U R
                  U-   5        g)z8Seek to the given position (relative to the blob start).Nz>Cannot seek in a blob that is not created by the BSDF decoder.r   zSeek beyond blob boundaries.)r   r   r   r   r   r  )r>   ps     r   r   	Blob.seek  sk    77?S  q5##a'Aq5A+++899T^^a'(r   c                     U R                   c  [        S5      eU R                   R                  5       U R                  -
  $ )zCGet the current file pointer position (relative to the blob start).z>Cannot tell in a blob that is not created by the BSDF decoder.)r   r   r   r  r   s    r   r   	Blob.tell  s6    77?S  ww||~..r   c                 ,   U R                   c  [        S5      eU R                  (       a  [        S5      eU R                   R	                  5       [        U5      -   U R                  :  a  [        S5      eSU l        U R                   R                  U5      $ )zWrite bytes to the blob.z?Cannot write in a blob that is not created by the BSDF decoder.z,Cannot arbitrarily write in compressed blob.zWrite beyond blob boundaries.T)	r   r   rQ   r   r   r'   r  r  r   )r>   r*   s     r   r   
Blob.write  sw    77?T  HII77<<>CG#dll29::ww}}R  r   c                    U R                   c  [        S5      eU R                  (       a  [        S5      eU R                   R	                  5       U-   U R
                  :  a  [        S5      eU R                   R                  U5      $ )zRead n bytes from the blob.z>Cannot read in a blob that is not created by the BSDF decoder.z+Cannot arbitrarily read in compressed blob.zRead beyond blob boundaries.)r   r   rQ   r   r   r  r   )r>   r!   s     r   r   	Blob.read  sk    77?S  GHH77<<>A,899ww||Ar   c                    U R                   b  U R                   nOkU R                  R                  5       nU R                  S5        U R                  R	                  U R
                  5      nU R                  R                  U5        U R                  S:X  a  UnU$ U R                  S:X  a  [        R                  " U5      nU$ U R                  S:X  a  [        R                  " U5      nU$ [        SU R                  -  5      e)z&Get the contents of the blob as bytes.r   r   r   zInvalid compression %i)r   r   r   r   r   r   rQ   rF   
decompressrG   r   )r>   r   r   r   s       r   r   Blob.get_bytes  s    ??&JAIIaLdnn5JGGLLOq E  "OOJ/E
 	 "NN:.E  7$:J:JJKKr   c                    U R                   (       a  U R                  (       a  U R                  S5        U R                  R	                  U R
                  5      nU R                  R                  U R                  U R                  -
  S-
  S-
  5        U R                  R                  [        R                  " U5      R                  5       5        ggg)zJReset the blob's checksum if present. Call this after modifying
the data.
r   r   r  N)rR   r  r   r   r   r   r  r  r   r  r  r  )r>   r   s     r   update_checksumBlob.update_checksum  s    
 IIaLdnn5JGGLL$..81<rABGGMM'++j188:;	 "0r   )r   r  r  r   r   rQ   r
  r  r  rR   r   N)r   r   F)r   r   r   r   r   rB   r   r   r  r   r   r   r   r   r)  r   r8   r   r   r   r   N  s;    >B8%#N
)/!
&	<r   r   c                 <    [        U40 UD6nUR                  U 5      $ )zjSave (BSDF-encode) the given object to bytes.
See `BSDFSerializer` for details on extensions and options.
)r5   r%   )r   r?   r@   r2   s       r   r%   r%     !     	z-W-A88B<r   c                     [        U40 UD6n[        U [        5      (       a'  [        U S5       nUR	                  XQ5      sSSS5        $ UR	                  X5      $ ! , (       d  f       g= f)zSave (BSDF-encode) the given object to the given filename or
file object. See` BSDFSerializer` for details on extensions and options.
wbN)r5   r-   r.   openr   )r    r   r?   r@   r2   fps         r   r   r     sU     	z-W-A!\""!T]b66"> ] vva} ]s   A
A(c                 <    [        U40 UD6nUR                  U 5      $ )zhLoad a (BSDF-encoded) structure from bytes.
See `BSDFSerializer` for details on extensions and options.
)r5   r   )r*   r?   r@   r2   s       r   r   r     r,  r   c                 @   [        U40 UD6n[        U [        5      (       a\  U R                  S5      (       a  [        R
                  R                  U 5      n [        U S5       nUR                  U5      sSSS5        $ UR                  U 5      $ ! , (       d  f       g= f)zLoad a (BSDF-encoded) structure from the given filename or file object.
See `BSDFSerializer` for details on extensions and options.
)z~/z~\rbN)	r5   r-   r.   
startswithospath
expanduserr/  r   )r    r?   r@   r2   r0  s        r   r   r   $  sx     	z-W-A!\""<<&&""1%A!T]b66": ] vvay ]s   #B
Bc                   8    \ rS rSrSrSrSrS rS rS r	S r
Srg	)
r\   i>  a  Base class to implement BSDF extensions for special data types.

Extension classes are provided to the BSDF serializer, which
instantiates the class. That way, the extension can be somewhat dynamic:
e.g. the NDArrayExtension exposes the ndarray class only when numpy
is imported.

A extension instance must have two attributes. These can be attributes of
the class, or of the instance set in ``__init__()``:

* name (str): the name by which encoded values will be identified.
* cls (type): the type (or list of types) to match values with.
  This is optional, but it makes the encoder select extensions faster.

Further, it needs 3 methods:

* `match(serializer, value) -> bool`: return whether the extension can
  convert the given value. The default is ``isinstance(value, self.cls)``.
* `encode(serializer, value) -> encoded_value`: the function to encode a
  value to more basic data types.
* `decode(serializer, encoded_value) -> value`: the function to decode an
  encoded value back to its intended representation.

 r8   c                 P    SU R                   < S[        [        U 5      5      < S3$ )Nz<BSDF extension z at 0x>)r]   hexidr   s    r   __repr__Extension.__repr__[  s    04		3r$x=IIr   c                 ,    [        X R                  5      $ r   )r-   ra   r>   r2   r   s      r   r0   Extension.match^  s    !XX&&r   c                     [        5       er   NotImplementedErrorrA  s      r   r%   Extension.encodea      !##r   c                     [        5       er   rD  rA  s      r   r   Extension.decoded  rG  r   N)r   r   r   r   r   r]   ra   r>  r0   r%   r   r   r8   r   r   r\   r\   >  s(    2 D
CJ'$$r   r\   c                   (    \ rS rSrSr\rS rS rSr	g)ComplexExtensionih  r   c                 2    UR                   UR                  4$ r   )realimagrA  s      r   r%   ComplexExtension.encodel  s    r   c                 &    [        US   US   5      $ )Nr   r   )complexrA  s      r   r   ComplexExtension.decodeo  s    qtQqT""r   r8   N)
r   r   r   r   r]   rQ  ra   r%   r   r   r8   r   r   rK  rK  h  s    D
C #r   rK  c                   0    \ rS rSrSrS rS rS rS rSr	g)	NDArrayExtensionis  ndarrayc                 X    S[         R                  ;   a  SS KnUR                  U l        g g )Nnumpyr   )sysmodulesrW  rU  ra   )r>   nps     r   rB   NDArrayExtension.__init__v  s!    ckk!zzDH "r   c                 f    [        US5      =(       a    [        US5      =(       a    [        US5      $ )Nshapedtypetobytes)r  rA  s      r   r0   NDArrayExtension.match|  s'    q'"Twq'':Twq)?TTr   c                 n    [        UR                  [        UR                  5      UR	                  5       S9$ )N)r]  r^  data)r   r]  	text_typer^  r_  rA  s      r   r%   NDArrayExtension.encode  s$    !''177);!))+NNr   c                 t     SS K nUR                  US   US   S9nUS   Ul        U$ ! [         a    Us $ f = f)Nr   rb  r^  )r^  r]  )rW  ImportError
frombufferr]  )r>   r2   r   rZ  as        r   r   NDArrayExtension.decode  sL    	 MM!F)1W:M6G*	  	H	s   ( 77)ra   N)
r   r   r   r   r]   rB   r0   r%   r   r   r8   r   r   rT  rT  s  s    D"UOr   rT  __main__r   )>r   
__future__r   r   r   rG   r  loggingr5  r/   r   rX  typesrF   ior   	getLoggerr   r_   r   joinr   version_infor   r   rc  r.   r   r   r   rZ   rd   basicConfigunicode
basestringlong	ClassTyper   r   unpackr   r   r"   r+   r3   objectr5   r   r   r   r%   r   r   r   loadsdumpsr\   rK  rT  r;   bsdf_climainr8   r   r   <module>r}     s  
& A @ 
   	 	  
   			8	$ hh/w// 
qQILMMJILM$KMu&J 	MM	$_V _J <T Tnt<6 t<t	 	'$ '$T#y #y 2 ()9:  zMMO	 r   