Public Member Functions | Data Fields

getid3_write_real Class Reference

getID3() by James Heinrich <info@getid3.org> // More...

Public Member Functions

 getid3_write_real ()
 WriteReal ()
 GenerateRMFchunk (&$chunks)
 GeneratePROPchunk (&$chunks, &$new_CONT_tag_data)
 GenerateCONTchunk ()
 RemoveReal ()

Data Fields

 $filename
 $tag_data = array()
 $warnings = array()
 $errors = array()
 $paddedlength = 512

Detailed Description

getID3() by James Heinrich <info@getid3.org> //

Definition at line 16 of file write.real.php.


Member Function Documentation

getid3_write_real::GenerateCONTchunk (  ) 

Definition at line 193 of file write.real.php.

References getid3_lib::BigEndian2String().

Referenced by WriteReal().

                                     {
                foreach ($this->tag_data as $key => $value) {
                        // limit each value to 0xFFFF bytes
                        $this->tag_data[$key] = substr($value, 0, 65535);
                }

                $CONTchunk  = "\x00\x00"; // object version

                $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['title']), 2);
                $CONTchunk .= @$this->tag_data['title'];

                $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['artist']), 2);
                $CONTchunk .= @$this->tag_data['artist'];

                $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['copyright']), 2);
                $CONTchunk .= @$this->tag_data['copyright'];

                $CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['comment']), 2);
                $CONTchunk .= @$this->tag_data['comment'];

                if ($this->paddedlength > (strlen($CONTchunk) + 8)) {
                        $CONTchunk .= str_repeat("\x00", $this->paddedlength - strlen($CONTchunk) - 8);
                }

                $CONTchunk  = 'CONT'.getid3_lib::BigEndian2String(strlen($CONTchunk) + 8, 4).$CONTchunk; // CONT chunk identifier + chunk length

                return $CONTchunk;
        }

Here is the call graph for this function:

Here is the caller graph for this function:

getid3_write_real::GeneratePROPchunk ( &$  chunks,
&$  new_CONT_tag_data 
)

Definition at line 156 of file write.real.php.

References getid3_lib::BigEndian2String().

Referenced by WriteReal().

                                                                  {
                $old_CONT_length = 0;
                $old_DATA_offset = 0;
                $old_INDX_offset = 0;
                foreach ($chunks as $key => $chunk) {
                        $chunkNameKeys[$chunk['name']] = $key;
                        if ($chunk['name'] == 'CONT') {
                                $old_CONT_length = $chunk['length'];
                        } elseif ($chunk['name'] == 'DATA') {
                                if (!$old_DATA_offset) {
                                        $old_DATA_offset = $chunk['offset'];
                                }
                        } elseif ($chunk['name'] == 'INDX') {
                                if (!$old_INDX_offset) {
                                        $old_INDX_offset = $chunk['offset'];
                                }
                        }
                }
                $CONTdelta = strlen($new_CONT_tag_data) - $old_CONT_length;

                $PROPchunk  = "\x00\x00"; // object version
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_bit_rate'],    4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_bit_rate'],    4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_packet_size'], 4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_packet_size'], 4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_packets'],     4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['duration'],        4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['preroll'],         4);
                $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_INDX_offset + $CONTdelta),              4);
                $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_DATA_offset + $CONTdelta),              4);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_streams'],     2);
                $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['flags_raw'],       2);

                $PROPchunk  = 'PROP'.getid3_lib::BigEndian2String(strlen($PROPchunk) + 8, 4).$PROPchunk; // PROP chunk identifier + chunk length
                return $PROPchunk;
        }

Here is the call graph for this function:

Here is the caller graph for this function:

getid3_write_real::GenerateRMFchunk ( &$  chunks  ) 

Definition at line 138 of file write.real.php.

References getid3_lib::BigEndian2String().

