⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 member.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 2 页
字号:
}# Note, this isn't exactly UTC 1980, it's 1980 + 12 hours and 1# minute so that nothing timezoney can muck us up.my $safe_epoch = 315576060;# convert a unix time to DOS date/time# NOT AN OBJECT METHOD!sub _unixToDosTime {    my $time_t = shift;    unless ($time_t) {        _error("Tried to add member with zero or undef value for time");        $time_t = $safe_epoch;    }    if ( $time_t < $safe_epoch ) {        _ioError("Unsupported date before 1980 encountered, moving to 1980");        $time_t = $safe_epoch;    }    my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime($time_t);    my $dt = 0;    $dt += ( $sec >> 1 );    $dt += ( $min << 5 );    $dt += ( $hour << 11 );    $dt += ( $mday << 16 );    $dt += ( ( $mon + 1 ) << 21 );    $dt += ( ( $year - 80 ) << 25 );    return $dt;}# Write my local header to a file handle.# Stores the offset to the start of the header in my# writeLocalHeaderRelativeOffset member.# Returns AZ_OK on success.sub _writeLocalFileHeader {    my $self = shift;    my $fh   = shift;    my $signatureData = pack( SIGNATURE_FORMAT, LOCAL_FILE_HEADER_SIGNATURE );    $fh->print($signatureData)      or return _ioError("writing local header signature");    my $header = pack(        LOCAL_FILE_HEADER_FORMAT,        $self->versionNeededToExtract(),        $self->bitFlag(),        $self->desiredCompressionMethod(),        $self->lastModFileDateTime(),        $self->crc32(),        $self->compressedSize(),    # may need to be re-written later        $self->uncompressedSize(),        length( $self->fileName() ),        length( $self->localExtraField() )    );    $fh->print($header) or return _ioError("writing local header");    if ( $self->fileName() ) {        $fh->print( $self->fileName() )          or return _ioError("writing local header filename");    }    if ( $self->localExtraField() ) {        $fh->print( $self->localExtraField() )          or return _ioError("writing local extra field");    }    return AZ_OK;}sub _writeCentralDirectoryFileHeader {    my $self = shift;    my $fh   = shift;    my $sigData =      pack( SIGNATURE_FORMAT, CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE );    $fh->print($sigData)      or return _ioError("writing central directory header signature");    my $fileNameLength    = length( $self->fileName() );    my $extraFieldLength  = length( $self->cdExtraField() );    my $fileCommentLength = length( $self->fileComment() );    my $header = pack(        CENTRAL_DIRECTORY_FILE_HEADER_FORMAT,        $self->versionMadeBy(),        $self->fileAttributeFormat(),        $self->versionNeededToExtract(),        $self->bitFlag(),        $self->desiredCompressionMethod(),        $self->lastModFileDateTime(),        $self->crc32(),            # these three fields should have been updated        $self->_writeOffset(),     # by writing the data stream out        $self->uncompressedSize(), #        $fileNameLength,        $extraFieldLength,        $fileCommentLength,        0,                         # {'diskNumberStart'},        $self->internalFileAttributes(),        $self->externalFileAttributes(),        $self->writeLocalHeaderRelativeOffset()    );    $fh->print($header)      or return _ioError("writing central directory header");    if ($fileNameLength) {        $fh->print( $self->fileName() )          or return _ioError("writing central directory header signature");    }    if ($extraFieldLength) {        $fh->print( $self->cdExtraField() )          or return _ioError("writing central directory extra field");    }    if ($fileCommentLength) {        $fh->print( $self->fileComment() )          or return _ioError("writing central directory file comment");    }    return AZ_OK;}# This writes a data descriptor to the given file handle.# Assumes that crc32, writeOffset, and uncompressedSize are# set correctly (they should be after a write).# Further, the local file header should have the# GPBF_HAS_DATA_DESCRIPTOR_MASK bit set.sub _writeDataDescriptor {    my $self   = shift;    my $fh     = shift;    my $header = pack(        SIGNATURE_FORMAT . DATA_DESCRIPTOR_FORMAT,        DATA_DESCRIPTOR_SIGNATURE,        $self->crc32(),        $self->_writeOffset(),    # compressed size        $self->uncompressedSize()    );    $fh->print($header)      or return _ioError("writing data descriptor");    return AZ_OK;}# Re-writes the local file header with new crc32 and compressedSize fields.# To be called after writing the data stream.# Assumes that filename and extraField sizes didn't change since last written.sub _refreshLocalFileHeader {    my $self = shift;    my $fh   = shift;    my $here = $fh->tell();    $fh->seek( $self->writeLocalHeaderRelativeOffset() + SIGNATURE_LENGTH,        IO::Seekable::SEEK_SET )      or return _ioError("seeking to rewrite local header");    my $header = pack(        LOCAL_FILE_HEADER_FORMAT,        $self->versionNeededToExtract(),        $self->bitFlag(),        $self->desiredCompressionMethod(),        $self->lastModFileDateTime(),        $self->crc32(),        $self->_writeOffset(),    # compressed size        $self->uncompressedSize(),        length( $self->fileName() ),        length( $self->localExtraField() )    );    $fh->print($header)      or return _ioError("re-writing local header");    $fh->seek( $here, IO::Seekable::SEEK_SET )      or return _ioError("seeking after rewrite of local header");    return AZ_OK;}sub readChunk {    my ( $self, $chunkSize ) = @_;    if ( $self->readIsDone() ) {        $self->endRead();        my $dummy = '';        return ( \$dummy, AZ_STREAM_END );    }    $chunkSize = $Archive::Zip::ChunkSize if not defined($chunkSize);    $chunkSize = $self->_readDataRemaining()      if $chunkSize > $self->_readDataRemaining();    my $buffer = '';    my $outputRef;    my ( $bytesRead, $status ) = $self->_readRawChunk( \$buffer, $chunkSize );    return ( \$buffer, $status ) unless $status == AZ_OK;    $self->{'readDataRemaining'} -= $bytesRead;    $self->{'readOffset'} += $bytesRead;    if ( $self->compressionMethod() == COMPRESSION_STORED ) {        $self->{'crc32'} = $self->computeCRC32( $buffer, $self->{'crc32'} );    }    ( $outputRef, $status ) = &{ $self->{'chunkHandler'} }( $self, \$buffer );    $self->{'writeOffset'} += length($$outputRef);    $self->endRead()      if $self->readIsDone();    return ( $outputRef, $status );}# Read the next raw chunk of my data. Subclasses MUST implement.#	my ( $bytesRead, $status) = $self->_readRawChunk( \$buffer, $chunkSize );sub _readRawChunk {    my $self = shift;    return $self->_subclassResponsibility();}# A place holder to catch rewindData errors if someone ignores# the error code.sub _noChunk {    my $self = shift;    return ( \undef, _error("trying to copy chunk when init failed") );}# Basically a no-op so that I can have a consistent interface.# ( $outputRef, $status) = $self->_copyChunk( \$buffer );sub _copyChunk {    my ( $self, $dataRef ) = @_;    return ( $dataRef, AZ_OK );}# ( $outputRef, $status) = $self->_deflateChunk( \$buffer );sub _deflateChunk {    my ( $self, $buffer ) = @_;    my ( $out,  $status ) = $self->_deflater()->deflate($buffer);    if ( $self->_readDataRemaining() == 0 ) {        my $extraOutput;        ( $extraOutput, $status ) = $self->_deflater()->flush();        $out .= $extraOutput;        $self->endRead();        return ( \$out, AZ_STREAM_END );    }    elsif ( $status == Z_OK ) {        return ( \$out, AZ_OK );    }    else {        $self->endRead();        my $retval = _error( 'deflate error', $status );        my $dummy = '';        return ( \$dummy, $retval );    }}# ( $outputRef, $status) = $self->_inflateChunk( \$buffer );sub _inflateChunk {    my ( $self, $buffer ) = @_;    my ( $out,  $status ) = $self->_inflater()->inflate($buffer);    my $retval;    $self->endRead() unless $status == Z_OK;    if ( $status == Z_OK || $status == Z_STREAM_END ) {        $retval = ( $status == Z_STREAM_END ) ? AZ_STREAM_END: AZ_OK;        return ( \$out, $retval );    }    else {        $retval = _error( 'inflate error', $status );        my $dummy = '';        return ( \$dummy, $retval );    }}sub rewindData {    my $self = shift;    my $status;    # set to trap init errors    $self->{'chunkHandler'} = $self->can('_noChunk');    # Work around WinZip bug with 0-length DEFLATED files    $self->desiredCompressionMethod(COMPRESSION_STORED)      if $self->uncompressedSize() == 0;    # assume that we're going to read the whole file, and compute the CRC anew.    $self->{'crc32'} = 0      if ( $self->compressionMethod() == COMPRESSION_STORED );    # These are the only combinations of methods we deal with right now.    if (    $self->compressionMethod() == COMPRESSION_STORED        and $self->desiredCompressionMethod() == COMPRESSION_DEFLATED )    {        ( $self->{'deflater'}, $status ) = Compress::Zlib::deflateInit(            '-Level'      => $self->desiredCompressionLevel(),            '-WindowBits' => -MAX_WBITS(),                     # necessary magic            '-Bufsize'    => $Archive::Zip::ChunkSize,            @_        );    # pass additional options        return _error( 'deflateInit error:', $status )          unless $status == Z_OK;        $self->{'chunkHandler'} = $self->can('_deflateChunk');    }    elsif ( $self->compressionMethod() == COMPRESSION_DEFLATED        and $self->desiredCompressionMethod() == COMPRESSION_STORED )    {        ( $self->{'inflater'}, $status ) = Compress::Zlib::inflateInit(            '-WindowBits' => -MAX_WBITS(),               # necessary magic            '-Bufsize'    => $Archive::Zip::ChunkSize,            @_        );    # pass additional options        return _error( 'inflateInit error:', $status )          unless $status == Z_OK;        $self->{'chunkHandler'} = $self->can('_inflateChunk');    }    elsif ( $self->compressionMethod() == $self->desiredCompressionMethod() ) {        $self->{'chunkHandler'} = $self->can('_copyChunk');    }    else {        return _error(            sprintf(                "Unsupported compression combination: read %d, write %d",                $self->compressionMethod(),                $self->desiredCompressionMethod()            )        );    }    $self->{'readDataRemaining'} =      ( $self->compressionMethod() == COMPRESSION_STORED )      ? $self->uncompressedSize()      : $self->compressedSize();    $self->{'dataEnded'}  = 0;    $self->{'readOffset'} = 0;    return AZ_OK;}sub endRead {    my $self = shift;    delete $self->{'inflater'};    delete $self->{'deflater'};    $self->{'dataEnded'}         = 1;    $self->{'readDataRemaining'} = 0;    return AZ_OK;}sub readIsDone {    my $self = shift;    return ( $self->_dataEnded() or !$self->_readDataRemaining() );}sub contents {    my $self        = shift;    my $newContents = shift;    if ( defined($newContents) ) {        # change our type and call the subclass contents method.        $self->_become(STRINGMEMBERCLASS);        return $self->contents( pack( 'C0a*', $newContents ) )          ;    # in case of Unicode    }    else {        my $oldCompression =          $self->desiredCompressionMethod(COMPRESSION_STORED);        my $status = $self->rewindData(@_);        if ( $status != AZ_OK ) {            $self->endRead();            return $status;        }        my $retval = '';        while ( $status == AZ_OK ) {            my $ref;            ( $ref, $status ) = $self->readChunk( $self->_readDataRemaining() );            # did we get it in one chunk?            if ( length($$ref) == $self->uncompressedSize() ) {                $retval = $$ref;            }            else { $retval .= $$ref }        }        $self->desiredCompressionMethod($oldCompression);        $self->endRead();        $status = AZ_OK if $status == AZ_STREAM_END;        $retval = undef unless $status == AZ_OK;        return wantarray ? ( $retval, $status ) : $retval;    }}sub extractToFileHandle {    my $self = shift;    return _error("encryption unsupported") if $self->isEncrypted();    my $fh = shift;    _binmode($fh);    my $oldCompression = $self->desiredCompressionMethod(COMPRESSION_STORED);    my $status         = $self->rewindData(@_);    $status = $self->_writeData($fh) if $status == AZ_OK;    $self->desiredCompressionMethod($oldCompression);    $self->endRead();    return $status;}# write local header and data stream to file handlesub _writeToFileHandle {    my $self         = shift;    my $fh           = shift;    my $fhIsSeekable = shift;    my $offset       = shift;    return _error("no member name given for $self")      unless $self->fileName();    $self->{'writeLocalHeaderRelativeOffset'} = $offset;    $self->{'wasWritten'}                     = 0;    # Determine if I need to write a data descriptor    # I need to do this if I can't refresh the header    # and I don't know compressed size or crc32 fields.    my $headerFieldsUnknown = (        ( $self->uncompressedSize() > 0 )          and ($self->compressionMethod() == COMPRESSION_STORED            or $self->desiredCompressionMethod() == COMPRESSION_DEFLATED )    );    my $shouldWriteDataDescriptor =      ( $headerFieldsUnknown and not $fhIsSeekable );    $self->hasDataDescriptor(1)      if ($shouldWriteDataDescriptor);    $self->{'writeOffset'} = 0;    my $status = $self->rewindData();    ( $status = $self->_writeLocalFileHeader($fh) )      if $status == AZ_OK;    ( $status = $self->_writeData($fh) )      if $status == AZ_OK;    if ( $status == AZ_OK ) {        $self->{'wasWritten'} = 1;        if ( $self->hasDataDescriptor() ) {            $status = $self->_writeDataDescriptor($fh);        }        elsif ($headerFieldsUnknown) {            $status = $self->_refreshLocalFileHeader($fh);        }    }    return $status;}# Copy my (possibly compressed) data to given file handle.# Returns C<AZ_OK> on successsub _writeData {    my $self    = shift;    my $writeFh = shift;    return AZ_OK if ( $self->uncompressedSize() == 0 );    my $status;    my $chunkSize = $Archive::Zip::ChunkSize;    while ( $self->_readDataRemaining() > 0 ) {        my $outRef;        ( $outRef, $status ) = $self->readChunk($chunkSize);        return $status if ( $status != AZ_OK and $status != AZ_STREAM_END );        if ( length($$outRef) > 0 ) {            $writeFh->print($$outRef)              or return _ioError("write error during copy");        }        last if $status == AZ_STREAM_END;    }    $self->{'compressedSize'} = $self->_writeOffset();    return AZ_OK;}# Return true if I depend on the named filesub _usesFileNamed {    return 0;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -