1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
#![no_std]

//! The `MacTypes-sys` library provides bindings to the MacTypes.h header on OSX.
//! This library defines base types used in both Carbon and legacy Cocoa APIs.

extern crate libc;

use core::cmp::{Eq, PartialEq};
use core::hash::{Hash, Hasher};
use core::fmt;
use core::mem;
use core::ptr;
use core::str;
use libc::*;

pub type UInt8 = u8;
pub type SInt8 = i8;
pub type UInt16 = u16;
pub type SInt16 = i16;
pub type UInt32 = u32;
pub type SInt32 = i32;

#[cfg(target_endian = "big")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct wide {
    pub hi: SInt32,
    pub lo: UInt32,
}

#[cfg(target_endian = "big")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct UnsignedWide {
    pub hi: UInt32,
    pub lo: UInt32,
}

#[cfg(target_endian = "little")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct wide {
    pub lo: UInt32,
    pub hi: SInt32,
}

#[cfg(target_endian = "little")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct UnsignedWide {
    pub lo: UInt32,
    pub hi: UInt32,
}

pub type SInt64 = i64;
pub type UInt64 = u64;

pub type Fixed = SInt32;
pub type FixedPtr = *mut Fixed;
pub type Fract = SInt32;
pub type FractPtr = *mut Fract;
pub type UnsignedFixed = UInt32;
pub type UnsignedFixedPtr = *mut UnsignedFixed;
pub type ShortFixed = SInt16;
pub type ShortFixedPtr = *mut ShortFixed;

pub type Float32 = c_float;
pub type Float64 = c_double;

#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[repr(C)]
pub struct Float80 {
    pub exp: SInt16,
    pub man: [UInt16; 4],
}

#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[repr(C)]
pub struct Float96 {
    pub exp: [SInt16; 2],
    pub man: [UInt16; 4],
}

pub type Ptr = *mut c_char;
pub type Handle = *mut Ptr;
pub type size = c_long;

pub type OSErr = SInt16;
pub type OSStatus = SInt32;
pub type LogicalAddress = *mut c_void;
pub type ConstLogicalAddress = *const c_void;
pub type PhysicalAddress = *mut c_void;
pub type BytePtr = *mut UInt8;
pub type ByteCount = c_ulong;
pub type ByteOffset = c_ulong;
pub type Duration = SInt32;
pub type AbsoluteTime = UnsignedWide;
pub type OptionBits = UInt32;
pub type ItemCount = c_ulong;
pub type PBVersion = UInt32;
pub type ScriptCode = SInt16;
pub type LangCode = SInt16;
pub type RegionCode = SInt16;
pub type FourCharCode = UInt32;
pub type OSType = FourCharCode;
pub type ResType = FourCharCode;
pub type OSTypePtr = *mut OSType;
pub type ResTypePtr = *mut ResType;

pub type Boolean = c_uchar;

pub type ProcPtr = unsafe extern "C" fn(c_long);
pub type Register68kProcPtr = unsafe extern "C" fn();

pub type UniversalProcPtr = ProcPtr;

pub type ProcHandle = *mut ProcPtr;
pub type UniversalProcHandle = *mut UniversalProcPtr;

pub type PRefCon = *mut c_void;

#[cfg(target_pointer_width = "64")]
pub type URefCon = *mut c_void;

#[cfg(target_pointer_width = "64")]
pub type SRefCon = *mut c_void;

#[cfg(target_pointer_width = "32")]
pub type URefCon = UInt32;

#[cfg(target_pointer_width = "32")]
pub type SRefCon = SInt32;

pub const kNoErr: OSErr = 0;
pub const kNilOptions: OptionBits = 0;
pub const kInvalidId: u32 = 0;
pub const kVariableLengthArray: u32 = 1;
pub const kUnknownType: u32 = 0x3F3F3F3F;

pub type UnicodeScalarValue = UInt32;
pub type UTF32Char = UInt32;
pub type UniChar = UInt16;
pub type UTF16Char = UInt16;
pub type UTF8Char = UInt8;
pub type UniCharPtr = *mut UniChar;
pub type UniCharCount = c_ulong;
pub type UniCharCountPtr = *mut UniCharCount;
pub type Str255 = [c_uchar; 256];
pub type Str63 = [c_uchar; 64];
pub type Str31 = [c_uchar; 32];
pub type Str27 = [c_uchar; 28];
pub type Str15 = [c_uchar; 16];

pub type StrField32 = [c_uchar; 34];

pub type StrFileName = Str63;
pub type StringPtr = *mut c_uchar;
pub type StringHandle = *mut StringPtr;
pub type ConstStringPtr = *const c_uchar;
pub type ConstStr255Param = *const c_uchar;
pub type ConstStr63Param = *const c_uchar;
pub type ConstStr31Param = *const c_uchar;
pub type ConstStr27Param = *const c_uchar;
pub type ConstStr15Param = *const c_uchar;
pub type ConstStrFileNameParam = *const ConstStr63Param;

#[inline]
pub unsafe extern "C" fn StrLength(string: ConstStr255Param) -> c_uchar {
    *string
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct ProcessSerialNumber {
    pub highLongOfPSN: UInt32,
    pub lowLongOfPSN: UInt32,
}

pub type ProcessSerialNumberPtr = *mut ProcessSerialNumber;

#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Point {
    pub v: c_short,
    pub h: c_short,
}