Referenced by WriteReal().

                                            {
                $oldCONTexists = false;
                foreach ($chunks as $key => $chunk) {
                        $chunkNameKeys[$chunk['name']] = $key;
                        if ($chunk['name'] == 'CONT') {
                                $oldCONTexists = true;
                        }
                }
                $newHeadersCount = $chunks[$chunkNameKeys['.RMF']]['headers_count'] + ($oldCONTexists ? 0 : 1);

                $RMFchunk  = "\x00\x00"; // object version
                $RMFchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['.RMF']]['file_version'], 4);
                $RMFchunk .= getid3_lib::BigEndian2String($newHeadersCount,                                4);

                $RMFchunk  = '.RMF'.getid3_lib::BigEndian2String(strlen($RMFchunk) + 8, 4).$RMFchunk; // .RMF chunk identifier + chunk length
                return $RMFchunk;
        }

Here is the call graph for this function:

Here is the caller graph for this function:

getid3_write_real::getid3_write_real (  ) 

Definition at line 24 of file write.real.php.

                                     {
                return true;
        }

getid3_write_real::RemoveReal (  ) 

Definition at line 222 of file write.real.php.

                              {
                // File MUST be writeable - CHMOD(646) at least
                if (is_writeable($this->filename)) {
                        if ($fp_source = @fopen($this->filename, 'r+b')) {

                                // Initialize getID3 engine
                                $getID3 = new getID3;
                                $OldThisFileInfo = $getID3->analyze($this->filename);
                                if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) {
                                        $this->errors[] = 'Cannot remove Real tags from old-style file format';
                                        fclose($fp_source);
                                        return false;
                                }

                                if (empty($OldThisFileInfo['real']['chunks'])) {
                                        $this->errors[] = 'Cannot remove Real tags because cannot find DATA chunk in file';
                                        fclose($fp_source);
                                        return false;
                                }
                                foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) {
                                        $oldChunkInfo[$chunkarray['name']] = $chunkarray;
                                }

                                if (empty($oldChunkInfo['CONT'])) {
                                        // no existing CONT chunk
                                        fclose($fp_source);
                                        return true;
                                }

                                $BeforeOffset = $oldChunkInfo['CONT']['offset'];
                                $AfterOffset  = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length'];
                                if ($tempfilename = tempnam('*', 'getID3')) {
                                        ob_start();
                                        if ($fp_temp = fopen($tempfilename, 'wb')) {

                                                rewind($fp_source);
                                                fwrite($fp_temp, fread($fp_source, $BeforeOffset));
                                                fseek($fp_source, $AfterOffset, SEEK_SET);
                                                while ($buffer = fread($fp_source, GETID3_FREAD_BUFFER_SIZE)) {
                                                        fwrite($fp_temp, $buffer, strlen($buffer));
                                                }
                                                fclose($fp_temp);

                                                if (copy($tempfilename, $this->filename)) {
                                                        unlink($tempfilename);
                                                        fclose($fp_source);
                                                        return true;
                                                }
                                                unlink($tempfilename);
                                                $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.') - '.strip_tags(ob_get_contents());

                                        } else {

                                                $this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents());

                                        }
                                        ob_end_clean();
                                }
                                fclose($fp_source);
                                return false;


                        } else {
                                $this->errors[] = 'Could not open '.$this->filename.' mode "r+b"';
                                return false;
                        }
                }
                $this->errors[] = 'File is not writeable: '.$this->filename;
                return false;
        }

getid3_write_real::WriteReal (  ) 

Definition at line 28 of file write.real.php.

