2007-03-29 22:34:40 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2012-04-18 16:51:48 +00:00
* Copyright ( C ) 2005 - 2012 , Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Michael Jerris < mike @ jerris . com >
* Paul D . Tinsley < pdt at jackhammer . org >
2009-07-10 17:18:02 +00:00
* John Wehle < john @ feith . com >
2007-03-29 22:34:40 +00:00
*
*
* switch_core_file . c - - Main Core Library ( File I / O Functions )
*
*/
2008-01-27 17:36:53 +00:00
2007-03-29 22:34:40 +00:00
# include <switch.h>
2007-05-14 17:10:46 +00:00
# include "private/switch_core_pvt.h"
2007-03-29 22:34:40 +00:00
2008-01-08 18:35:51 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_perform_file_open ( const char * file , const char * func , int line ,
switch_file_handle_t * fh ,
2008-05-27 04:30:03 +00:00
const char * file_path ,
uint8_t channels , uint32_t rate , unsigned int flags , switch_memory_pool_t * pool )
2007-03-29 22:34:40 +00:00
{
char * ext ;
switch_status_t status ;
char stream_name [ 128 ] = " " ;
char * rhs = NULL ;
2009-09-16 20:09:27 +00:00
const char * spool_path = NULL ;
2009-09-29 19:58:02 +00:00
int is_stream = 0 ;
2007-03-29 22:34:40 +00:00
2009-01-24 18:11:42 +00:00
if ( switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Handle already open \n " ) ;
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-11-10 23:50:58 +00:00
if ( ! fh - > samplerate ) {
if ( ! ( fh - > samplerate = rate ) ) {
fh - > samplerate = 8000 ;
}
}
2009-01-24 18:11:42 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( file_path ) ) {
2007-12-29 23:15:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Filename \n " ) ;
return SWITCH_STATUS_FALSE ;
}
2009-10-08 14:01:03 +00:00
fh - > flags = flags ;
2009-09-16 20:09:27 +00:00
if ( pool ) {
fh - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & fh - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
UNPROTECT_INTERFACE ( fh - > file_interface ) ;
return status ;
}
switch_set_flag ( fh , SWITCH_FILE_FLAG_FREE_POOL ) ;
}
2007-03-29 22:34:40 +00:00
if ( ( rhs = strstr ( file_path , SWITCH_URL_SEPARATOR ) ) ) {
switch_copy_string ( stream_name , file_path , ( rhs + 1 ) - file_path ) ;
ext = stream_name ;
file_path = rhs + 3 ;
2009-09-16 22:56:30 +00:00
fh - > file_path = switch_core_strdup ( fh - > memory_pool , file_path ) ;
2009-09-29 19:58:02 +00:00
is_stream = 1 ;
2007-03-29 22:34:40 +00:00
} else {
2009-09-16 22:56:30 +00:00
if ( ( flags & SWITCH_FILE_FLAG_WRITE ) ) {
char * p , * e ;
fh - > file_path = switch_core_strdup ( fh - > memory_pool , file_path ) ;
p = fh - > file_path ;
if ( * p = = ' [ ' & & * ( p + 1 ) = = * SWITCH_PATH_SEPARATOR ) {
e = switch_find_end_paren ( p , ' [ ' , ' ] ' ) ;
2010-02-06 03:38:24 +00:00
2009-09-16 22:56:30 +00:00
if ( e ) {
* e = ' \0 ' ;
spool_path = p + 1 ;
fh - > file_path = e + 1 ;
}
2010-02-06 03:38:24 +00:00
}
2009-09-16 22:56:30 +00:00
if ( ! spool_path ) {
2011-02-02 21:43:26 +00:00
spool_path = switch_core_get_variable_pdup ( SWITCH_AUDIO_SPOOL_PATH_VARIABLE , fh - > memory_pool ) ;
2009-09-16 22:56:30 +00:00
}
2010-02-06 03:38:24 +00:00
2009-09-16 22:56:30 +00:00
file_path = fh - > file_path ;
}
2007-03-29 22:34:40 +00:00
if ( ( ext = strrchr ( file_path , ' . ' ) ) = = 0 ) {
2008-11-12 13:41:18 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unknown file Format [%s] \n " , file_path ) ;
2009-10-08 14:55:16 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , fail ) ;
2007-03-29 22:34:40 +00:00
}
ext + + ;
2009-09-16 22:56:30 +00:00
fh - > file_path = switch_core_strdup ( fh - > memory_pool , file_path ) ;
2007-03-29 22:34:40 +00:00
}
2010-02-06 03:38:24 +00:00
2009-09-16 22:56:30 +00:00
2007-03-29 22:34:40 +00:00
if ( ( fh - > file_interface = switch_loadable_module_get_file_interface ( ext ) ) = = 0 ) {
2008-10-11 05:44:11 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid file format [%s] for [%s]! \n " , ext , file_path ) ;
2009-10-08 14:55:16 +00:00
switch_goto_status ( SWITCH_STATUS_GENERR , fail ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2008-01-08 18:35:51 +00:00
fh - > file = file ;
fh - > func = func ;
fh - > line = line ;
2009-10-08 14:01:03 +00:00
2010-02-06 03:38:24 +00:00
2009-09-16 20:09:27 +00:00
if ( spool_path ) {
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
switch_uuid_t uuid ;
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( uuid_str , & uuid ) ;
2010-02-06 03:38:24 +00:00
2009-09-16 20:09:27 +00:00
fh - > spool_path = switch_core_sprintf ( fh - > memory_pool , " %s%s%s.%s " , spool_path , SWITCH_PATH_SEPARATOR , uuid_str , ext ) ;
2011-08-16 20:50:21 +00:00
} else {
fh - > spool_path = NULL ;
2007-03-29 22:34:40 +00:00
}
if ( rhs ) {
fh - > handler = switch_core_strdup ( fh - > memory_pool , rhs ) ;
2011-08-16 20:50:21 +00:00
} else {
fh - > handler = NULL ;
2007-03-29 22:34:40 +00:00
}
if ( channels ) {
fh - > channels = channels ;
} else {
fh - > channels = 1 ;
}
2009-09-16 20:09:27 +00:00
file_path = fh - > spool_path ? fh - > spool_path : fh - > file_path ;
2007-12-12 21:30:55 +00:00
if ( ( status = fh - > file_interface - > file_open ( fh , file_path ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-09-16 20:09:27 +00:00
if ( fh - > spool_path ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Spool dir is set. Make sure [%s] is also a valid path \n " , fh - > spool_path ) ;
}
2008-11-12 19:28:05 +00:00
UNPROTECT_INTERFACE ( fh - > file_interface ) ;
2009-10-08 14:55:16 +00:00
switch_goto_status ( status , fail ) ;
2009-09-16 20:09:27 +00:00
}
2009-09-16 22:25:21 +00:00
2010-02-06 03:38:24 +00:00
if ( ( flags & SWITCH_FILE_FLAG_WRITE ) & & ! is_stream & & ( status = switch_file_exists ( file_path , fh - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-09-16 22:19:36 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " File [%s] not created! \n " , file_path ) ;
2009-09-16 20:09:27 +00:00
fh - > file_interface - > file_close ( fh ) ;
UNPROTECT_INTERFACE ( fh - > file_interface ) ;
2009-10-08 14:55:16 +00:00
switch_goto_status ( status , fail ) ;
2007-12-12 21:30:55 +00:00
}
if ( ( flags & SWITCH_FILE_FLAG_READ ) ) {
fh - > native_rate = fh - > samplerate ;
} else {
fh - > native_rate = rate ;
}
2008-05-27 04:30:03 +00:00
if ( fh - > samplerate & & rate & & fh - > samplerate ! = rate ) {
2010-09-09 14:27:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " File %s sample rate %d doesn't match requested rate %d \n " , file_path , fh - > samplerate , rate ) ;
2007-12-12 21:30:55 +00:00
if ( ( flags & SWITCH_FILE_FLAG_READ ) ) {
fh - > samplerate = rate ;
}
2007-03-29 22:34:40 +00:00
}
2009-07-23 15:55:13 +00:00
if ( fh - > pre_buffer_datalen ) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
switch_buffer_create_dynamic ( & fh - > pre_buffer , fh - > pre_buffer_datalen * fh - > channels , fh - > pre_buffer_datalen * fh - > channels / 2 , 0 ) ;
fh - > pre_buffer_data = switch_core_alloc ( fh - > memory_pool , fh - > pre_buffer_datalen * fh - > channels ) ;
}
2009-02-12 21:05:44 +00:00
if ( fh - > channels > 1 & & ( flags & SWITCH_FILE_FLAG_READ ) ) {
2009-01-15 17:47:21 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " File has %d channels, muxing to mono will occur. \n " , fh - > channels ) ;
2009-01-09 20:34:01 +00:00
}
2007-12-12 21:30:55 +00:00
switch_set_flag ( fh , SWITCH_FILE_OPEN ) ;
2009-10-08 14:55:16 +00:00
return status ;
2007-12-12 21:30:55 +00:00
2010-02-06 03:38:24 +00:00
fail :
2009-09-16 20:09:27 +00:00
if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_FREE_POOL ) ) {
switch_core_destroy_memory_pool ( & fh - > memory_pool ) ;
}
2007-03-29 22:34:40 +00:00
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_file_read ( switch_file_handle_t * fh , void * data , switch_size_t * len )
{
2009-01-09 20:34:01 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2011-04-22 21:43:29 +00:00
switch_size_t want , orig_len = * len ;
2010-02-06 03:38:24 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2009-01-24 18:11:42 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
top :
2009-01-09 20:34:01 +00:00
2009-01-08 01:42:09 +00:00
if ( fh - > buffer & & switch_buffer_inuse ( fh - > buffer ) > = * len * 2 ) {
2008-01-10 03:12:32 +00:00
* len = switch_buffer_read ( fh - > buffer , data , orig_len * 2 ) / 2 ;
2007-12-12 21:30:55 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-01-09 20:34:01 +00:00
if ( switch_test_flag ( fh , SWITCH_FILE_DONE ) ) {
switch_clear_flag ( fh , SWITCH_FILE_DONE ) ;
* len = 0 ;
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-01-08 01:42:09 +00:00
want = * len ;
2010-02-06 03:38:24 +00:00
more :
2009-01-09 20:34:01 +00:00
if ( fh - > pre_buffer ) {
switch_size_t rlen ;
2009-01-10 03:52:28 +00:00
int asis = switch_test_flag ( fh , SWITCH_FILE_NATIVE ) ;
2009-01-09 20:34:01 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_BUFFER_DONE ) ) {
2009-01-12 23:14:55 +00:00
rlen = asis ? fh - > pre_buffer_datalen : fh - > pre_buffer_datalen / 2 ;
if ( switch_buffer_inuse ( fh - > pre_buffer ) < rlen * 2 ) {
2009-01-09 20:34:01 +00:00
if ( ( status = fh - > file_interface - > file_read ( fh , fh - > pre_buffer_data , & rlen ) ) ! = SWITCH_STATUS_SUCCESS | | ! rlen ) {
switch_set_flag ( fh , SWITCH_FILE_BUFFER_DONE ) ;
} else {
2009-03-20 13:58:45 +00:00
fh - > samples_in + = rlen ;
2009-01-15 17:47:21 +00:00
if ( fh - > channels > 1 ) {
2010-02-06 03:38:24 +00:00
switch_mux_channels ( ( int16_t * ) fh - > pre_buffer_data , rlen , fh - > channels ) ;
2009-01-15 17:47:21 +00:00
}
2009-01-10 03:52:28 +00:00
switch_buffer_write ( fh - > pre_buffer , fh - > pre_buffer_data , asis ? rlen : rlen * 2 ) ;
2009-01-09 20:34:01 +00:00
}
}
}
2009-01-10 03:52:28 +00:00
rlen = switch_buffer_read ( fh - > pre_buffer , data , asis ? * len : * len * 2 ) ;
* len = asis ? rlen : rlen / 2 ;
2010-02-06 03:38:24 +00:00
2009-01-09 20:34:01 +00:00
if ( * len = = 0 ) {
switch_set_flag ( fh , SWITCH_FILE_DONE ) ;
2010-02-06 03:38:24 +00:00
goto top ;
2009-01-09 20:34:01 +00:00
} else {
status = SWITCH_STATUS_SUCCESS ;
}
} else {
if ( ( status = fh - > file_interface - > file_read ( fh , data , len ) ) ! = SWITCH_STATUS_SUCCESS | | ! * len ) {
switch_set_flag ( fh , SWITCH_FILE_DONE ) ;
goto top ;
}
2009-01-15 17:47:21 +00:00
2009-03-20 13:58:45 +00:00
fh - > samples_in + = * len ;
2009-01-15 17:47:21 +00:00
if ( fh - > channels > 1 ) {
2010-02-06 03:38:24 +00:00
switch_mux_channels ( ( int16_t * ) data , * len , fh - > channels ) ;
2009-01-15 17:47:21 +00:00
}
2007-12-12 21:30:55 +00:00
}
2009-01-09 20:34:01 +00:00
2007-12-12 21:30:55 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_NATIVE ) & & fh - > native_rate ! = fh - > samplerate ) {
if ( ! fh - > resampler ) {
if ( switch_resample_create ( & fh - > resampler ,
2009-07-23 15:55:13 +00:00
fh - > native_rate , fh - > samplerate , ( uint32_t ) orig_len , SWITCH_RESAMPLE_QUALITY , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
2007-12-12 21:30:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Unable to create resampler! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
}
2008-05-27 04:30:03 +00:00
2010-02-06 03:38:24 +00:00
switch_resample_process ( fh - > resampler , data , ( uint32_t ) * len ) ;
2009-01-08 01:42:09 +00:00
if ( fh - > resampler - > to_len < want | | fh - > resampler - > to_len > orig_len ) {
2007-12-12 21:30:55 +00:00
if ( ! fh - > buffer ) {
2009-01-13 05:17:07 +00:00
int factor = fh - > resampler - > to_len * fh - > samplerate / 1000 ;
2009-01-12 19:12:09 +00:00
switch_buffer_create_dynamic ( & fh - > buffer , factor , factor , 0 ) ;
2007-12-12 21:30:55 +00:00
switch_assert ( fh - > buffer ) ;
}
2009-01-22 00:18:00 +00:00
if ( ! fh - > dbuf | | fh - > dbuflen < fh - > resampler - > to_len * 2 ) {
2009-05-05 15:09:32 +00:00
void * mem ;
2009-01-22 00:18:00 +00:00
fh - > dbuflen = fh - > resampler - > to_len * 2 ;
2009-05-05 15:09:32 +00:00
mem = realloc ( fh - > dbuf , fh - > dbuflen ) ;
switch_assert ( mem ) ;
fh - > dbuf = mem ;
2007-12-12 21:30:55 +00:00
}
2009-05-05 15:09:32 +00:00
switch_assert ( fh - > resampler - > to_len * 2 < = fh - > dbuflen ) ;
2009-02-13 23:35:17 +00:00
memcpy ( ( int16_t * ) fh - > dbuf , fh - > resampler - > to , fh - > resampler - > to_len * 2 ) ;
2007-12-12 21:30:55 +00:00
switch_buffer_write ( fh - > buffer , fh - > dbuf , fh - > resampler - > to_len * 2 ) ;
2009-01-08 01:42:09 +00:00
if ( switch_buffer_inuse ( fh - > buffer ) < want * 2 ) {
2009-01-12 19:12:09 +00:00
* len = want ;
2009-01-08 01:42:09 +00:00
goto more ;
}
2008-01-10 03:12:32 +00:00
* len = switch_buffer_read ( fh - > buffer , data , orig_len * 2 ) / 2 ;
2007-12-12 21:30:55 +00:00
} else {
2009-02-13 23:35:17 +00:00
memcpy ( data , fh - > resampler - > to , fh - > resampler - > to_len * 2 ) ;
2007-12-12 21:30:55 +00:00
* len = fh - > resampler - > to_len ;
}
2010-02-06 03:38:24 +00:00
2008-05-27 04:30:03 +00:00
2007-12-12 21:30:55 +00:00
}
2010-02-06 03:38:24 +00:00
2007-12-12 21:30:55 +00:00
return status ;
2007-03-29 22:34:40 +00:00
}
2009-11-06 23:29:36 +00:00
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_write ( switch_file_handle_t * fh , void * data , switch_size_t * len )
{
2007-12-12 21:30:55 +00:00
switch_size_t orig_len = * len ;
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
2007-12-31 19:41:39 +00:00
2009-01-24 18:11:42 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_FALSE ;
}
2007-12-31 19:41:39 +00:00
if ( ! fh - > file_interface - > file_write ) {
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:30:03 +00:00
2007-12-12 21:30:55 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_NATIVE ) & & fh - > native_rate ! = fh - > samplerate ) {
if ( ! fh - > resampler ) {
if ( switch_resample_create ( & fh - > resampler ,
2010-02-06 03:38:24 +00:00
fh - > native_rate ,
fh - > samplerate ,
( uint32_t ) orig_len * 2 * fh - > channels , SWITCH_RESAMPLE_QUALITY , fh - > channels ) ! = SWITCH_STATUS_SUCCESS ) {
2007-12-12 21:30:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Unable to create resampler! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
}
2008-05-27 04:30:03 +00:00
2010-02-06 03:38:24 +00:00
switch_resample_process ( fh - > resampler , data , ( uint32_t ) * len ) ;
2009-07-23 15:55:13 +00:00
if ( fh - > resampler - > to_len > orig_len ) {
2007-12-12 21:30:55 +00:00
if ( ! fh - > dbuf ) {
2009-05-05 15:09:32 +00:00
void * mem ;
2009-07-23 15:55:13 +00:00
fh - > dbuflen = fh - > resampler - > to_len * 2 * fh - > channels ;
2009-05-05 15:09:32 +00:00
mem = realloc ( fh - > dbuf , fh - > dbuflen ) ;
switch_assert ( mem ) ;
fh - > dbuf = mem ;
2007-12-12 21:30:55 +00:00
}
2009-05-05 15:09:32 +00:00
switch_assert ( fh - > resampler - > to_len * 2 < = fh - > dbuflen ) ;
2009-07-23 15:55:13 +00:00
memcpy ( fh - > dbuf , fh - > resampler - > to , fh - > resampler - > to_len * 2 * fh - > channels ) ;
2007-12-12 21:30:55 +00:00
data = fh - > dbuf ;
} else {
2009-07-23 15:55:13 +00:00
memcpy ( data , fh - > resampler - > to , fh - > resampler - > to_len * 2 * fh - > channels ) ;
2007-12-12 21:30:55 +00:00
}
2009-07-23 15:55:13 +00:00
* len = fh - > resampler - > to_len ;
2007-12-12 21:30:55 +00:00
}
if ( ! * len ) {
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:34:40 +00:00
2009-01-09 20:34:01 +00:00
if ( fh - > pre_buffer ) {
switch_size_t rlen , blen ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2009-01-10 03:52:28 +00:00
int asis = switch_test_flag ( fh , SWITCH_FILE_NATIVE ) ;
2010-02-06 03:38:24 +00:00
2009-01-14 19:44:14 +00:00
switch_buffer_write ( fh - > pre_buffer , data , ( asis ? * len : * len * 2 ) * fh - > channels ) ;
2009-01-09 20:34:01 +00:00
rlen = switch_buffer_inuse ( fh - > pre_buffer ) ;
2009-11-06 23:29:36 +00:00
2009-01-09 20:34:01 +00:00
if ( rlen > = fh - > pre_buffer_datalen ) {
2009-05-05 15:09:32 +00:00
if ( ( blen = switch_buffer_read ( fh - > pre_buffer , fh - > pre_buffer_data , fh - > pre_buffer_datalen ) ) ) {
2010-02-06 03:38:24 +00:00
if ( ! asis )
blen / = 2 ;
if ( fh - > channels > 1 )
blen / = fh - > channels ;
2009-05-05 15:09:32 +00:00
if ( ( status = fh - > file_interface - > file_write ( fh , fh - > pre_buffer_data , & blen ) ) ! = SWITCH_STATUS_SUCCESS ) {
* len = 0 ;
}
2009-01-09 20:34:01 +00:00
}
}
2011-01-24 15:41:53 +00:00
fh - > samples_out + = orig_len ;
2009-01-09 20:34:01 +00:00
return status ;
} else {
2009-03-20 13:58:45 +00:00
switch_status_t status ;
if ( ( status = fh - > file_interface - > file_write ( fh , data , len ) ) = = SWITCH_STATUS_SUCCESS ) {
2009-11-06 23:29:36 +00:00
fh - > samples_out + = orig_len ;
2009-03-20 13:58:45 +00:00
}
return status ;
2009-01-09 20:34:01 +00:00
}
2007-03-29 22:34:40 +00:00
}
2012-07-20 03:38:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_write_video ( switch_file_handle_t * fh , void * data , switch_size_t * len )
{
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_GENERR ;
}
if ( ! fh - > file_interface - > file_write_video ) {
return SWITCH_STATUS_FALSE ;
}
return fh - > file_interface - > file_write_video ( fh , data , len ) ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_seek ( switch_file_handle_t * fh , unsigned int * cur_pos , int64_t samples , int whence )
2007-03-29 22:34:40 +00:00
{
2007-07-05 17:03:14 +00:00
switch_status_t status ;
2010-10-27 00:34:47 +00:00
int ok = 1 ;
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2010-10-27 00:34:47 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) | | ! fh - > file_interface - > file_seek ) {
ok = 0 ;
} else if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_WRITE ) ) {
if ( ! ( switch_test_flag ( fh , SWITCH_FILE_WRITE_APPEND ) | | switch_test_flag ( fh , SWITCH_FILE_WRITE_OVER ) ) ) {
ok = 0 ;
}
} else if ( ! switch_test_flag ( fh , SWITCH_FILE_FLAG_READ ) ) {
ok = 0 ;
2009-02-23 19:52:29 +00:00
}
2010-10-27 00:34:47 +00:00
if ( ! ok ) {
2007-12-31 19:41:39 +00:00
return SWITCH_STATUS_FALSE ;
}
2010-10-27 00:34:47 +00:00
2009-07-10 17:18:02 +00:00
if ( fh - > buffer ) {
switch_buffer_zero ( fh - > buffer ) ;
}
if ( fh - > pre_buffer ) {
switch_buffer_zero ( fh - > pre_buffer ) ;
}
if ( whence = = SWITCH_SEEK_CUR ) {
2010-10-27 00:34:47 +00:00
unsigned int cur = 0 ;
if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_WRITE ) ) {
fh - > file_interface - > file_seek ( fh , & cur , fh - > samples_out , SEEK_SET ) ;
} else {
fh - > file_interface - > file_seek ( fh , & cur , fh - > offset_pos , SEEK_SET ) ;
}
2009-07-10 17:18:02 +00:00
}
2007-03-29 22:34:40 +00:00
switch_set_flag ( fh , SWITCH_FILE_SEEK ) ;
2007-07-05 17:03:14 +00:00
status = fh - > file_interface - > file_seek ( fh , cur_pos , samples , whence ) ;
2010-10-27 00:34:47 +00:00
2011-05-17 18:00:34 +00:00
fh - > offset_pos = * cur_pos ;
2010-10-27 00:34:47 +00:00
2011-05-17 18:00:34 +00:00
if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_WRITE ) ) {
fh - > samples_out = * cur_pos ;
2007-07-05 17:03:14 +00:00
}
2010-10-27 00:34:47 +00:00
2007-07-05 17:03:14 +00:00
return status ;
2007-03-29 22:34:40 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_set_string ( switch_file_handle_t * fh , switch_audio_col_t col , const char * string )
2007-03-29 22:34:40 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2009-02-23 19:52:29 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_FALSE ;
}
2007-12-31 19:41:39 +00:00
if ( ! fh - > file_interface - > file_set_string ) {
return SWITCH_STATUS_FALSE ;
}
2007-03-29 22:34:40 +00:00
return fh - > file_interface - > file_set_string ( fh , col , string ) ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_get_string ( switch_file_handle_t * fh , switch_audio_col_t col , const char * * string )
2007-03-29 22:34:40 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2009-02-23 19:52:29 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_FALSE ;
}
2007-12-31 19:41:39 +00:00
if ( ! fh - > file_interface - > file_get_string ) {
return SWITCH_STATUS_FALSE ;
}
2007-03-29 22:34:40 +00:00
return fh - > file_interface - > file_get_string ( fh , col , string ) ;
}
2009-11-17 21:40:09 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_truncate ( switch_file_handle_t * fh , int64_t offset )
{
switch_status_t status ;
2010-02-06 03:38:24 +00:00
2009-11-17 21:40:09 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
if ( ! ( switch_test_flag ( fh , SWITCH_FILE_OPEN ) & & switch_test_flag ( fh , SWITCH_FILE_FLAG_WRITE ) ) ) {
return SWITCH_STATUS_FALSE ;
}
if ( ! fh - > file_interface - > file_truncate ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
if ( ( status = fh - > file_interface - > file_truncate ( fh , offset ) ) = = SWITCH_STATUS_SUCCESS ) {
2009-11-17 21:40:09 +00:00
if ( fh - > buffer ) {
switch_buffer_zero ( fh - > buffer ) ;
}
if ( fh - > pre_buffer ) {
switch_buffer_zero ( fh - > pre_buffer ) ;
}
fh - > samples_out = 0 ;
fh - > pos = 0 ;
}
return status ;
}
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_close ( switch_file_handle_t * fh )
{
2007-12-12 14:16:24 +00:00
switch_status_t status ;
2007-12-11 19:23:57 +00:00
switch_assert ( fh ! = NULL ) ;
switch_assert ( fh - > file_interface ! = NULL ) ;
2007-06-22 19:14:53 +00:00
2009-01-10 03:52:28 +00:00
if ( ! switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) {
return SWITCH_STATUS_FALSE ;
}
2007-12-12 21:30:55 +00:00
if ( fh - > buffer ) {
switch_buffer_destroy ( & fh - > buffer ) ;
}
2009-01-09 20:34:01 +00:00
if ( fh - > pre_buffer ) {
if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_WRITE ) ) {
switch_size_t rlen , blen ;
2009-01-10 03:52:28 +00:00
int asis = switch_test_flag ( fh , SWITCH_FILE_NATIVE ) ;
2010-02-06 03:38:24 +00:00
while ( ( rlen = switch_buffer_inuse ( fh - > pre_buffer ) ) ) {
2009-05-05 15:09:32 +00:00
if ( ( blen = switch_buffer_read ( fh - > pre_buffer , fh - > pre_buffer_data , fh - > pre_buffer_datalen ) ) ) {
2010-02-06 03:38:24 +00:00
if ( ! asis )
blen / = 2 ;
if ( fh - > channels > 1 )
blen / = fh - > channels ;
2009-05-05 15:09:32 +00:00
if ( fh - > file_interface - > file_write ( fh , fh - > pre_buffer_data , & blen ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
2009-01-09 20:34:01 +00:00
}
}
}
switch_buffer_destroy ( & fh - > pre_buffer ) ;
}
2009-01-14 19:44:14 +00:00
switch_clear_flag ( fh , SWITCH_FILE_OPEN ) ;
status = fh - > file_interface - > file_close ( fh ) ;
2007-12-12 21:30:55 +00:00
switch_resample_destroy ( & fh - > resampler ) ;
2009-09-16 20:09:27 +00:00
if ( fh - > spool_path ) {
char * command ;
# ifdef _MSC_VER
command = switch_mprintf ( " move %s %s " , fh - > spool_path , fh - > file_path ) ;
# else
command = switch_mprintf ( " /bin/mv %s %s " , fh - > spool_path , fh - > file_path ) ;
# endif
2011-04-25 02:47:12 +00:00
if ( system ( command ) = = - 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Failed to copy spooled file [%s] to [%s] because of a command error : %s \n " , fh - > spool_path , fh - > file_path , command ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Copy spooled file [%s] to [%s] \n " , fh - > spool_path , fh - > file_path ) ;
}
2009-09-16 20:09:27 +00:00
free ( command ) ;
}
2008-11-12 19:28:05 +00:00
UNPROTECT_INTERFACE ( fh - > file_interface ) ;
2007-12-12 14:16:24 +00:00
if ( switch_test_flag ( fh , SWITCH_FILE_FLAG_FREE_POOL ) ) {
switch_core_destroy_memory_pool ( & fh - > memory_pool ) ;
}
2009-05-05 15:09:32 +00:00
switch_safe_free ( fh - > dbuf ) ;
2007-12-12 14:16:24 +00:00
return status ;
2007-03-29 22:34:40 +00:00
}
2008-01-27 05:02:52 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 05:02:52 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 05:02:52 +00:00
*/