pub type PointPtr = *mut Point;

#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Rect {
    pub top: c_short,
    pub left: c_short,
    pub bottom: c_short,
    pub right: c_short,
}

pub type RectPtr = *mut Rect;

#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct FixedRect {
    pub top: Fixed,
    pub left: Fixed,
    pub bottom: Fixed,
    pub right: Fixed,
}

pub type FixedRectPtr = *mut FixedRect;

pub type CharParameter = c_short;

pub const normal: Style = 0;
pub const bold: Style = 1;
pub const italic: Style = 2;
pub const underline: Style = 4;
pub const outline: Style = 8;
pub const shadow: Style = 0x10;
pub const condense: Style = 0x20;
pub const extend: Style = 0x40;

pub type Style = c_uchar;
pub type StyleParameter = c_short;
pub type StyleField = Style;

pub type TimeValue = SInt32;
pub type TimeScale = SInt32;
pub type CompTimeValue = wide;
pub type TimeBase = *mut TimeBaseRecord;

#[repr(C)]
pub struct TimeBaseRecord {
    _priv: c_void
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct TimeRecord {
    pub value: CompTimeValue,
    pub scale: TimeScale,
    pub base: TimeBase,
}

#[cfg(target_endian = "big")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct NumVersion {
    pub majorRev: UInt8,
    pub minorAndBugRef: UInt8,
    pub stage: UInt8,
    pub nonRelRev: UInt8,
}

#[cfg(target_endian = "little")]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct NumVersion {
    pub nonRelRev: UInt8,
    pub stage: UInt8,
    pub minorAndBugRef: UInt8,
    pub majorRev: UInt8,
}

pub const developStage: UInt32 = 0x20;
pub const alphaStage: UInt32 = 0x40;
pub const betaStage: UInt32 = 0x60;
pub const finalStage: UInt32 = 0x80;

#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct NumVersionVariant {
    pub whole: UInt32,
}

pub type NumVersionVariantPtr = *mut NumVersionVariant;
pub type NumVersionVariantHandle = *mut NumVersionVariantPtr;

#[repr(C)]
pub struct VersRec {
    pub numericVersion: NumVersion,
    pub countryCode: c_short,
    pub shortVersion: Str255,
    pub reserved: Str255,
}

// Manual implementation of various traits on VersRec as the Str255 members prevent auto-derive

impl Clone for VersRec {
    fn clone(&self) -> Self {
        let mut clone = VersRec::default();
        clone.numericVersion = self.numericVersion;
        clone.countryCode = self.countryCode;
        unsafe {
            ptr::copy_nonoverlapping(&self.shortVersion, &mut clone.shortVersion, 1);
            ptr::copy_nonoverlapping(&self.reserved, &mut clone.reserved, 1);
        }
        clone
    }
}

impl Copy for VersRec { }

impl Default for VersRec {
    fn default() -> Self {
        unsafe { mem::zeroed() }
    }
}

impl Eq for VersRec { }

impl fmt::Debug for VersRec {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("VersRec")
            .field("numericVersion", &self.numericVersion)
            .field("countryCode", &self.countryCode)
            .field("shortVersion", &str::from_utf8(&self.shortVersion).unwrap())
            .field("reserved", &str::from_utf8(&self.reserved).unwrap())
            .finish()
    }
}

impl Hash for VersRec {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u32(unsafe { mem::transmute(self.numericVersion) });
        state.write_i16(self.countryCode);
        state.write(&self.shortVersion);
        state.write(&self.reserved);
    }
}

impl PartialEq for VersRec {
    fn eq(&self, other: &Self) -> bool {
        #[inline]
        fn ptr<T>(slice: &[T]) -> *const c_void {
            slice.as_ptr() as *const _
        }

        unsafe {
            self.numericVersion == other.numericVersion &&
            self.countryCode == other.countryCode &&
            memcmp(ptr(&self.shortVersion), ptr(&other.shortVersion), mem::size_of::<Str255>()) == 0 &&
            memcmp(ptr(&self.reserved), ptr(&other.reserved), mem::size_of::<Str255>()) == 0
        }
    }
}

pub type VersRecPtr = *mut VersRec;
pub type VersRecHndl = *mut VersRecPtr;

pub type Byte = UInt8;
pub type SignedByte = SInt8;
pub type WidePtr = *mut wide;
pub type UnsignedWidePtr = *mut UnsignedWide;
pub type extended80 = Float80;
pub type extended96 = Float96;
pub type VHSelect = SInt8;

#[cfg(target_os = "macos")]
#[cfg_attr(target_os = "macos", link(name = "CoreServices", kind = "framework"))]
extern "C" {
    pub fn Debugger();
    pub fn DebugStr(debuggerMsg: ConstStr255Param);
    pub fn SysBreak();
    pub fn SysBreakStr(debuggerMsg: ConstStr255Param);
    pub fn SysBreakFunc(debuggerMsg: ConstStr255Param);
}

#[cfg(test)]
mod versrec_manual_derive_tests {
    use super::*;
    #[test]
    fn test_clone_and_eq() {
        let mut rec0 = VersRec::default();
        rec0.countryCode = 14;

        let random_string = b"Hello, world!A)R\xE2Q$";
        for i in 0..random_string.len() {
            rec0.shortVersion[i] = random_string[i];
        }

        let rec1 = rec0.clone();
        assert_eq!(rec0, rec1);
    }
}