References GenerateCONTchunk(), GeneratePROPchunk(), and GenerateRMFchunk().

                             {
                // File MUST be writeable - CHMOD(646) at least
                if (is_writeable($this->filename)) {
                        if ($fp_source = @fopen($this->filename, 'r+b')) {

                                // Initialize getID3 engine
                                $getID3 = new getID3;
                                $OldThisFileInfo = $getID3->analyze($this->filename);
                                if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) {
                                        $this->errors[] = 'Cannot write Real tags on old-style file format';
                                        fclose($fp_source);
                                        return false;
                                }

                                if (empty($OldThisFileInfo['real']['chunks'])) {
                                        $this->errors[] = 'Cannot write Real tags because cannot find DATA chunk in file';
                                        fclose($fp_source);
                                        return false;
                                }
                                foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) {
                                        $oldChunkInfo[$chunkarray['name']] = $chunkarray;
                                }
                                if (!empty($oldChunkInfo['CONT']['length'])) {
                                        $this->paddedlength = max($oldChunkInfo['CONT']['length'], $this->paddedlength);
                                }

                                $new_CONT_tag_data = $this->GenerateCONTchunk();
                                $new_PROP_tag_data = $this->GeneratePROPchunk($OldThisFileInfo['real']['chunks'], $new_CONT_tag_data);
                                $new__RMF_tag_data = $this->GenerateRMFchunk($OldThisFileInfo['real']['chunks']);

                                if (@$oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data)) {
                                        fseek($fp_source, $oldChunkInfo['.RMF']['offset'], SEEK_SET);
                                        fwrite($fp_source, $new__RMF_tag_data);
                                } else {
                                        $this->errors[] = 'new .RMF tag ('.strlen($new__RMF_tag_data).' bytes) different length than old .RMF tag ('.$oldChunkInfo['.RMF']['length'].' bytes)';
                                        fclose($fp_source);
                                        return false;
                                }

                                if (@$oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data)) {
                                        fseek($fp_source, $oldChunkInfo['PROP']['offset'], SEEK_SET);
                                        fwrite($fp_source, $new_PROP_tag_data);
                                } else {
                                        $this->errors[] = 'new PROP tag ('.strlen($new_PROP_tag_data).' bytes) different length than old PROP tag ('.$oldChunkInfo['PROP']['length'].' bytes)';
                                        fclose($fp_source);
                                        return false;
                                }

                                if (@$oldChunkInfo['CONT']['length'] == strlen($new_CONT_tag_data)) {

                                        // new data length is same as old data length - just overwrite
                                        fseek($fp_source, $oldChunkInfo['CONT']['offset'], SEEK_SET);
                                        fwrite($fp_source, $new_CONT_tag_data);
                                        fclose($fp_source);
                                        return true;

                                } else {

                                        if (empty($oldChunkInfo['CONT'])) {
                                                // no existing CONT chunk
                                                $BeforeOffset = $oldChunkInfo['DATA']['offset'];
                                                $AfterOffset  = $oldChunkInfo['DATA']['offset'];
                                        } else {
                                                // new data is longer than old data
                                                $BeforeOffset = $oldChunkInfo['CONT']['offset'];
                                                $AfterOffset  = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length'];
                                        }
                                        if ($tempfilename = tempnam('*', 'getID3')) {
                                                ob_start();
                                                if ($fp_temp = fopen($tempfilename, 'wb')) {

                                                        rewind($fp_source);
                                                        fwrite($fp_temp, fread($fp_source, $BeforeOffset));
                                                        fwrite($fp_temp, $new_CONT_tag_data);
                                                        fseek($fp_source, $AfterOffset, SEEK_SET);
                                                        while ($buffer = fread($fp_source, GETID3_FREAD_BUFFER_SIZE)) {
                                                                fwrite($fp_temp, $buffer, strlen($buffer));
                                                        }
                                                        fclose($fp_temp);

                                                        if (copy($tempfilename, $this->filename)) {
                                                                unlink($tempfilename);
                                                                fclose($fp_source);
                                                                return true;
                                                        }
                                                        unlink($tempfilename);
                                                        $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.') - '.strip_tags(ob_get_contents());

                                                } else {

                                                        $this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents());

                                                }
                                                ob_end_clean();
                                        }
                                        fclose($fp_source);
                                        return false;

                                }


                        } else {
                                $this->errors[] = 'Could not open '.$this->filename.' mode "r+b"';
                                return false;
                        }
                }
                $this->errors[] = 'File is not writeable: '.$this->filename;
                return false;
        }

Here is the call graph for this function:


Field Documentation

getid3_write_real::$errors = array()

Definition at line 21 of file write.real.php.

getid3_write_real::$filename

Definition at line 18 of file write.real.php.

getid3_write_real::$paddedlength = 512

Definition at line 22 of file write.real.php.

getid3_write_real::$tag_data = array()

Definition at line 19 of file write.real.php.

getid3_write_real::$warnings = array()

Definition at line 20 of file write.real.php.


The documentation for this class was generated from the following file: