76 {
77
78 if (is_writeable($this->filename) && is_file($this->filename) && ($fp_source = fopen($this->filename, 'r+b'))) {
79
80
81 $getID3 = new GetId3Core();
82 $OldThisFileInfo = $getID3->analyze($this->filename);
83 if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) {
84 $this->errors[] = 'Cannot write Real tags on old-style file format';
85 fclose($fp_source);
86
87 return false;
88 }
89
90 if (empty($OldThisFileInfo['real']['chunks'])) {
91 $this->errors[] = 'Cannot write Real tags because cannot find DATA chunk in file';
92 fclose($fp_source);
93
94 return false;
95 }
96 foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) {
97 $oldChunkInfo[$chunkarray['name']] = $chunkarray;
98 }
99 if (!empty($oldChunkInfo['CONT']['length'])) {
100 $this->paddedlength = max($oldChunkInfo['CONT']['length'], $this->paddedlength);
101 }
102
104 $new_PROP_tag_data = $this->
GeneratePROPchunk($OldThisFileInfo[
'real'][
'chunks'], $new_CONT_tag_data);
105 $new__RMF_tag_data = $this->
GenerateRMFchunk($OldThisFileInfo[
'real'][
'chunks']);
106
107 if (isset($oldChunkInfo['.RMF']['length']) && ($oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data))) {
108 fseek($fp_source, $oldChunkInfo['.RMF']['offset'], SEEK_SET);
109 fwrite($fp_source, $new__RMF_tag_data);
110 } else {
111 $this->errors[] = 'new .RMF tag ('.strlen($new__RMF_tag_data).' bytes) different length than old .RMF tag ('.$oldChunkInfo['.RMF']['length'].' bytes)';
112 fclose($fp_source);
113
114 return false;
115 }
116
117 if (isset($oldChunkInfo['PROP']['length']) && ($oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data))) {
118 fseek($fp_source, $oldChunkInfo['PROP']['offset'], SEEK_SET);
119 fwrite($fp_source, $new_PROP_tag_data);
120 } else {
121 $this->errors[] = 'new PROP tag ('.strlen($new_PROP_tag_data).' bytes) different length than old PROP tag ('.$oldChunkInfo['PROP']['length'].' bytes)';
122 fclose($fp_source);
123
124 return false;
125 }
126
127 if (isset($oldChunkInfo['CONT']['length']) && ($oldChunkInfo['CONT']['length'] == strlen($new_CONT_tag_data))) {
128
129
130 fseek($fp_source, $oldChunkInfo['CONT']['offset'], SEEK_SET);
131 fwrite($fp_source, $new_CONT_tag_data);
132 fclose($fp_source);
133
134 return true;
135
136 } else {
137
138 if (empty($oldChunkInfo['CONT'])) {
139
140 $BeforeOffset = $oldChunkInfo['DATA']['offset'];
141 $AfterOffset = $oldChunkInfo['DATA']['offset'];
142 } else {
143
144 $BeforeOffset = $oldChunkInfo['CONT']['offset'];
145 $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length'];
146 }
148 if (is_writable($tempfilename) && is_file($tempfilename) && ($fp_temp = fopen($tempfilename, 'wb'))) {
149
150 rewind($fp_source);
151 fwrite($fp_temp, fread($fp_source, $BeforeOffset));
152 fwrite($fp_temp, $new_CONT_tag_data);
153 fseek($fp_source, $AfterOffset, SEEK_SET);
154 while ($buffer = fread($fp_source, $this->fread_buffer_size)) {
155 fwrite($fp_temp, $buffer, strlen($buffer));
156 }
157 fclose($fp_temp);
158
159 if (copy($tempfilename, $this->filename)) {
160 unlink($tempfilename);
161 fclose($fp_source);
162
163 return true;
164 }
165 unlink($tempfilename);
166 $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.')';
167
168 } else {
169 $this->errors[] = 'Could not fopen("'.$tempfilename.'", "wb")';
170 }
171 }
172 fclose($fp_source);
173
174 return false;
175
176 }
177
178 }
179 $this->errors[] = 'Could not fopen("'.$this->filename.'", "r+b")';
180
181 return false;
182 }
GenerateRMFchunk(&$chunks)
GeneratePROPchunk(&$chunks, &$new_CONT_tag_data)