Guest User

Untitled

a guest
May 24th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.83 KB | None | 0 0
  1. use std::ffi::{CString, NulError};
  2. use std::fs::File;
  3. use std::io::prelude::*;
  4. use std::io;
  5. use std::path::PathBuf;
  6.  
  7. use libc;
  8. use libcue_sys as libcue;
  9. use libcue_sys::DiscMode;
  10.  
  11. use cd_text::CDText;
  12. use rem::REM;
  13. use track::Track;
  14.  
  15. /// The CD struct represents the entirety of a CD, which is the core unit of
  16. /// a CUE sheet. This struct contains the parsing methods used as the primary
  17. /// entry point to libcue's functionality.
  18. ///
  19. /// A CD can be a pure CD audio disc, a pure data disc, or a mixed-mode disc
  20. /// containing both data and audio tracks in arbitrary order. A CD will
  21. /// always have at least one track.
  22. ///
  23. /// Here's an example of a simple function which parses a CUE sheet and
  24. /// prints information about its contents:
  25. ///
  26. /// ```rust, no_run
  27. /// let cd = CD::parse_file(path).unwrap();
  28. ///
  29. /// println!("Number of tracks: {}", cd.get_track_count());
  30. /// let mode = match cd.get_mode() {
  31. /// DiscMode::CD_DA => "CD-DA",
  32. /// DiscMode::CD_ROM => "CD-ROM",
  33. /// DiscMode::CD_ROM_XA => "CD-ROM XA",
  34. /// };
  35. /// println!("Mode: {}", mode);
  36. /// println!("");
  37. ///
  38. /// for (index, track) in cd.tracks().iter().enumerate() {
  39. /// println!("Track {}", index + 1);
  40. /// println!("Filename: {}", track.get_filename());
  41. /// println!("Mode: {}", track_mode);
  42. /// println!("Start: {}", track.get_start());
  43. /// println!("Length: {}", track.get_length());
  44. /// println!("Pregap: {}", track.get_zero_pre());
  45. /// println!("Postgap: {}", track.get_zero_post());
  46. /// println!("");
  47. /// }
  48. /// ```
  49. pub struct CD {
  50. cd: *mut libcue::CdPointer,
  51. }
  52.  
  53. impl CD {
  54. /// Parses a string containing a CUE sheet and returns a CD struct.
  55. /// Returns a NulError if the provided string contains any null bytes.
  56. pub fn parse(string: String) -> Result<CD, NulError> {
  57. let c_string = CString::new(string)?;
  58. let cd;
  59. unsafe {
  60. cd = libcue::cue_parse_string(c_string.as_ptr());
  61. }
  62. let cd_type = CD {
  63. cd: cd,
  64. };
  65. return Ok(cd_type);
  66. }
  67.  
  68. /// Reads the file contained at `path` and parses it like the `parse` function
  69. /// above.
  70. pub fn parse_file(path: PathBuf) -> Result<CD, io::Error> {
  71. let mut cue_sheet = vec![];
  72. File::open(&path)?.read_to_end(&mut cue_sheet)?;
  73. return Ok(CD::parse(String::from_utf8_lossy(&cue_sheet).into_owned()).unwrap());
  74. }
  75.  
  76. /// Returns a DiscMode value indicating the type of disc represented by this
  77. /// CUE sheet.
  78. /// Individual tracks also have types; see `Track.get_mode` and `Track.get_sub_mode`.
  79. pub fn get_mode(&self) -> DiscMode {
  80. unsafe {
  81. return libcue::cd_get_mode(self.cd);
  82. }
  83. }
  84.  
  85. /// Returns the path on disc to the sidecar metadata file containing CD-TEXT
  86. /// metadata, if any.
  87. pub fn get_cdtextfile(&self) -> String {
  88. let c_string;
  89. unsafe {
  90. let raw_string = libcue::cd_get_cdtextfile(self.cd);
  91. c_string = CString::from_raw(raw_string);
  92. }
  93. return c_string.to_string_lossy().into_owned();
  94. }
  95.  
  96. /// Returns the total number of tracks in this CD.
  97. pub fn get_track_count(&self) -> isize {
  98. unsafe {
  99. return libcue::cd_get_ntrack(self.cd) as isize;
  100. }
  101. }
  102.  
  103. /// Returns a Track struct for the track at the requested index.
  104. /// If the requested track doesn't exist in the CD, returns `Err`
  105. /// with a string containing an error message.
  106. /// Note that track numbering starts from 1; there is no track 0.
  107. pub fn get_track(&self, index: isize) -> Result<Track, String> {
  108. let track_count = self.get_track_count();
  109. if index > track_count {
  110. return Err(format!("Invalid index; CD has {} tracks", track_count));
  111. }
  112.  
  113. let track;
  114. unsafe {
  115. track = libcue::cd_get_track(self.cd, index as libc::c_int);
  116. }
  117.  
  118. return Ok(Track::from(track));
  119. }
  120.  
  121. /// Returns a Vec containing every track in the CD.
  122. pub fn tracks(&self) -> Vec<Track> {
  123. let mut tracks = vec![];
  124. let mut index = 1;
  125. while index <= self.get_track_count() {
  126. tracks.push(self.get_track(index).unwrap());
  127. index += 1;
  128. }
  129.  
  130. return tracks;
  131. }
  132.  
  133. /// Returns a CDText struct representing the CD-TEXT data stored within
  134. /// this CUE sheet.
  135. pub fn get_cdtext(&self) -> CDText {
  136. let cdtext;
  137. unsafe {
  138. cdtext = libcue::cd_get_cdtext(self.cd);
  139. }
  140. return CDText::from(cdtext);
  141. }
  142.  
  143. /// Returns a REM struct representing the comments stored within
  144. /// this CUE sheet.
  145. pub fn get_rem(&self) -> REM {
  146. let rem;
  147. unsafe {
  148. rem = libcue::cd_get_rem(self.cd);
  149. }
  150. return REM::from(rem);
  151. }
  152. }
  153.  
  154. impl Drop for CD {
  155. fn drop(&mut self) {
  156. unsafe {
  157. libcue::cd_delete(self.cd);
  158. }
  159. }
  160. }
Add Comment
Please, Sign In to add comment