ó žçƒQc@sUddlZddlZddlZddlZddlZdefd„ƒYZdejfd„ƒYZ de fd„ƒYZ dej fd „ƒYZ dd lmZmZmZmZmZmZmZddlZddlZddlZddlZd ejfd „ƒYZd ejfd„ƒYZdad„Zd„Zd„ZdS(iÿÿÿÿNt RangeErrorcBseZdZRS(s6Error raised when an unsatisfiable range is requested.(t__name__t __module__t__doc__(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRstHTTPRangeHandlercBs eZdZd„Zd„ZRS(s™Handler that enables HTTP Range headers. This was extremely simple. The Range header is a HTTP feature to begin with so all this class does is tell urllib2 that the "206 Partial Content" response from the HTTP server is what we expected. Example: import urllib2 import byterange range_handler = range.HTTPRangeHandler() opener = urllib2.build_opener(range_handler) # install it urllib2.install_opener(opener) # create Request and set Range header req = urllib2.Request('http://www.python.org/') req.header['Range'] = 'bytes=30-50' f = urllib2.urlopen(req) cCs1tj|||jƒƒ}||_||_|S(N(turllibt addinfourlt get_full_urltcodetmsg(tselftreqtfpRR thdrstr((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pythttp_error_2066s  cCstdƒ‚dS(NsRequested Range Not Satisfiable(R(R R R RR R ((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pythttp_error_416=s(RRRRR(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRs tRangeableFileObjectcBsheZdZd„Zd„Zd„Zdd„Zdd„Zdd„Zd „Z d „Z d „Z RS( sFile object wrapper to enable raw range handling. This was implemented primarily for handling range specifications for file:// urls. This object effectively makes a file object look like it consists only of a range of bytes in the stream. Examples: # expose 10 bytes, starting at byte position 20, from # /etc/aliases. >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30)) # seek seeks within the range (to position 23 in this case) >>> fo.seek(3) # tell tells where your at _within the range_ (position 3 in # this case) >>> fo.tell() # read EOFs if an attempt is made to read past the last # byte in the range. the following will return only 7 bytes. >>> fo.read(30) cCs>||_t|ƒ\|_|_d|_|j|jƒdS(s}Create a RangeableFileObject. fo -- a file like object. only the read() method need be supported but supporting an optimized seek() is preferable. rangetup -- a (firstbyte,lastbyte) tuple specifying the range to work over. The file object provided is assumed to be at byte offset 0. iN(tfotrange_tuple_normalizet firstbytetlastbytetrealpost_do_seek(R Rtrangetup((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyt__init__Vs  cCst|j|ƒS(s«This effectively allows us to wrap at the instance level. Any attribute not found in _this_ object will be searched for in self.fo. This includes methods.(tgetattrR(R tname((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyt __getattr__dscCs|j|jS(s4Return the position within the range. This is different from fo.seek in that position 0 is the first byte position of the range tuple. For example, if this object was created with a range tuple of (500,899), tell() will return 0 when at byte position 500 of the file. (RR(R ((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyttelljsicCs¡|dkst‚|dkr.|j|}n7|dkrJ|j|}n|dkretdƒ‚n|jr‰||jkr‰|j}n|j||jƒdS(seSeek within the byte range. Positioning is identical to that described under tell(). iiis$seek from end of file not supported.N(iii(tAssertionErrorRRtIOErrorRR(R toffsettwhencet realoffset((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pytseekss    iÿÿÿÿcCs:|j|ƒ}|jj|ƒ}|jt|ƒ7_|S(s`Read within the range. This method will limit the size read based on the range. (t_calc_read_sizeRtreadRtlen(R tsizetrslt((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR%†scCs:|j|ƒ}|jj|ƒ}|jt|ƒ7_|S(sfRead lines within the range. This method will limit the size read based on the range. (R$RtreadlineRR&(R R'R(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR)scCsX|jrT|dkrA|j||jkrQ|j|j}qQqT|j|j}n|S(sSHandles calculating the amount of data to read based on the range. iÿÿÿÿ(RR(R R'((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR$˜s   cCsN|dkst‚t|jd|jƒ}||j|ƒ|j|7_dS(sSeek based on whether wrapped object supports seek(). offset is relative to the current position (self.realpos). iR#N(RRRt_poor_mans_seekR(R R R#((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR¤scCs}d}d}xj||krx|||kr8||}n|jj|ƒ}t|ƒ|krktdƒ‚n||7}qWdS(s®Seek by calling the wrapped file objects read() method. This is used for file like objects that do not have native seek support. The wrapped objects read() method is called to manually seek to the desired position. offset -- read this number of bytes from the wrapped file object. raise RangeError if we encounter EOF before reaching the specified offset. iisRequested Range Not SatisfiableN(RR%R&R(R R tpostbufsizetbuf((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR*­s  ( RRRRRRR#R%R)R$RR*(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRAs    tFileRangeHandlercBseZdZd„ZRS(s~FileHandler subclass that adds Range support. This class handles Range headers exactly like an HTTP server would. c CsÏddl}ddl}|jƒ}|jƒ}tj|ƒ}tj|ƒ}|tj}|j j |tj ƒ} |j |ƒd} |rØtj |ƒ\}} | sÃtj|ƒ|jƒkrØtjdƒ‚qØnt|dƒ} |jjddƒ} t| ƒ} | d kst‚| r–| \}}|dkrA|}n|dkse||kse||krttdƒ‚n||}t| ||fƒ} n|jd| p¨d || fƒ}tj| |d |ƒS( Niÿÿÿÿisfile not on local hosttrbtRangetsRequested Range Not Satisfiables6Content-Type: %s Content-Length: %d Last-Modified: %s s text/plainsfile:((t mimetypestemailtget_hostt get_selectorRt url2pathnametoststattST_SIZEtUtilst formatdatetST_MTIMEt guess_typet splitporttsockett gethostbynamet get_namesturllib2tURLErrortopentheaderstgettNonetrange_header_to_tupleRRRtmessage_from_stringR(R R R2R3thosttfilet localfiletstatsR'tmodifiedtmtypetportRtbrangetfbtlbRE((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pytopen_local_fileÆs:     !    $ (RRRRT(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR.Ás(R>t splitusert splitpasswdt splitattrtunquotet addclosehookRtFTPRangeHandlercBseZd„Zd„ZRS(cCsŸ|jƒ}|s$tddƒ‚nt|ƒ\}}|dkrNtj}n t|ƒ}t|ƒ\}}|r‡t|ƒ\}}nd}t |ƒ}t |p¥dƒ}t |p·dƒ}yt j |ƒ}Wn%t j k r÷}t j|ƒ‚nXt|jƒƒ\}}|jdƒ} tt | ƒ} | d | d} } | ra| d ra| d} ny|j||||| ƒ} | r‹dpŽd } xM|D]E} t| ƒ\} }| jƒd kr˜|dkr˜|jƒ} q˜q˜Wd}t|jjddƒƒ}|dkst‚|r>|\}}|dkr>|}q>n| j| | |ƒ\}}|rî|\}}|dkrÌ|dks|dkržtdƒ‚n|}||}|dkrëtdƒ‚qëqî||}t|d|fƒ}nd}tj|jƒƒd}|r$|d|7}n|dk rM|dkrM|d|7}nt j!|ƒ}t"|||jƒƒSWn%tj#k rš}td|ƒ‚nXdS(Ns ftp errors no host givenR1t/iÿÿÿÿiitItDttypetatAtitdR0s@Requested Range Not Satisfiable due to unobtainable file length.sRequested Range Not SatisfiablesContent-Type: %s sContent-Length: %d (R_R`RaR\RbR](($R4RR>RGtftplibtFTP_PORTtintRURVRXR?R@terrorRBRCRWR5tsplittmapt connect_ftptlowertupperRHRERFRtretrfileRRR2R=RR3RIRt all_errors(R R RJRPtusertpasswdR tpathtattrstdirsRKtfwR^tattrtvaluetrestt range_tupRRRSR tretrlenRERO((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pytftp_openõsz                cCst|||||ƒ}|S(N(t ftpwrapper(R RnRoRJRPRrRs((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRiDs(RRRyRi(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRZôs ORzcBseZdd„ZRS(c Csÿ|jƒ|dkr%d}d}nd|}d}y|jj|ƒWn.tjk ry|jƒ|jj|ƒnXd}|r‹| r‹y|jj|ƒWn%tjk rÈ}t d|ƒ‚nX|jj|ƒy#d|}|jj ||ƒ}Wq‹tjk r‡}t |ƒj d ƒr]|j ||ƒ\}} t||d fƒ}|| fSt |ƒj d ƒsˆt d|ƒ‚qˆq‹Xn|sÏ|jjdƒ|r´d |}nd }|jj |ƒ}nd|_t|djdƒ|jƒ|dfS(NRbR]sTYPE AisTYPE is ftp errorsRETR t501R1t550sLIST tLISTR/(RbR](t endtransfertftptvoidcmdRcRmtinitRGtnlstt error_permRt ntransfercmdtstrt startswithRlRtbusyRYtmakefile( R RKR^RvtcmdtisdirtconntreasonR Rx((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRlMsJ          N(RRRGRl(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRzHscCsš|dkrdStdkr:ddl}|jdƒantj|ƒ}|r–t|jddƒƒ}|r’|dr’|d|ddf}n|SdS(sËGet a (firstbyte,lastbyte) tuple from a Range header value. Range headers have the form "bytes=-". This function pulls the firstbyte and lastbyte values and returns a (firstbyte,lastbyte) tuple. If lastbyte is not specified in the header value, it is returned as an empty string in the tuple. Return None if range_header is None Return () if range_header does not conform to the range spec pattern. iÿÿÿÿNs^bytes=(\d{1,})-(\d*)iii((RGt_rangeretretcompiletmatchRtgroup(t range_headerRŽRttup((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyRHƒs   cCsS|dkrdSt|ƒ}|rO|drG|d|ddf}nd|SdS(s•Convert a range tuple to a Range header value. Return a string of the form "bytes=-" or None if no range is needed. iis bytes=%s-%sN(RGR(Rw((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pytrange_tuple_to_headerŸs   cCsØ|dkrdS|d}|dkr/d}n t|ƒ}y|d}Wntk rbd}n1X|dkrxd}n|dkr“t|ƒ}n||fdkr©dS||krÎtd||fƒ‚n||fS(s6Normalize a (first_byte,last_byte) range tuple. Return a tuple whose first element is guaranteed to be an int and whose second element will be '' (meaning: the last byte) or an int. Finally, return None if the normalized tuple == (0,'') as that is equivalent to retrieving the entire file. iR1isInvalid byte range: %s-%sN(NR1(iR1(RGRet IndexErrorR(RwRRRS((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyR¬s&           ( R7R8RRBt email.UtilsR3RRt BaseHandlerRtobjectRt FileHandlerR.R>RURVRWRXRYRRcR?R2t FTPHandlerRZRzRGRRHR”R(((s7/sys/lib/python2.7/site-packages/mercurial/byterange.pyts&     #€,4    T: