strings.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:6k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU Lesser General Public License as published by
  6. ** the Free Software Foundation; either version 2.1 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU Lesser General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU Lesser General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "sndfile.h"
  23. #include "common.h"
  24. #define STRINGS_DEBUG 0
  25. #if STRINGS_DEBUG
  26. static void hexdump (void *data, int len) ;
  27. #endif
  28. int
  29. psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
  30. { static char lsf_name [] = PACKAGE "-" VERSION ;
  31. static char bracket_name [] = " (" PACKAGE "-" VERSION ")" ;
  32. int k, str_len, len_remaining, str_flags, str_type_replace = 0 ;
  33. if (str == NULL)
  34. return SFE_STR_BAD_STRING ;
  35. str_len = strlen (str) ;
  36. /* A few extra checks for write mode. */
  37. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  38. { if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
  39. return SFE_STR_NO_SUPPORT ;
  40. if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0)
  41. return SFE_STR_NO_SUPPORT ;
  42. /* Only allow zero length strings for software. */
  43. if (str_type != SF_STR_SOFTWARE && str_len == 0)
  44. return SFE_STR_BAD_STRING ;
  45. } ;
  46. /* Find the next free slot in table. */
  47. for (k = 0 ; k < SF_MAX_STRINGS ; k++)
  48. { /* If we find a matching entry clear it. */
  49. if (psf->strings [k].type == str_type)
  50. psf->strings [k].type = -1 ;
  51. if (psf->strings [k].type == 0)
  52. break ;
  53. } ;
  54. /* Determine flags */
  55. str_flags = SF_STR_LOCATE_START ;
  56. if (psf->file.mode == SFM_RDWR || psf->have_written || str_type_replace)
  57. { if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
  58. return SFE_STR_NO_ADD_END ;
  59. str_flags = SF_STR_LOCATE_END ;
  60. } ;
  61. /* More sanity checking. */
  62. if (k >= SF_MAX_STRINGS)
  63. return SFE_STR_MAX_COUNT ;
  64. if (k == 0 && psf->str_end != NULL)
  65. { psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULLn") ;
  66. return SFE_STR_WEIRD ;
  67. } ;
  68. if (k != 0 && psf->str_end == NULL)
  69. { psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULLn") ;
  70. return SFE_STR_WEIRD ;
  71. } ;
  72. /* Special case for the first string. */
  73. if (k == 0)
  74. psf->str_end = psf->str_storage ;
  75. len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
  76. if (len_remaining < str_len + 2)
  77. return SFE_STR_MAX_DATA ;
  78. switch (str_type)
  79. { case SF_STR_SOFTWARE :
  80. /* In write mode, want to append libsndfile-version to string. */
  81. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  82. { psf->strings [k].type = str_type ;
  83. psf->strings [k].str = psf->str_end ;
  84. psf->strings [k].flags = str_flags ;
  85. memcpy (psf->str_end, str, str_len + 1) ;
  86. psf->str_end += str_len ;
  87. /*
  88. ** If the supplied string does not already contain a
  89. ** libsndfile-X.Y.Z component, then add it.
  90. */
  91. if (strstr (str, PACKAGE) == NULL && len_remaining > (int) (strlen (bracket_name) + str_len + 2))
  92. { if (strlen (str) == 0)
  93. strncat (psf->str_end, lsf_name, len_remaining) ;
  94. else
  95. strncat (psf->str_end, bracket_name, len_remaining) ;
  96. psf->str_end += strlen (psf->str_end) ;
  97. } ;
  98. /* Plus one to catch string terminator. */
  99. psf->str_end += 1 ;
  100. break ;
  101. } ;
  102. /* Fall though if not write mode. */
  103. case SF_STR_TITLE :
  104. case SF_STR_COPYRIGHT :
  105. case SF_STR_ARTIST :
  106. case SF_STR_COMMENT :
  107. case SF_STR_DATE :
  108. case SF_STR_ALBUM :
  109. case SF_STR_LICENSE :
  110. psf->strings [k].type = str_type ;
  111. psf->strings [k].str = psf->str_end ;
  112. psf->strings [k].flags = str_flags ;
  113. /* Plus one to catch string terminator. */
  114. memcpy (psf->str_end, str, str_len + 1) ;
  115. psf->str_end += str_len + 1 ;
  116. break ;
  117. default :
  118. psf_log_printf (psf, "%s : SFE_STR_BAD_TYPEn", __func__) ;
  119. return SFE_STR_BAD_TYPE ;
  120. } ;
  121. psf->str_flags |= str_flags ;
  122. #if STRINGS_DEBUG
  123. psf_log_printf (psf, "str_storage          : %Xn", (int) psf->str_storage) ;
  124. psf_log_printf (psf, "str_end              : %Xn", (int) psf->str_end) ;
  125. psf_log_printf (psf, "sizeof (str_storage) : %dn", SIGNED_SIZEOF (psf->str_storage)) ;
  126. psf_log_printf (psf, "used                 : %dn", (int ) (psf->str_end - psf->str_storage)) ;
  127. psf_log_printf (psf, "remaining            : %dn", SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage)) ;
  128. hexdump (psf->str_storage, 300) ;
  129. #endif
  130. return 0 ;
  131. } /* psf_store_string */
  132. int
  133. psf_set_string (SF_PRIVATE *psf, int str_type, const char *str)
  134. { if (psf->file.mode == SFM_READ)
  135. return SFE_STR_NOT_WRITE ;
  136. return psf_store_string (psf, str_type, str) ;
  137. } /* psf_set_string */
  138. const char*
  139. psf_get_string (SF_PRIVATE *psf, int str_type)
  140. { int k ;
  141. for (k = 0 ; k < SF_MAX_STRINGS ; k++)
  142. if (str_type == psf->strings [k].type)
  143. return psf->strings [k].str ;
  144. return NULL ;
  145. } /* psf_get_string */
  146. int
  147. psf_location_string_count (const SF_PRIVATE * psf, int location)
  148. { int k, count = 0 ;
  149. for (k = 0 ; k < SF_MAX_STRINGS ; k++)
  150. if (psf->strings [k].type > 0 && psf->strings [k].flags & location)
  151. count ++ ;
  152. return count ;
  153. } /* psf_location_string_count */
  154. /*==============================================================================
  155. */
  156. #if STRINGS_DEBUG
  157. #include <ctype.h>
  158. static void
  159. hexdump (void *data, int len)
  160. { unsigned char *ptr ;
  161. int k ;
  162. ptr = data ;
  163. puts ("---------------------------------------------------------") ;
  164. while (len >= 16)
  165. { for (k = 0 ; k < 16 ; k++)
  166. printf ("%02X ", ptr [k] & 0xFF) ;
  167. printf ("   ") ;
  168. for (k = 0 ; k < 16 ; k++)
  169. printf ("%c", psf_isprint (ptr [k]) ? ptr [k] : '.') ;
  170. puts ("") ;
  171. ptr += 16 ;
  172. len -= 16 ;
  173. } ;
  174. } /* hexdump */
  175. #endif