~ubuntu-branches/ubuntu/precise/banshee/precise-proposed

« back to all changes in this revision

Viewing changes to src/Libraries/MusicBrainz/MusicBrainz/DiscFreeBsd.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2012-02-18 22:17:24 UTC
  • mfrom: (6.3.23 experimental)
  • Revision ID: package-import@ubuntu.com-20120218221724-cnwdvn490wjjue8t
Tags: 2.3.5-1ubuntu1
* Merge from Debian Experimental, remaining changes:
  + Enable and recommend SoundMenu and Disable NotificationArea by default
  + Disable boo and karma extensions
  + Move desktop file for Meego UI to /usr/share/une/applications
  + Change the url for the Amazon store redirector

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// DiskFreeBsd.cs
 
2
//
 
3
// Copyright (c) 2009 Romain Tartière <romain@blogreen.org>
 
4
//
 
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
// of this software and associated documentation files (the "Software"), to deal
 
7
// in the Software without restriction, including without limitation the rights
 
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
// copies of the Software, and to permit persons to whom the Software is
 
10
// furnished to do so, subject to the following conditions:
 
11
//
 
12
// The above copyright notice and this permission notice shall be included in
 
13
// all copies or substantial portions of the Software.
 
14
//
 
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
21
// THE SOFTWARE.
 
22
 
 
23
using System;
 
24
using System.Runtime.InteropServices;
 
25
 
 
26
namespace MusicBrainz
 
27
{
 
28
    internal sealed class DiscFreeBsd : LocalDisc
 
29
    {
 
30
 
 
31
#region <fcntl.h>
 
32
        // open for reading only
 
33
        const int O_RDONLY   = 0x0000;
 
34
        // no delay
 
35
        const int O_NONBLOCK = 0x0004;
 
36
 
 
37
        [DllImport ("libc", CharSet = CharSet.Auto, SetLastError = true)]
 
38
        static extern int open (string path, int flags);
 
39
#endregion
 
40
 
 
41
#region <unistd.h>
 
42
        [DllImport ("libc", SetLastError = true)]
 
43
        static extern int close (int d);
 
44
#endregion
 
45
 
 
46
#region <sys/cdio.h>
 
47
        struct msf_lba
 
48
        {
 
49
            public int lba; // network byte order
 
50
        }
 
51
 
 
52
        [StructLayout (LayoutKind.Explicit)]
 
53
        struct cd_toc_entry
 
54
        {
 
55
            [FieldOffset (2)]
 
56
            public byte track;
 
57
            [FieldOffset (4)]
 
58
            public msf_lba addr;
 
59
        }
 
60
 
 
61
        // Ioctls for the CD drive
 
62
 
 
63
        const byte CD_LBA_FORMAT = 1;
 
64
 
 
65
        struct ioc_toc_header
 
66
        {
 
67
            public short len;
 
68
            public byte starting_track;
 
69
            public byte ending_track;
 
70
        }
 
71
        const ulong CDIOREADTOCHEADER = 1074029316;
 
72
        [DllImport ("libc", EntryPoint = "ioctl")]
 
73
        static extern int cd_read_toc_header (int fd, ulong request, ref ioc_toc_header data);
 
74
        static int cd_read_toc_header (int fd, ref ioc_toc_header data)
 
75
        {
 
76
            return cd_read_toc_header (fd, CDIOREADTOCHEADER, ref data);
 
77
        }
 
78
 
 
79
        struct ioc_read_toc_entry
 
80
        {
 
81
            public byte address_format;
 
82
            public byte starting_track;
 
83
            public ushort data_len;
 
84
            public IntPtr data; // cd_toc_entry*
 
85
        }
 
86
        const ulong CDIOREADTOCENTRYS = 3222299397;
 
87
        [DllImport ("libc", EntryPoint = "ioctl")]
 
88
        static extern int cd_read_toc_entrys (int fd, ulong request, ref ioc_read_toc_entry data);
 
89
        static int cd_read_toc_entrys (int fd, ref ioc_read_toc_entry data)
 
90
        {
 
91
            return cd_read_toc_entrys (fd, CDIOREADTOCENTRYS, ref data);
 
92
        }
 
93
 
 
94
#endregion
 
95
 
 
96
        internal DiscFreeBsd (string device)
 
97
        {
 
98
            int fd = open (device, O_RDONLY | O_NONBLOCK);
 
99
 
 
100
            if (fd < 0) {
 
101
                throw new LocalDiscException (String.Format ("Cannot open device `{0}'", device));
 
102
            }
 
103
 
 
104
            try {
 
105
                ioc_toc_header h = new ioc_toc_header ();
 
106
                if (cd_read_toc_header (fd, ref h) < 0) {
 
107
                    throw new LocalDiscException ("Cannot read table of contents header");
 
108
                }
 
109
                if (h.ending_track == 0) {
 
110
                    throw new LocalDiscException ("This disc has no tracks");
 
111
                }
 
112
 
 
113
                first_track = h.starting_track;
 
114
                last_track = h.ending_track;
 
115
 
 
116
                int n = h.ending_track - h.starting_track + 1;
 
117
                int len = (n + 1) * Marshal.SizeOf (typeof (cd_toc_entry));
 
118
 
 
119
                ioc_read_toc_entry t = new ioc_read_toc_entry ();
 
120
                t.address_format = CD_LBA_FORMAT;
 
121
                t.starting_track = 0;
 
122
                t.data_len = (ushort) len;
 
123
                t.data = Marshal.AllocHGlobal (len);
 
124
                try {
 
125
 
 
126
                    if (cd_read_toc_entrys (fd, ref t) < 0) {
 
127
                        throw new LocalDiscException ("Cannot read table of contents entries");
 
128
                    }
 
129
 
 
130
                    for (int i = 0; i <= n; i++) {
 
131
                        ulong offset = (ulong) (i * Marshal.SizeOf (typeof (cd_toc_entry)));
 
132
                        cd_toc_entry e = (cd_toc_entry) Marshal.PtrToStructure ((IntPtr) ((ulong)t.data + offset), typeof (cd_toc_entry));
 
133
                        track_offsets[first_track + i] = System.Net.IPAddress.NetworkToHostOrder (e.addr.lba) + 150;
 
134
                    }
 
135
 
 
136
                    // Move Leadout to the beginning.
 
137
                    track_offsets [0] = track_offsets [last_track + 1];
 
138
                    track_offsets [last_track + 1] = 0;
 
139
                } finally {
 
140
                    Marshal.FreeHGlobal (t.data);
 
141
                }
 
142
            } finally {
 
143
                close (fd);
 
144
            }
 
145
 
 
146
            Init ();
 
147
        }
 
148
    }
 
149
}