Browse Source

Merge pull request #15 from FenrirWolf/std

Standard library support, for reals this time.
pull/10/head
Ronald Kinard 8 years ago committed by GitHub
parent
commit
20a7da8cfa
  1. 42
      README.md
  2. 36
      build.rs
  3. 14
      ctr-libc/Cargo.toml
  4. 1
      ctr-libc/README.md
  5. 122
      ctr-libc/src/constants.rs
  6. 39
      ctr-libc/src/functions.rs
  7. 177
      ctr-libc/src/lib.rs
  8. 7
      ctr-std/3ds.json
  9. 16
      ctr-std/Cargo.toml
  10. 5
      ctr-std/README.md
  11. 5
      ctr-std/Xargo.toml
  12. 35
      ctr-std/src/ascii.rs
  13. 497
      ctr-std/src/error.rs
  14. 1871
      ctr-std/src/f32.rs
  15. 1756
      ctr-std/src/f64.rs
  16. 849
      ctr-std/src/ffi/c_str.rs
  17. 24
      ctr-std/src/ffi/mod.rs
  18. 181
      ctr-std/src/ffi/os_str.rs
  19. 1153
      ctr-std/src/io/buffered.rs
  20. 600
      ctr-std/src/io/cursor.rs
  21. 594
      ctr-std/src/io/error.rs
  22. 296
      ctr-std/src/io/impls.rs
  23. 1990
      ctr-std/src/io/mod.rs
  24. 24
      ctr-std/src/io/prelude.rs
  25. 33
      ctr-std/src/io/print.rs
  26. 215
      ctr-std/src/io/util.rs
  27. 174
      ctr-std/src/lib.rs
  28. 481
      ctr-std/src/macros.rs
  29. 143
      ctr-std/src/memchr.rs
  30. 293
      ctr-std/src/num.rs
  31. 17
      ctr-std/src/os/mod.rs
  32. 34
      ctr-std/src/panicking.rs
  33. 617
      ctr-std/src/path.rs
  34. 146
      ctr-std/src/prelude/mod.rs
  35. 53
      ctr-std/src/prelude/v1.rs
  36. 36
      ctr-std/src/rt.rs
  37. 29
      ctr-std/src/sync/mod.rs
  38. 37
      ctr-std/src/sys/mod.rs
  39. 61
      ctr-std/src/sys/unix/ext/ffi.rs
  40. 41
      ctr-std/src/sys/unix/ext/mod.rs
  41. 51
      ctr-std/src/sys/unix/memchr.rs
  42. 50
      ctr-std/src/sys/unix/mod.rs
  43. 123
      ctr-std/src/sys/unix/os.rs
  44. 119
      ctr-std/src/sys/unix/os_str.rs
  45. 29
      ctr-std/src/sys/unix/path.rs
  46. 179
      ctr-std/src/sys_common/io.rs
  47. 76
      ctr-std/src/sys_common/mod.rs
  48. 31
      ctru-rs/3ds.json
  49. 19
      ctru-rs/Cargo.toml
  50. 44
      ctru-rs/README.md
  51. 9
      ctru-rs/Xargo.toml
  52. 37
      ctru-rs/src/console.rs
  53. 38
      ctru-rs/src/error.rs
  54. 14
      ctru-rs/src/gfx.rs
  55. 21
      ctru-rs/src/lib.rs
  56. 6
      ctru-rs/src/sdmc.rs
  57. 36
      ctru-rs/src/services/apt.rs
  58. 286
      ctru-rs/src/services/fs.rs
  59. 2
      ctru-rs/src/services/gspgpu.rs
  60. 8
      ctru-rs/src/services/hid.rs
  61. 0
      ctru-rs/src/services/mod.rs
  62. 6
      ctru-rs/src/srv.rs
  63. 5
      ctru-sys/Cargo.toml
  64. 1
      ctru-sys/src/applets/mod.rs
  65. 258
      ctru-sys/src/applets/swkbd.rs
  66. 37
      ctru-sys/src/gpu/gpu.rs
  67. 133
      ctru-sys/src/gpu/gx.rs
  68. 91
      ctru-sys/src/gpu/shaderProgram.rs
  69. 172
      ctru-sys/src/gpu/shbin.rs
  70. 13
      ctru-sys/src/lib.rs
  71. 82
      ctru-sys/src/ndsp/channel.rs
  72. 2
      ctru-sys/src/ndsp/mod.rs
  73. 112
      ctru-sys/src/ndsp/ndsp.rs
  74. 63
      ctru-sys/src/os.rs
  75. 64
      ctru-sys/src/romfs.rs
  76. 24
      ctru-sys/src/sdmc.rs
  77. 9
      ctru-sys/src/services/ac.rs
  78. 191
      ctru-sys/src/services/am.rs
  79. 18
      ctru-sys/src/services/ampxi.rs
  80. 320
      ctru-sys/src/services/apt.rs
  81. 378
      ctru-sys/src/services/cam.rs
  82. 19
      ctru-sys/src/services/cfgnor.rs
  83. 46
      ctru-sys/src/services/cfgu.rs
  84. 73
      ctru-sys/src/services/dsp.rs
  85. 369
      ctru-sys/src/services/fs.rs
  86. 107
      ctru-sys/src/services/gspgpu.rs
  87. 19
      ctru-sys/src/services/gsplcd.rs
  88. 13
      ctru-sys/src/services/hb.rs
  89. 97
      ctru-sys/src/services/hid.rs
  90. 149
      ctru-sys/src/services/httpc.rs
  91. 30
      ctru-sys/src/services/ir.rs
  92. 19
      ctru-sys/src/services/irrst.rs
  93. 35
      ctru-sys/src/services/mic.rs
  94. 8
      ctru-sys/src/services/mod.rs
  95. 67
      ctru-sys/src/services/mvd.rs
  96. 23
      ctru-sys/src/services/ndm.rs
  97. 53
      ctru-sys/src/services/news.rs
  98. 127
      ctru-sys/src/services/nfc.rs
  99. 16
      ctru-sys/src/services/ns.rs
  100. 31
      ctru-sys/src/services/pm.rs
  101. Some files were not shown because too many files have changed in this diff Show More

42
README.md

@ -1,41 +1,16 @@
# ctru-rs # ctru-rs
A Rust wrapper library for smealum's A Rust wrapper library for smealum's [ctrulib](https://github.com/smealum/ctrulib).
[ctrulib](https://github.com/smealum/ctrulib). Intended for use only when
targeting CTR.
## How to build See the [3DS project template](https://github.com/rust3ds/rust3ds-template) for instructions on how to use this library.
1. Install the devkitARM toolchain for your system. Make sure `DEVKITPRO` is ## Structure
set in your environment.
2. Modify ~/.cargo/config and add the following lines:
```toml This repository is organized as follows:
[target.3ds] * `ctru-rs`: Safe, idiomatic wrapper around `ctru-sys`.
ar = "/path/to/arm-none-eabi-ar" * `ctru-sys`: Low-level, unsafe bindings to ctrulib
``` * `ctr-std`: A partial implementation of the Rust standard library for the 3DS.
* `ctr-libc`: C types and functions used by ctru-sys and ctr-std.
3. Build with `cargo build --target 3ds.json`.
4. A dkA linkable .rlib (static library) will be generated. Read below for
instructions on using.
## How to use
You can build your homebrew projects through Cargo just as easily as any other
platform. Add this to your `Cargo.toml`:
```toml
[dependencies.ctru-rs]
git="https://github.com/rust3ds/ctru-rs"
```
**It is highly recommended to use the [template
project.](https://github.com/rust3ds/rust3ds-template)**
## Contributing
PR's are welcome. Organization of rust specific features and wrapper
functionality has not been decided on yet.
## License ## License
@ -66,3 +41,4 @@ applies to every file in the tree, unless otherwise noted.
Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses. Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.
See [LICENSE-APACHE](https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE), [LICENSE-MIT](https://github.com/rust-lang/rust/blob/master/LICENSE-MIT), and [COPYRIGHT](https://github.com/rust-lang/rust/blob/master/COPYRIGHT) for details. See [LICENSE-APACHE](https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE), [LICENSE-MIT](https://github.com/rust-lang/rust/blob/master/LICENSE-MIT), and [COPYRIGHT](https://github.com/rust-lang/rust/blob/master/COPYRIGHT) for details.

36
build.rs

@ -1,36 +0,0 @@
use std::env;
use std::path::PathBuf;
use std::fs;
use std::option::Option::{self, Some, None};
const ENV_DKP: &'static str = "CTRULIB";
fn find_libctru() -> Option<PathBuf> {
if let Ok(value) = env::var(ENV_DKP) {
let mut path = PathBuf::from(value);
path.push("lib");
// metadata returns Err if the dir does not exist
if let Ok(metadata) = fs::metadata(path.as_path()) {
if metadata.is_dir() {
return Some(path);
}
}
}
return None;
}
fn main() {
if let Some(path) = find_libctru() {
if let Some(s) = path.to_str() {
println!("cargo:rustc-link-lib=static=ctru");
println!("cargo:rustc-link-search=native={}", s);
} else {
println!("path is not a valid string");
std::process::exit(1);
}
} else {
println!("could not find libctru");
std::process::exit(1);
}
}

14
ctr-libc/Cargo.toml

@ -0,0 +1,14 @@
[package]
name = "ctr-libc"
version = "0.1.0"
authors = ["Fenrir <fenrirwolf@gmail.com>", "The Rust Project Developers"]
license = "MIT/Apache 2.0"
description = """
A library for types and bindings to native C functions found in newlib
for devkitARM
"""
[features]
default = ["use_std"]
use_std = []

1
ctr-libc/README.md

@ -0,0 +1 @@
Extended libc bindings for use with ctr-std. This library is experimental. Use of some functions might result in undefined symbols.

122
ctr-libc/src/constants.rs

@ -0,0 +1,122 @@
// Many of these constants are unused/unnecessary. But let's keep them around for now.
pub const STDIN_FILENO: ::c_int = 0;
pub const STDOUT_FILENO: ::c_int = 1;
pub const STDERR_FILENO: ::c_int = 2;
pub const EPERM: ::c_int = 1;
pub const ENOENT: ::c_int = 2;
pub const ESRCH: ::c_int = 3;
pub const EINTR: ::c_int = 4;
pub const EIO: ::c_int = 5;
pub const ENXIO: ::c_int = 6;
pub const E2BIG: ::c_int = 7;
pub const ENOEXEC: ::c_int = 8;
pub const EBADF: ::c_int = 9;
pub const ECHILD: ::c_int = 10;
pub const EAGAIN: ::c_int = 11;
pub const ENOMEM: ::c_int = 12;
pub const EACCES: ::c_int = 13;
pub const EFAULT: ::c_int = 14;
pub const EBUSY: ::c_int = 16;
pub const EEXIST: ::c_int = 17;
pub const EXDEV: ::c_int = 18;
pub const ENODEV: ::c_int = 19;
pub const ENOTDIR: ::c_int = 20;
pub const EISDIR: ::c_int = 21;
pub const EINVAL: ::c_int = 22;
pub const ENFILE: ::c_int = 23;
pub const EMFILE: ::c_int = 24;
pub const ENOTTY: ::c_int = 25;
pub const ETXTBSY: ::c_int = 26;
pub const EFBIG: ::c_int = 27;
pub const ENOSPC: ::c_int = 28;
pub const ESPIPE: ::c_int = 29;
pub const EROFS: ::c_int = 30;
pub const EMLINK: ::c_int = 31;
pub const EPIPE: ::c_int = 32;
pub const EDOM: ::c_int = 33;
pub const ERANGE: ::c_int = 34;
pub const ENOMSG: ::c_int = 35;
pub const EIDRM: ::c_int = 36;
pub const EDEADLK: ::c_int = 45;
pub const ENOLCK: ::c_int = 46;
pub const ENOSTR: ::c_int = 60;
pub const ENODATA: ::c_int = 61;
pub const ETIME: ::c_int = 62;
pub const ENOSR: ::c_int = 63;
pub const ENOLINK: ::c_int = 67;
pub const EPROTO: ::c_int = 71;
pub const EMULTIHOP: ::c_int = 74;
pub const EBADMSG: ::c_int = 77;
pub const EFTYPE: ::c_int = 79;
pub const ENOSYS: ::c_int = 88;
pub const ENOTEMPTY: ::c_int = 90;
pub const ENAMETOOLONG: ::c_int = 91;
pub const ELOOP: ::c_int = 92;
pub const EOPNOTSUPP: ::c_int = 95;
pub const EPFNOSUPPORT: ::c_int = 96;
pub const ECONNRESET: ::c_int = 104;
pub const ENOBUFS: ::c_int = 105;
pub const EAFNOSUPPORT: ::c_int = 106;
pub const EPROTOTYPE: ::c_int = 107;
pub const ENOTSOCK: ::c_int = 108;
pub const ENOPROTOOPT: ::c_int = 109;
pub const ECONNREFUSED: ::c_int = 111;
pub const EADDRINUSE: ::c_int = 112;
pub const ECONNABORTED: ::c_int = 113;
pub const ENETUNREACH: ::c_int = 114;
pub const ENETDOWN: ::c_int = 115;
pub const ETIMEDOUT: ::c_int = 116;
pub const EHOSTDOWN: ::c_int = 117;
pub const EHOSTUNREACH: ::c_int = 118;
pub const EINPROGRESS: ::c_int = 119;
pub const EALREADY: ::c_int = 120;
pub const EDESTADDRREQ: ::c_int = 121;
pub const EMSGSIZE: ::c_int = 122;
pub const EPROTONOSUPPORT: ::c_int = 123;
pub const EADDRNOTAVAIL: ::c_int = 125;
pub const ENETRESET: ::c_int = 126;
pub const EISCONN: ::c_int = 127;
pub const ENOTCONN: ::c_int = 128;
pub const ETOOMANYREFS: ::c_int = 129;
pub const EDQUOT: ::c_int = 132;
pub const ESTALE: ::c_int = 133;
pub const ENOTSUP: ::c_int = 134;
pub const EILSEQ: ::c_int = 138;
pub const EOVERFLOW: ::c_int = 139;
pub const ECANCELED: ::c_int = 140;
pub const ENOTRECOVERABLE: ::c_int = 141;
pub const EOWNERDEAD: ::c_int = 142;
pub const EWOULDBLOCK: ::c_int = 11;
pub const __ELASTERROR: ::c_int = 2000;
pub const O_RDONLY: ::c_int = 0;
pub const O_WRONLY: ::c_int = 1;
pub const O_RDWR: ::c_int = 2;
pub const O_APPEND: ::c_int = 8;
pub const O_CREAT: ::c_int = 512;
pub const O_TRUNC: ::c_int = 1024;
pub const O_EXCL: ::c_int = 2048;
pub const O_SYNC: ::c_int = 8192;
pub const O_NONBLOCK: ::c_int = 16384;
pub const O_NOCTTY: ::c_int = 32768;
pub const FD_CLOEXEC: ::c_int = 1;
pub const DT_FIFO: u8 = 1;
pub const DT_CHR: u8 = 2;
pub const DT_DIR: u8 = 4;
pub const DT_BLK: u8 = 6;
pub const DT_REG: u8 = 8;
pub const DT_LNK: u8 = 10;
pub const DT_SOCK: u8 = 12;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_ACCMODE: ::c_int = 3;
pub const SEEK_SET: ::c_int = 0;
pub const SEEK_CUR: ::c_int = 1;
pub const SEEK_END: ::c_int = 2;
pub const SIG_IGN: ::sighandler_t = 1 as ::sighandler_t;
pub const SIGPIPE: ::c_int = 13;

39
ctr-libc/src/functions.rs

@ -0,0 +1,39 @@
extern "C" {
pub fn abort() -> !;
pub fn chdir(dir: *const ::c_char) -> ::c_int;
pub fn chmod(path: *const ::c_char, mode: ::mode_t) -> ::c_int;
pub fn close(fd: ::c_int) -> ::c_int;
pub fn closedir(dirp: *mut ::DIR) -> ::c_int;
pub fn exit(status: ::c_int) -> !;
pub fn fchmod(fd: ::c_int, mode: ::mode_t) -> ::c_int;
pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int;
pub fn fdatasync(fd: ::c_int) -> ::c_int;
pub fn free(p: *mut ::c_void);
pub fn fstat(fildes: ::c_int, buf: *mut ::stat) -> ::c_int;
pub fn ftruncate(fd: ::c_int, length: ::off_t) -> ::c_int;
pub fn fsync(fd: ::c_int) -> ::c_int;
pub fn getcwd(buf: *mut ::c_char, size: ::size_t) -> *mut ::c_char;
pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int;
pub fn link(src: *const ::c_char, dst: *const ::c_char) -> ::c_int;
pub fn lstat(path: *const ::c_char, buf: *mut ::stat) -> ::c_int;
pub fn lseek(fd: ::c_int, offset: ::off_t, whence: ::c_int) -> ::off_t;
pub fn memchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
pub fn mkdir(path: *const ::c_char, mode: ::mode_t) -> ::c_int;
pub fn open(path: *const ::c_char, oflag: ::c_int, ...) -> ::c_int;
pub fn opendir(dirname: *const ::c_char) -> *mut ::DIR;
pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: ::off_t) -> ::ssize_t;
pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: ::off_t) -> ::ssize_t;
pub fn read(fd: ::c_int, puf: *mut ::c_void, count: ::size_t) -> ::ssize_t;
pub fn readlink(path: *const ::c_char, buf: *mut ::c_char, bufsz: ::size_t) -> ::ssize_t;
pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) -> ::c_int;
pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char;
pub fn rename(oldname: *const ::c_char, newname: *const ::c_char) -> ::c_int;
pub fn rmdir(path: *const ::c_char) -> ::c_int;
pub fn signal(signum: ::c_int, handler: ::sighandler_t) -> ::sighandler_t;
pub fn stat(path: *const ::c_char, buf: *mut ::stat) -> ::c_int;
pub fn strlen(cs: *const ::c_char) -> ::size_t;
pub fn symlink(path1: *const ::c_char, path2: *const ::c_char) -> ::c_int;
pub fn unlink(c: *const ::c_char) -> ::c_int;
pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t;
}

177
ctr-libc/src/lib.rs

@ -0,0 +1,177 @@
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(bad_style, overflowing_literals, improper_ctypes, non_camel_case_types)]
#![no_std]
mod constants;
mod functions;
pub use constants::*;
pub use functions::*;
#[link(name = "c")]
#[link(name = "m")]
extern {}
#[repr(u8)]
pub enum c_void {
__variant1,
__variant2,
}
// char is u8 on ARM
pub type c_char = u8;
pub type c_schar = i8;
pub type c_uchar = u8;
pub type c_short = i16;
pub type c_ushort = u16;
pub type c_int = i32;
pub type c_uint = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type c_longlong = i64;
pub type c_ulonglong = u64;
// 4 bytes on ARM
pub type c_long = i32;
pub type c_ulong = u32;
pub type size_t = usize;
pub type ptrdiff_t = isize;
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ssize_t = isize;
// devkitARM says wchar_t is 4 bytes. Nintendo's API says it's 2 bytes.
// hope you never have to interact between the two...
pub type wchar_t = c_int;
pub type int8_t = i8;
pub type uint8_t = u8;
pub type int16_t = i16;
pub type uint16_t = u16;
pub type int32_t = i32;
pub type uint32_t = u32;
pub type int64_t = i64;
pub type uint64_t = u64;
pub type time_t = i32;
pub type clockid_t = c_int;
pub type mode_t = u32;
pub type sighandler_t = size_t;
pub type dev_t = u32;
pub type nlink_t = u32;
pub type uid_t = u32;
pub type gid_t = u32;
pub type off_t = i64;
pub type blksize_t = i32;
pub type blkcnt_t = c_ulong;
pub type fsblkcnt_t = uint64_t;
pub type fsfilcnt_t = uint32_t;
pub type ino_t = u32;
pub type suseconds_t = i32;
pub type error_t = c_int;
pub enum timezone {}
pub enum _reent {}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct itimerspec {
pub it_interval: timespec,
pub it_value: timespec,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct tm {
pub tm_sec: c_int,
pub tm_min: c_int,
pub tm_hour: c_int,
pub tm_mday: c_int,
pub tm_mon: c_int,
pub tm_year: c_int,
pub tm_wday: c_int,
pub tm_yday: c_int,
pub tm_isdst: c_int,
}
pub enum DIR {}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_mode: mode_t,
pub st_nlink: nlink_t,
pub st_uid: uid_t,
pub st_gid: gid_t,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_atime: time_t,
pub st_spare1: c_long,
pub st_mtime: time_t,
pub st_spare2: c_long,
pub st_ctime: time_t,
pub st_spare3: c_long,
pub st_blksize: blksize_t,
pub st_blocks: blkcnt_t,
pub st_spare4: [c_long; 2usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct statvfs {
pub f_bsize: c_ulong,
pub f_frsize: c_ulong,
pub f_blocks: fsblkcnt_t,
pub f_bfree: fsblkcnt_t,
pub f_bavail: fsblkcnt_t,
pub f_files: fsfilcnt_t,
pub f_ffree: fsfilcnt_t,
pub f_favail: fsfilcnt_t,
pub f_fsid: c_ulong,
pub f_flag: c_ulong,
pub f_namemax: c_ulong,
}
#[repr(C)]
#[derive(Copy)]
pub struct dirent {
pub d_ino: ino_t,
pub d_type: c_uchar,
pub d_name: [c_char; 256usize],
}
impl Clone for dirent {
fn clone(&self) -> Self { *self }
}

7
3ds.json → ctr-std/3ds.json

@ -5,15 +5,16 @@
"ar": "arm-none-eabi-ar", "ar": "arm-none-eabi-ar",
"target-endian": "little", "target-endian": "little",
"target-pointer-width": "32", "target-pointer-width": "32",
"target-family": "unix",
"arch": "arm", "arch": "arm",
"os": "linux", "os": "linux",
"env": "newlib",
"cpu": "mpcore", "cpu": "mpcore",
"features": "+vfp2", "features": "+vfp2",
"relocation-model": "static", "relocation-model": "static",
"disable-redzone": true,
"executables": true, "executables": true,
"no-compiler-rt": true,
"exe-suffix": ".elf", "exe-suffix": ".elf",
"panic-strategy": "abort",
"pre-link-args": [ "pre-link-args": [
"-specs=3dsx.specs", "-specs=3dsx.specs",
"-march=armv6k", "-march=armv6k",
@ -25,8 +26,6 @@
"-lc", "-lc",
"-lm", "-lm",
"-lsysbase", "-lsysbase",
"-lc",
"-lgcc",
"-lc" "-lc"
] ]
} }

16
ctr-std/Cargo.toml

@ -0,0 +1,16 @@
[package]
name = "std"
version = "0.0.0"
license = "MIT/Apache 2.0"
[dependencies.compiler_builtins]
git = "https://github.com/rust-lang-nursery/compiler-builtins"
[dependencies.ctr-libc]
path = "../ctr-libc"
[dependencies.alloc_system]
version = "0.1.1"
[dependencies.spin]
version = "0.4"

5
ctr-std/README.md

@ -0,0 +1,5 @@
A work-in-progress port of the Rust Standard Library for the Nintendo 3DS, based on [ctrulib](https://github.com/smealum/ctrulib/) and the [devkitARM](http://devkitPro.org) toolchain.
## Structure
This library aims to mimick the Rust standard library's public interface as closely as possible, exposing functionality that is common between the 3DS and other platforms. System-specific functionality such as control input, save file management, GPU features, and so forth are implemented in `ctru-rs`.

5
ctr-std/Xargo.toml

@ -0,0 +1,5 @@
[dependencies.collections]
[dependencies.ctr-libc]
path = "../ctr-libc"
stage = 1

35
src/ascii.rs → ctr-std/src/ascii.rs

@ -10,9 +10,11 @@
//! Operations on ASCII strings and characters. //! Operations on ASCII strings and characters.
use core::mem; #![stable(feature = "rust1", since = "1.0.0")]
use core::ops::Range;
use collections::{String, Vec}; use mem;
use ops::Range;
use iter::FusedIterator;
/// Extension methods for ASCII-subset only operations on string slices. /// Extension methods for ASCII-subset only operations on string slices.
/// ///
@ -36,8 +38,10 @@ use collections::{String, Vec};
/// it will not get mapped to an uppercase variant, resulting in `"CAF\u{e9}"`. /// it will not get mapped to an uppercase variant, resulting in `"CAF\u{e9}"`.
/// ///
/// [combining character]: https://en.wikipedia.org/wiki/Combining_character /// [combining character]: https://en.wikipedia.org/wiki/Combining_character
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsciiExt { pub trait AsciiExt {
/// Container type for copied ASCII characters. /// Container type for copied ASCII characters.
#[stable(feature = "rust1", since = "1.0.0")]
type Owned; type Owned;
/// Checks if the value is within the ASCII range. /// Checks if the value is within the ASCII range.
@ -53,6 +57,7 @@ pub trait AsciiExt {
/// assert!(ascii.is_ascii()); /// assert!(ascii.is_ascii());
/// assert!(!utf8.is_ascii()); /// assert!(!utf8.is_ascii());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn is_ascii(&self) -> bool; fn is_ascii(&self) -> bool;
/// Makes a copy of the string in ASCII upper case. /// Makes a copy of the string in ASCII upper case.
@ -71,6 +76,7 @@ pub trait AsciiExt {
/// assert_eq!('A', ascii.to_ascii_uppercase()); /// assert_eq!('A', ascii.to_ascii_uppercase());
/// assert_eq!('❤', utf8.to_ascii_uppercase()); /// assert_eq!('❤', utf8.to_ascii_uppercase());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn to_ascii_uppercase(&self) -> Self::Owned; fn to_ascii_uppercase(&self) -> Self::Owned;
/// Makes a copy of the string in ASCII lower case. /// Makes a copy of the string in ASCII lower case.
@ -89,6 +95,7 @@ pub trait AsciiExt {
/// assert_eq!('a', ascii.to_ascii_lowercase()); /// assert_eq!('a', ascii.to_ascii_lowercase());
/// assert_eq!('❤', utf8.to_ascii_lowercase()); /// assert_eq!('❤', utf8.to_ascii_lowercase());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn to_ascii_lowercase(&self) -> Self::Owned; fn to_ascii_lowercase(&self) -> Self::Owned;
/// Checks that two strings are an ASCII case-insensitive match. /// Checks that two strings are an ASCII case-insensitive match.
@ -110,6 +117,7 @@ pub trait AsciiExt {
/// assert!(ascii1.eq_ignore_ascii_case(&ascii3)); /// assert!(ascii1.eq_ignore_ascii_case(&ascii3));
/// assert!(!ascii1.eq_ignore_ascii_case(&ascii4)); /// assert!(!ascii1.eq_ignore_ascii_case(&ascii4));
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn eq_ignore_ascii_case(&self, other: &Self) -> bool; fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
/// Converts this type to its ASCII upper case equivalent in-place. /// Converts this type to its ASCII upper case equivalent in-place.
@ -127,6 +135,7 @@ pub trait AsciiExt {
/// ///
/// assert_eq!('A', ascii); /// assert_eq!('A', ascii);
/// ``` /// ```
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_uppercase(&mut self); fn make_ascii_uppercase(&mut self);
/// Converts this type to its ASCII lower case equivalent in-place. /// Converts this type to its ASCII lower case equivalent in-place.
@ -144,9 +153,11 @@ pub trait AsciiExt {
/// ///
/// assert_eq!('a', ascii); /// assert_eq!('a', ascii);
/// ``` /// ```
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_lowercase(&mut self); fn make_ascii_lowercase(&mut self);
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsciiExt for str { impl AsciiExt for str {
type Owned = String; type Owned = String;
@ -187,6 +198,7 @@ impl AsciiExt for str {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsciiExt for [u8] { impl AsciiExt for [u8] {
type Owned = Vec<u8>; type Owned = Vec<u8>;
#[inline] #[inline]
@ -229,6 +241,7 @@ impl AsciiExt for [u8] {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsciiExt for u8 { impl AsciiExt for u8 {
type Owned = u8; type Owned = u8;
#[inline] #[inline]
@ -247,6 +260,7 @@ impl AsciiExt for u8 {
fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsciiExt for char { impl AsciiExt for char {
type Owned = char; type Owned = char;
#[inline] #[inline]
@ -285,6 +299,7 @@ impl AsciiExt for char {
/// An iterator over the escaped version of a byte, constructed via /// An iterator over the escaped version of a byte, constructed via
/// `std::ascii::escape_default`. /// `std::ascii::escape_default`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct EscapeDefault { pub struct EscapeDefault {
range: Range<usize>, range: Range<usize>,
data: [u8; 4], data: [u8; 4],
@ -315,6 +330,7 @@ pub struct EscapeDefault {
/// assert_eq!(b'\\', escaped.next().unwrap()); /// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b't', escaped.next().unwrap()); /// assert_eq!(b't', escaped.next().unwrap());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn escape_default(c: u8) -> EscapeDefault { pub fn escape_default(c: u8) -> EscapeDefault {
let (data, len) = match c { let (data, len) = match c {
b'\t' => ([b'\\', b't', 0, 0], 2), b'\t' => ([b'\\', b't', 0, 0], 2),
@ -337,17 +353,23 @@ pub fn escape_default(c: u8) -> EscapeDefault {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for EscapeDefault { impl Iterator for EscapeDefault {
type Item = u8; type Item = u8;
fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) } fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() } fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl DoubleEndedIterator for EscapeDefault { impl DoubleEndedIterator for EscapeDefault {
fn next_back(&mut self) -> Option<u8> { fn next_back(&mut self) -> Option<u8> {
self.range.next_back().map(|i| self.data[i]) self.range.next_back().map(|i| self.data[i])
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for EscapeDefault {} impl ExactSizeIterator for EscapeDefault {}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}
static ASCII_LOWERCASE_MAP: [u8; 256] = [ static ASCII_LOWERCASE_MAP: [u8; 256] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@ -431,8 +453,7 @@ static ASCII_UPPERCASE_MAP: [u8; 256] = [
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use rustc_unicode::char::from_u32; use char::from_u32;
use collections::string::ToString;
#[test] #[test]
fn test_is_ascii() { fn test_is_ascii() {
@ -447,9 +468,7 @@ mod tests {
assert!("banana\0\u{7F}".is_ascii()); assert!("banana\0\u{7F}".is_ascii());
assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii())); assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii()));
assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii())); assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii()));
assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii()));
// NOTE: This test fails for some reason.
assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii()));
} }
#[test] #[test]

497
ctr-std/src/error.rs

@ -0,0 +1,497 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in [`Result<T, E>`]. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail (via
//! [`Display`]) and cause chain information:
//!
//! ```
//! use std::fmt::Display;
//!
//! trait Error: Display {
//! fn description(&self) -> &str;
//!
//! fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The [`cause`] method is generally used when errors cross "abstraction
//! boundaries", i.e. when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via [`cause`] chains.
//!
//! [`Result<T, E>`]: ../result/enum.Result.html
//! [`Display`]: ../fmt/trait.Display.html
//! [`cause`]: trait.Error.html#method.cause
#![stable(feature = "rust1", since = "1.0.0")]
// A note about crates and the facade:
//
// Originally, the `Error` trait was defined in libcore, and the impls
// were scattered about. However, coherence objected to this
// arrangement, because to create the blanket impls for `Box` required
// knowing that `&str: !Error`, and we have no means to deal with that
// sort of conflict just now. Therefore, for the time being, we have
// moved the `Error` trait into libstd. As we evolve a sol'n to the
// coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in.
use any::TypeId;
use cell;
use char;
use fmt::{self, Debug, Display};
use mem::transmute;
use num;
use str;
use string;
/// Base functionality for all errors in Rust.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display {
/// A short description of the error.
///
/// The description should only be used for a simple message.
/// It should not contain newlines or sentence-ending punctuation,
/// to facilitate embedding in larger user-facing strings.
/// For showing formatted error messages with more information see
/// [`Display`].
///
/// [`Display`]: ../fmt/trait.Display.html
///
/// # Examples
///
/// ```
/// use std::error::Error;
///
/// match "xc".parse::<u32>() {
/// Err(e) => {
/// println!("Error: {}", e.description());
/// }
/// _ => println!("No error"),
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn description(&self) -> &str;
/// The lower-level cause of this error, if any.
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::fmt;
///
/// #[derive(Debug)]
/// struct SuperError {
/// side: SuperErrorSideKick,
/// }
///
/// impl fmt::Display for SuperError {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "SuperError is here!")
/// }
/// }
///
/// impl Error for SuperError {
/// fn description(&self) -> &str {
/// "I'm the superhero of errors!"
/// }
///
/// fn cause(&self) -> Option<&Error> {
/// Some(&self.side)
/// }
/// }
///
/// #[derive(Debug)]
/// struct SuperErrorSideKick;
///
/// impl fmt::Display for SuperErrorSideKick {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "SuperErrorSideKick is here!")
/// }
/// }
///
/// impl Error for SuperErrorSideKick {
/// fn description(&self) -> &str {
/// "I'm SuperError side kick!"
/// }
/// }
///
/// fn get_super_error() -> Result<(), SuperError> {
/// Err(SuperError { side: SuperErrorSideKick })
/// }
///
/// fn main() {
/// match get_super_error() {
/// Err(e) => {
/// println!("Error: {}", e.description());
/// println!("Caused by: {}", e.cause().unwrap());
/// }
/// _ => println!("No error"),
/// }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn cause(&self) -> Option<&Error> { None }
/// Get the `TypeId` of `self`
#[doc(hidden)]
#[unstable(feature = "error_type_id",
reason = "unclear whether to commit to this public implementation detail",
issue = "27745")]
fn type_id(&self) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
fn from(err: E) -> Box<Error + 'a> {
Box::new(err)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
fn from(err: E) -> Box<Error + Send + Sync + 'a> {
Box::new(err)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<Error + Send + Sync> {
fn from(err: String) -> Box<Error + Send + Sync> {
#[derive(Debug)]
struct StringError(String);
impl Error for StringError {
fn description(&self) -> &str { &self.0 }
}
impl Display for StringError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
Box::new(StringError(err))
}
}
#[stable(feature = "string_box_error", since = "1.7.0")]
impl From<String> for Box<Error> {
fn from(str_err: String) -> Box<Error> {
let err1: Box<Error + Send + Sync> = From::from(str_err);
let err2: Box<Error> = err1;
err2
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}
#[stable(feature = "string_box_error", since = "1.7.0")]
impl<'a> From<&'a str> for Box<Error> {
fn from(err: &'a str) -> Box<Error> {
From::from(String::from(err))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
fn description(&self) -> &str { "failed to parse bool" }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
fn description(&self) -> &str {
"invalid utf-8: corrupt contents"
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
fn description(&self) -> &str {
self.__description()
}
}
#[unstable(feature = "try_from", issue = "33417")]
impl Error for num::TryFromIntError {
fn description(&self) -> &str {
self.__description()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
fn description(&self) -> &str {
self.__description()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
fn description(&self) -> &str {
"invalid utf-8"
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
fn description(&self) -> &str {
"invalid utf-16"
}
}
#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
fn description(&self) -> &str {
match *self {}
}
}
#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
fn description(&self) -> &str {
"unpaired surrogate found"
}
}
#[stable(feature = "box_error", since = "1.7.0")]
impl<T: Error> Error for Box<T> {
fn description(&self) -> &str {
Error::description(&**self)
}
fn cause(&self) -> Option<&Error> {
Error::cause(&**self)
}
}
#[stable(feature = "fmt_error", since = "1.11.0")]
impl Error for fmt::Error {
fn description(&self) -> &str {
"an error occurred when formatting an argument"
}
}
#[stable(feature = "try_borrow", since = "1.13.0")]
impl Error for cell::BorrowError {
fn description(&self) -> &str {
"already mutably borrowed"
}
}
#[stable(feature = "try_borrow", since = "1.13.0")]
impl Error for cell::BorrowMutError {
fn description(&self) -> &str {
"already borrowed"
}
}
#[unstable(feature = "try_from", issue = "33417")]
impl Error for char::CharTryFromError {
fn description(&self) -> &str {
"converted integer out of range for `char`"
}
}
// copied from any.rs
impl Error + 'static {
/// Returns true if the boxed type is the same as `T`
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
// Get TypeId of the type this function is instantiated with
let t = TypeId::of::<T>();
// Get TypeId of the type in the trait object
let boxed = self.type_id();
// Compare both TypeIds on equality
t == boxed
}
/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
if self.is::<T>() {
unsafe {
Some(&*(self as *const Error as *const T))
}
} else {
None
}
}
/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
unsafe {
Some(&mut *(self as *mut Error as *mut T))
}
} else {
None
}
}
}
impl Error + 'static + Send {
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
<Error + 'static>::is::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
<Error + 'static>::downcast_ref::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
<Error + 'static>::downcast_mut::<T>(self)
}
}
impl Error + 'static + Send + Sync {
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
<Error + 'static>::is::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
<Error + 'static>::downcast_ref::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
<Error + 'static>::downcast_mut::<T>(self)
}
}
impl Error {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
if self.is::<T>() {
unsafe {
let raw: *mut Error = Box::into_raw(self);
Ok(Box::from_raw(raw as *mut T))
}
} else {
Err(self)
}
}
}
impl Error + Send {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>)
-> Result<Box<T>, Box<Error + Send>> {
let err: Box<Error> = self;
<Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send marker
transmute::<Box<Error>, Box<Error + Send>>(s)
})
}
}
impl Error + Send + Sync {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>)
-> Result<Box<T>, Box<Self>> {
let err: Box<Error> = self;
<Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send+Sync marker
transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
})
}
}
#[cfg(test)]
mod tests {
use super::Error;
use fmt;
#[derive(Debug, PartialEq)]
struct A;
#[derive(Debug, PartialEq)]
struct B;
impl fmt::Display for A {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "A")
}
}
impl fmt::Display for B {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "B")
}
}
impl Error for A {
fn description(&self) -> &str { "A-desc" }
}
impl Error for B {
fn description(&self) -> &str { "A-desc" }
}
#[test]
fn downcasting() {
let mut a = A;
let mut a = &mut a as &mut (Error + 'static);
assert_eq!(a.downcast_ref::<A>(), Some(&A));
assert_eq!(a.downcast_ref::<B>(), None);
assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
assert_eq!(a.downcast_mut::<B>(), None);
let a: Box<Error> = Box::new(A);
match a.downcast::<B>() {
Ok(..) => panic!("expected error"),
Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
}
}
}

1871
ctr-std/src/f32.rs

File diff suppressed because it is too large Load Diff

1756
ctr-std/src/f64.rs

File diff suppressed because it is too large Load Diff

849
ctr-std/src/ffi/c_str.rs

@ -0,0 +1,849 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ascii;
use borrow::{Cow, Borrow};
use cmp::Ordering;
use error::Error;
use fmt::{self, Write};
use io;
use libc::{self, c_char};
use mem;
use memchr;
use ops;
use ptr;
use slice;
use str::{self, Utf8Error};
/// A type representing an owned C-compatible string
///
/// This type serves the primary purpose of being able to safely generate a
/// C-compatible string from a Rust byte slice or vector. An instance of this
/// type is a static guarantee that the underlying bytes contain no interior 0
/// bytes and the final byte is 0.
///
/// A `CString` is created from either a byte slice or a byte vector. After
/// being created, a `CString` predominately inherits all of its methods from
/// the `Deref` implementation to `[c_char]`. Note that the underlying array
/// is represented as an array of `c_char` as opposed to `u8`. A `u8` slice
/// can be obtained with the `as_bytes` method. Slices produced from a `CString`
/// do *not* contain the trailing nul terminator unless otherwise specified.
///
/// # Examples
///
/// ```no_run
/// # fn main() {
/// use std::ffi::CString;
/// use std::os::raw::c_char;
///
/// extern {
/// fn my_printer(s: *const c_char);
/// }
///
/// let c_to_print = CString::new("Hello, world!").unwrap();
/// unsafe {
/// my_printer(c_to_print.as_ptr());
/// }
/// # }
/// ```
///
/// # Safety
///
/// `CString` is intended for working with traditional C-style strings
/// (a sequence of non-null bytes terminated by a single null byte); the
/// primary use case for these kinds of strings is interoperating with C-like
/// code. Often you will need to transfer ownership to/from that external
/// code. It is strongly recommended that you thoroughly read through the
/// documentation of `CString` before use, as improper ownership management
/// of `CString` instances can lead to invalid memory accesses, memory leaks,
/// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CString {
// Invariant 1: the slice ends with a zero byte and has a length of at least one.
// Invariant 2: the slice contains only one zero byte.
// Improper usage of unsafe function can break Invariant 2, but not Invariant 1.
inner: Box<[u8]>,
}
/// Representation of a borrowed C string.
///
/// This dynamically sized type is only safely constructed via a borrowed
/// version of an instance of `CString`. This type can be constructed from a raw
/// C string as well and represents a C string borrowed from another location.
///
/// Note that this structure is **not** `repr(C)` and is not recommended to be
/// placed in the signatures of FFI functions. Instead safe wrappers of FFI
/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
/// interface to other consumers.
///
/// # Examples
///
/// Inspecting a foreign C string
///
/// ```no_run
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
///
/// extern { fn my_string() -> *const c_char; }
///
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
/// println!("string length: {}", slice.to_bytes().len());
/// }
/// ```
///
/// Passing a Rust-originating C string
///
/// ```no_run
/// use std::ffi::{CString, CStr};
/// use std::os::raw::c_char;
///
/// fn work(data: &CStr) {
/// extern { fn work_with(data: *const c_char); }
///
/// unsafe { work_with(data.as_ptr()) }
/// }
///
/// let s = CString::new("data data data data").unwrap();
/// work(&s);
/// ```
///
/// Converting a foreign C string into a Rust `String`
///
/// ```no_run
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
///
/// extern { fn my_string() -> *const c_char; }
///
/// fn my_string_safe() -> String {
/// unsafe {
/// CStr::from_ptr(my_string()).to_string_lossy().into_owned()
/// }
/// }
///
/// println!("string: {}", my_string_safe());
/// ```
#[derive(Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CStr {
// FIXME: this should not be represented with a DST slice but rather with
// just a raw `c_char` along with some form of marker to make
// this an unsized type. Essentially `sizeof(&CStr)` should be the
// same as `sizeof(&c_char)` but `CStr` should be an unsized type.
inner: [c_char]
}
/// An error returned from `CString::new` to indicate that a nul byte was found
/// in the vector provided.
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct NulError(usize, Vec<u8>);
/// An error returned from `CStr::from_bytes_with_nul` to indicate that a nul
/// byte was found too early in the slice provided or one wasn't found at all.
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub struct FromBytesWithNulError { _a: () }
/// An error returned from `CString::into_string` to indicate that a UTF-8 error
/// was encountered during the conversion.
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "cstring_into", since = "1.7.0")]
pub struct IntoStringError {
inner: CString,
error: Utf8Error,
}
impl CString {
/// Creates a new C-compatible string from a container of bytes.
///
/// This method will consume the provided data and use the underlying bytes
/// to construct a new string, ensuring that there is a trailing 0 byte.
///
/// # Examples
///
/// ```no_run
/// use std::ffi::CString;
/// use std::os::raw::c_char;
///
/// extern { fn puts(s: *const c_char); }
///
/// let to_print = CString::new("Hello!").unwrap();
/// unsafe {
/// puts(to_print.as_ptr());
/// }
/// ```
///
/// # Errors
///
/// This function will return an error if the bytes yielded contain an
/// internal 0 byte. The error returned will contain the bytes as well as
/// the position of the nul byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
Self::_new(t.into())
}
fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
match memchr::memchr(0, &bytes) {
Some(i) => Err(NulError(i, bytes)),
None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
}
}
/// Creates a C-compatible string from a byte vector without checking for
/// interior 0 bytes.
///
/// This method is equivalent to `new` except that no runtime assertion
/// is made that `v` contains no 0 bytes, and it requires an actual
/// byte vector, not anything that can be converted to one with Into.
///
/// # Examples
///
/// ```
/// use std::ffi::CString;
///
/// let raw = b"foo".to_vec();
/// unsafe {
/// let c_string = CString::from_vec_unchecked(raw);
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
v.reserve_exact(1);
v.push(0);
CString { inner: v.into_boxed_slice() }
}
/// Retakes ownership of a `CString` that was transferred to C.
///
/// Additionally, the length of the string will be recalculated from the pointer.
///
/// # Safety
///
/// This should only ever be called with a pointer that was earlier
/// obtained by calling `into_raw` on a `CString`. Other usage (e.g. trying to take
/// ownership of a string that was allocated by foreign code) is likely to lead
/// to undefined behavior or allocator corruption.
#[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
let len = libc::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts(ptr, len as usize);
CString { inner: mem::transmute(slice) }
}
/// Transfers ownership of the string to a C caller.
///
/// The pointer must be returned to Rust and reconstituted using
/// `from_raw` to be properly deallocated. Specifically, one
/// should *not* use the standard C `free` function to deallocate
/// this string.
///
/// Failure to call `from_raw` will lead to a memory leak.
#[stable(feature = "cstr_memory", since = "1.4.0")]
pub fn into_raw(self) -> *mut c_char {
Box::into_raw(self.into_inner()) as *mut c_char
}
/// Converts the `CString` into a `String` if it contains valid Unicode data.
///
/// On failure, ownership of the original `CString` is returned.
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_string(self) -> Result<String, IntoStringError> {
String::from_utf8(self.into_bytes())
.map_err(|e| IntoStringError {
error: e.utf8_error(),
inner: unsafe { CString::from_vec_unchecked(e.into_bytes()) },
})
}
/// Returns the underlying byte buffer.
///
/// The returned buffer does **not** contain the trailing nul separator and
/// it is guaranteed to not have any interior nul bytes.
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_bytes(self) -> Vec<u8> {
let mut vec = self.into_inner().into_vec();
let _nul = vec.pop();
debug_assert_eq!(_nul, Some(0u8));
vec
}
/// Equivalent to the `into_bytes` function except that the returned vector
/// includes the trailing nul byte.
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_bytes_with_nul(self) -> Vec<u8> {
self.into_inner().into_vec()
}
/// Returns the contents of this `CString` as a slice of bytes.
///
/// The returned slice does **not** contain the trailing nul separator and
/// it is guaranteed to not have any interior nul bytes.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes(&self) -> &[u8] {
&self.inner[..self.inner.len() - 1]
}
/// Equivalent to the `as_bytes` function except that the returned slice
/// includes the trailing nul byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes_with_nul(&self) -> &[u8] {
&self.inner
}
// Bypass "move out of struct which implements `Drop` trait" restriction.
fn into_inner(self) -> Box<[u8]> {
unsafe {
let result = ptr::read(&self.inner);
mem::forget(self);
result
}
}
}
// Turns this `CString` into an empty string to prevent
// memory unsafe code from working by accident. Inline
// to prevent LLVM from optimizing it away in debug builds.
#[stable(feature = "cstring_drop", since = "1.13.0")]
impl Drop for CString {
#[inline]
fn drop(&mut self) {
unsafe { *self.inner.get_unchecked_mut(0) = 0; }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for CString {
type Target = CStr;
fn deref(&self) -> &CStr {
unsafe { mem::transmute(self.as_bytes_with_nul()) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for CString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
#[stable(feature = "cstring_into", since = "1.7.0")]
impl From<CString> for Vec<u8> {
fn from(s: CString) -> Vec<u8> {
s.into_bytes()
}
}
#[stable(feature = "cstr_debug", since = "1.3.0")]
impl fmt::Debug for CStr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"")?;
for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
f.write_char(byte as char)?;
}
write!(f, "\"")
}
}
#[stable(feature = "cstr_default", since = "1.10.0")]
impl<'a> Default for &'a CStr {
fn default() -> &'a CStr {
static SLICE: &'static [c_char] = &[0];
unsafe { CStr::from_ptr(SLICE.as_ptr()) }
}
}
#[stable(feature = "cstr_default", since = "1.10.0")]
impl Default for CString {
/// Creates an empty `CString`.
fn default() -> CString {
let a: &CStr = Default::default();
a.to_owned()
}
}
#[stable(feature = "cstr_borrow", since = "1.3.0")]
impl Borrow<CStr> for CString {
fn borrow(&self) -> &CStr { self }
}
impl NulError {
/// Returns the position of the nul byte in the slice that was provided to
/// `CString::new`.
///
/// # Examples
///
/// ```
/// use std::ffi::CString;
///
/// let nul_error = CString::new("foo\0bar").unwrap_err();
/// assert_eq!(nul_error.nul_position(), 3);
///
/// let nul_error = CString::new("foo bar\0").unwrap_err();
/// assert_eq!(nul_error.nul_position(), 7);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn nul_position(&self) -> usize { self.0 }
/// Consumes this error, returning the underlying vector of bytes which
/// generated the error in the first place.
///
/// # Examples
///
/// ```
/// use std::ffi::CString;
///
/// let nul_error = CString::new("foo\0bar").unwrap_err();
/// assert_eq!(nul_error.into_vec(), b"foo\0bar");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_vec(self) -> Vec<u8> { self.1 }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for NulError {
fn description(&self) -> &str { "nul byte found in data" }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for NulError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "nul byte found in provided data at position: {}", self.0)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl From<NulError> for io::Error {
fn from(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput,
"data provided contains a nul byte")
}
}
impl IntoStringError {
/// Consumes this error, returning original `CString` which generated the
/// error.
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_cstring(self) -> CString {
self.inner
}
/// Access the underlying UTF-8 error that was the cause of this error.
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn utf8_error(&self) -> Utf8Error {
self.error
}
}
#[stable(feature = "cstring_into", since = "1.7.0")]
impl Error for IntoStringError {
fn description(&self) -> &str {
"C string contained non-utf8 bytes"
}
fn cause(&self) -> Option<&Error> {
Some(&self.error)
}
}
#[stable(feature = "cstring_into", since = "1.7.0")]
impl fmt::Display for IntoStringError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.description().fmt(f)
}
}
impl CStr {
/// Casts a raw C string to a safe C string wrapper.
///
/// This function will cast the provided `ptr` to the `CStr` wrapper which
/// allows inspection and interoperation of non-owned C strings. This method
/// is unsafe for a number of reasons:
///
/// * There is no guarantee to the validity of `ptr`
/// * The returned lifetime is not guaranteed to be the actual lifetime of
/// `ptr`
/// * There is no guarantee that the memory pointed to by `ptr` contains a
/// valid nul terminator byte at the end of the string.
///
/// > **Note**: This operation is intended to be a 0-cost cast but it is
/// > currently implemented with an up-front calculation of the length of
/// > the string. This is not guaranteed to always be the case.
///
/// # Examples
///
/// ```no_run
/// # fn main() {
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
///
/// extern {
/// fn my_string() -> *const c_char;
/// }
///
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
/// println!("string returned: {}", slice.to_str().unwrap());
/// }
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
let len = libc::strlen(ptr);
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
}
/// Creates a C string wrapper from a byte slice.
///
/// This function will cast the provided `bytes` to a `CStr` wrapper after
/// ensuring that it is null terminated and does not contain any interior
/// nul bytes.
///
/// # Examples
///
/// ```
/// use std::ffi::CStr;
///
/// let cstr = CStr::from_bytes_with_nul(b"hello\0");
/// assert!(cstr.is_ok());
/// ```
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub fn from_bytes_with_nul(bytes: &[u8])
-> Result<&CStr, FromBytesWithNulError> {
if bytes.is_empty() || memchr::memchr(0, &bytes) != Some(bytes.len() - 1) {
Err(FromBytesWithNulError { _a: () })
} else {
Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
}
}
/// Unsafely creates a C string wrapper from a byte slice.
///
/// This function will cast the provided `bytes` to a `CStr` wrapper without
/// performing any sanity checks. The provided slice must be null terminated
/// and not contain any interior nul bytes.
///
/// # Examples
///
/// ```
/// use std::ffi::{CStr, CString};
///
/// unsafe {
/// let cstring = CString::new("hello").unwrap();
/// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
/// assert_eq!(cstr, &*cstring);
/// }
/// ```
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
mem::transmute(bytes)
}
/// Returns the inner pointer to this C string.
///
/// The returned pointer will be valid for as long as `self` is and points
/// to a contiguous region of memory terminated with a 0 byte to represent
/// the end of the string.
///
/// **WARNING**
///
/// It is your responsibility to make sure that the underlying memory is not
/// freed too early. For example, the following code will cause undefined
/// behaviour when `ptr` is used inside the `unsafe` block:
///
/// ```no_run
/// use std::ffi::{CString};
///
/// let ptr = CString::new("Hello").unwrap().as_ptr();
/// unsafe {
/// // `ptr` is dangling
/// *ptr;
/// }
/// ```
///
/// This happens because the pointer returned by `as_ptr` does not carry any
/// lifetime information and the string is deallocated immediately after
/// the `CString::new("Hello").unwrap().as_ptr()` expression is evaluated.
/// To fix the problem, bind the string to a local variable:
///
/// ```no_run
/// use std::ffi::{CString};
///
/// let hello = CString::new("Hello").unwrap();
/// let ptr = hello.as_ptr();
/// unsafe {
/// // `ptr` is valid because `hello` is in scope
/// *ptr;
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_ptr(&self) -> *const c_char {
self.inner.as_ptr()
}
/// Converts this C string to a byte slice.
///
/// This function will calculate the length of this string (which normally
/// requires a linear amount of work to be done) and then return the
/// resulting slice of `u8` elements.
///
/// The returned slice will **not** contain the trailing nul that this C
/// string has.
///
/// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes(&self) -> &[u8] {
let bytes = self.to_bytes_with_nul();
&bytes[..bytes.len() - 1]
}
/// Converts this C string to a byte slice containing the trailing 0 byte.
///
/// This function is the equivalent of `to_bytes` except that it will retain
/// the trailing nul instead of chopping it off.
///
/// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute(&self.inner) }
}
/// Yields a `&str` slice if the `CStr` contains valid UTF-8.
///
/// This function will calculate the length of this string and check for
/// UTF-8 validity, and then return the `&str` if it's valid.
///
/// > **Note**: This method is currently implemented to check for validity
/// > after a 0-cost cast, but it is planned to alter its definition in the
/// > future to perform the length calculation in addition to the UTF-8
/// > check whenever this method is called.
#[stable(feature = "cstr_to_str", since = "1.4.0")]
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
// NB: When CStr is changed to perform the length check in .to_bytes()
// instead of in from_ptr(), it may be worth considering if this should
// be rewritten to do the UTF-8 check inline with the length calculation
// instead of doing it afterwards.
str::from_utf8(self.to_bytes())
}
/// Converts a `CStr` into a `Cow<str>`.
///
/// This function will calculate the length of this string (which normally
/// requires a linear amount of work to be done) and then return the
/// resulting slice as a `Cow<str>`, replacing any invalid UTF-8 sequences
/// with `U+FFFD REPLACEMENT CHARACTER`.
///
/// > **Note**: This method is currently implemented to check for validity
/// > after a 0-cost cast, but it is planned to alter its definition in the
/// > future to perform the length calculation in addition to the UTF-8
/// > check whenever this method is called.
#[stable(feature = "cstr_to_str", since = "1.4.0")]
pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.to_bytes())
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for CStr {
fn eq(&self, other: &CStr) -> bool {
self.to_bytes().eq(other.to_bytes())
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for CStr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for CStr {
fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
self.to_bytes().partial_cmp(&other.to_bytes())
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for CStr {
fn cmp(&self, other: &CStr) -> Ordering {
self.to_bytes().cmp(&other.to_bytes())
}
}
#[stable(feature = "cstr_borrow", since = "1.3.0")]
impl ToOwned for CStr {
type Owned = CString;
fn to_owned(&self) -> CString {
unsafe { CString::from_vec_unchecked(self.to_bytes().to_vec()) }
}
}
#[stable(feature = "cstring_asref", since = "1.7.0")]
impl<'a> From<&'a CStr> for CString {
fn from(s: &'a CStr) -> CString {
s.to_owned()
}
}
#[stable(feature = "cstring_asref", since = "1.7.0")]
impl ops::Index<ops::RangeFull> for CString {
type Output = CStr;
#[inline]
fn index(&self, _index: ops::RangeFull) -> &CStr {
self
}
}
#[stable(feature = "cstring_asref", since = "1.7.0")]
impl AsRef<CStr> for CStr {
fn as_ref(&self) -> &CStr {
self
}
}
#[stable(feature = "cstring_asref", since = "1.7.0")]
impl AsRef<CStr> for CString {
fn as_ref(&self) -> &CStr {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use os::raw::c_char;
use borrow::Cow::{Borrowed, Owned};
use hash::{Hash, Hasher};
use collections::hash_map::DefaultHasher;
#[test]
fn c_to_rust() {
let data = b"123\0";
let ptr = data.as_ptr() as *const c_char;
unsafe {
assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
}
}
#[test]
fn simple() {
let s = CString::new("1234").unwrap();
assert_eq!(s.as_bytes(), b"1234");
assert_eq!(s.as_bytes_with_nul(), b"1234\0");
}
#[test]
fn build_with_zero1() {
assert!(CString::new(&b"\0"[..]).is_err());
}
#[test]
fn build_with_zero2() {
assert!(CString::new(vec![0]).is_err());
}
#[test]
fn build_with_zero3() {
unsafe {
let s = CString::from_vec_unchecked(vec![0]);
assert_eq!(s.as_bytes(), b"\0");
}
}
#[test]
fn formatted() {
let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
}
#[test]
fn borrowed() {
unsafe {
let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
assert_eq!(s.to_bytes(), b"12");
assert_eq!(s.to_bytes_with_nul(), b"12\0");
}
}
#[test]
fn to_str() {
let data = b"123\xE2\x80\xA6\0";
let ptr = data.as_ptr() as *const c_char;
unsafe {
assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
}
let data = b"123\xE2\0";
let ptr = data.as_ptr() as *const c_char;
unsafe {
assert!(CStr::from_ptr(ptr).to_str().is_err());
assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
}
}
#[test]
fn to_owned() {
let data = b"123\0";
let ptr = data.as_ptr() as *const c_char;
let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
assert_eq!(owned.as_bytes_with_nul(), data);
}
#[test]
fn equal_hash() {
let data = b"123\xE2\xFA\xA6\0";
let ptr = data.as_ptr() as *const c_char;
let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
let mut s = DefaultHasher::new();
cstr.hash(&mut s);
let cstr_hash = s.finish();
let mut s = DefaultHasher::new();
CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
let cstring_hash = s.finish();
assert_eq!(cstr_hash, cstring_hash);
}
#[test]
fn from_bytes_with_nul() {
let data = b"123\0";
let cstr = CStr::from_bytes_with_nul(data);
assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
let cstr = CStr::from_bytes_with_nul(data);
assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
unsafe {
let cstr = CStr::from_bytes_with_nul(data);
let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
assert_eq!(cstr, Ok(cstr_unchecked));
}
}
#[test]
fn from_bytes_with_nul_unterminated() {
let data = b"123";
let cstr = CStr::from_bytes_with_nul(data);
assert!(cstr.is_err());
}
#[test]
fn from_bytes_with_nul_interior() {
let data = b"1\023\0";
let cstr = CStr::from_bytes_with_nul(data);
assert!(cstr.is_err());
}
}

24
ctr-std/src/ffi/mod.rs

@ -0,0 +1,24 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Utilities related to FFI bindings.
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub use self::c_str::{FromBytesWithNulError};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsString, OsStr};
mod c_str;
mod os_str;

181
src/ffi/os_str.rs → ctr-std/src/ffi/os_str.rs

@ -8,19 +8,15 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use collections::borrow::{Borrow, Cow, ToOwned}; use borrow::{Borrow, Cow};
use core::fmt::{self, Debug}; use fmt::{self, Debug};
use core::mem; use mem;
use collections::String; use ops;
use core::ops; use cmp;
use core::cmp; use hash::{Hash, Hasher};
use core::hash::{Hash, Hasher};
use collections::Vec;
use sys::wtf8::{Wtf8, Wtf8Buf}; use sys::os_str::{Buf, Slice};
use sys::{AsInner, IntoInner, FromInner}; use sys_common::{AsInner, IntoInner, FromInner};
pub use sys::wtf8::EncodeWide;
/// A type that can represent owned, mutable platform-native strings, but is /// A type that can represent owned, mutable platform-native strings, but is
/// cheaply inter-convertible with Rust strings. /// cheaply inter-convertible with Rust strings.
@ -39,26 +35,26 @@ pub use sys::wtf8::EncodeWide;
/// and platform-native string values, and in particular allowing a Rust string /// and platform-native string values, and in particular allowing a Rust string
/// to be converted into an "OS" string with no cost. /// to be converted into an "OS" string with no cost.
#[derive(Clone)] #[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString { pub struct OsString {
inner: Wtf8Buf inner: Buf
} }
/// Slices into OS strings (see `OsString`). /// Slices into OS strings (see `OsString`).
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr { pub struct OsStr {
inner: Wtf8 inner: Slice
} }
impl OsString { impl OsString {
/// Constructs a new empty `OsString`. /// Constructs a new empty `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OsString { pub fn new() -> OsString {
OsString { inner: Wtf8Buf::from_string(String::new()) } OsString { inner: Buf::from_string(String::new()) }
}
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
String::from_utf8(vec).ok().map(OsString::from)
} }
/// Converts to an `OsStr` slice. /// Converts to an `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_os_str(&self) -> &OsStr { pub fn as_os_str(&self) -> &OsStr {
self self
} }
@ -66,13 +62,15 @@ impl OsString {
/// Converts the `OsString` into a `String` if it contains valid Unicode data. /// Converts the `OsString` into a `String` if it contains valid Unicode data.
/// ///
/// On failure, ownership of the original `OsString` is returned. /// On failure, ownership of the original `OsString` is returned.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_string(self) -> Result<String, OsString> { pub fn into_string(self) -> Result<String, OsString> {
self.inner.into_string().map_err(|buf| OsString { inner: buf} ) self.inner.into_string().map_err(|buf| OsString { inner: buf} )
} }
/// Extends the string with the given `&OsStr` slice. /// Extends the string with the given `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) { pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
self.inner.push_wtf8(&s.as_ref().inner) self.inner.push_slice(&s.as_ref().inner)
} }
/// Creates a new `OsString` with the given capacity. /// Creates a new `OsString` with the given capacity.
@ -82,13 +80,15 @@ impl OsString {
/// allocate. /// allocate.
/// ///
/// See main `OsString` documentation information about encoding. /// See main `OsString` documentation information about encoding.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn with_capacity(capacity: usize) -> OsString { pub fn with_capacity(capacity: usize) -> OsString {
OsString { OsString {
inner: Wtf8Buf::with_capacity(capacity) inner: Buf::with_capacity(capacity)
} }
} }
/// Truncates the `OsString` to zero length. /// Truncates the `OsString` to zero length.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.inner.clear() self.inner.clear()
} }
@ -96,6 +96,7 @@ impl OsString {
/// Returns the capacity this `OsString` can hold without reallocating. /// Returns the capacity this `OsString` can hold without reallocating.
/// ///
/// See `OsString` introduction for information about encoding. /// See `OsString` introduction for information about encoding.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
self.inner.capacity() self.inner.capacity()
} }
@ -104,6 +105,7 @@ impl OsString {
/// in the given `OsString`. /// in the given `OsString`.
/// ///
/// The collection may reserve more space to avoid frequent reallocations. /// The collection may reserve more space to avoid frequent reallocations.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn reserve(&mut self, additional: usize) { pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional) self.inner.reserve(additional)
} }
@ -115,34 +117,27 @@ impl OsString {
/// Note that the allocator may give the collection more space than it /// Note that the allocator may give the collection more space than it
/// requests. Therefore capacity can not be relied upon to be precisely /// requests. Therefore capacity can not be relied upon to be precisely
/// minimal. Prefer reserve if future insertions are expected. /// minimal. Prefer reserve if future insertions are expected.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn reserve_exact(&mut self, additional: usize) { pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional) self.inner.reserve_exact(additional)
} }
/// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
/// 16-bit code units.
///
/// This is lossless: calling `.encode_wide()` on the resulting string
/// will always return the original code units.
///
/// NOTE: This function was copied from the windows implementation of OsStringExt
pub fn from_wide(wide: &[u16]) -> OsString {
OsString { inner: Wtf8Buf::from_wide(wide) }
}
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for OsString { impl From<String> for OsString {
fn from(s: String) -> OsString { fn from(s: String) -> OsString {
OsString { inner: Wtf8Buf::from_string(s) } OsString { inner: Buf::from_string(s) }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString { impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
fn from(s: &'a T) -> OsString { fn from(s: &'a T) -> OsString {
s.as_ref().to_os_string() s.as_ref().to_os_string()
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString { impl ops::Index<ops::RangeFull> for OsString {
type Output = OsStr; type Output = OsStr;
@ -152,6 +147,7 @@ impl ops::Index<ops::RangeFull> for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString { impl ops::Deref for OsString {
type Target = OsStr; type Target = OsStr;
@ -161,39 +157,47 @@ impl ops::Deref for OsString {
} }
} }
#[stable(feature = "osstring_default", since = "1.9.0")]
impl Default for OsString { impl Default for OsString {
/// Constructs an empty `OsString`.
#[inline] #[inline]
fn default() -> OsString { fn default() -> OsString {
OsString::new() OsString::new()
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString { impl Debug for OsString {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fmt::Debug::fmt(&**self, formatter) fmt::Debug::fmt(&**self, formatter)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString { impl PartialEq for OsString {
fn eq(&self, other: &OsString) -> bool { fn eq(&self, other: &OsString) -> bool {
&**self == &**other &**self == &**other
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString { impl PartialEq<str> for OsString {
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
&**self == other &**self == other
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str { impl PartialEq<OsString> for str {
fn eq(&self, other: &OsString) -> bool { fn eq(&self, other: &OsString) -> bool {
&**other == self &**other == self
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {} impl Eq for OsString {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsString { impl PartialOrd for OsString {
#[inline] #[inline]
fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
@ -209,6 +213,7 @@ impl PartialOrd for OsString {
fn ge(&self, other: &OsString) -> bool { &**self >= &**other } fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsString { impl PartialOrd<str> for OsString {
#[inline] #[inline]
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
@ -216,6 +221,7 @@ impl PartialOrd<str> for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString { impl Ord for OsString {
#[inline] #[inline]
fn cmp(&self, other: &OsString) -> cmp::Ordering { fn cmp(&self, other: &OsString) -> cmp::Ordering {
@ -223,6 +229,7 @@ impl Ord for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsString { impl Hash for OsString {
#[inline] #[inline]
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
@ -232,38 +239,61 @@ impl Hash for OsString {
impl OsStr { impl OsStr {
/// Coerces into an `OsStr` slice. /// Coerces into an `OsStr` slice.
///
/// # Examples
///
/// ```
/// use std::ffi::OsStr;
///
/// let os_str = OsStr::new("foo");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr { pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
s.as_ref() s.as_ref()
} }
fn from_inner(inner: &Wtf8) -> &OsStr { fn from_inner(inner: &Slice) -> &OsStr {
unsafe { mem::transmute(inner) } unsafe { mem::transmute(inner) }
} }
/// Yields a `&str` slice if the `OsStr` is valid Unicode. /// Yields a `&str` slice if the `OsStr` is valid Unicode.
/// ///
/// This conversion may entail doing a check for UTF-8 validity. /// This conversion may entail doing a check for UTF-8 validity.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_str(&self) -> Option<&str> { pub fn to_str(&self) -> Option<&str> {
self.inner.as_str() self.inner.to_str()
} }
/// Converts an `OsStr` to a `Cow<str>`. /// Converts an `OsStr` to a `Cow<str>`.
/// ///
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_string_lossy(&self) -> Cow<str> { pub fn to_string_lossy(&self) -> Cow<str> {
self.inner.to_string_lossy() self.inner.to_string_lossy()
} }
/// Copies the slice into an owned `OsString`. /// Copies the slice into an owned `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_os_string(&self) -> OsString { pub fn to_os_string(&self) -> OsString {
let mut buf = Wtf8Buf::with_capacity(self.inner.len()); OsString { inner: self.inner.to_owned() }
buf.push_wtf8(&self.inner);
OsString { inner: buf }
} }
/// Checks whether the `OsStr` is empty. /// Checks whether the `OsStr` is empty.
///
/// # Examples
///
/// ```
/// use std::ffi::OsStr;
///
/// let os_str = OsStr::new("");
/// assert!(os_str.is_empty());
///
/// let os_str = OsStr::new("foo");
/// assert!(!os_str.is_empty());
/// ```
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.inner.is_empty() self.inner.inner.is_empty()
} }
/// Returns the length of this `OsStr`. /// Returns the length of this `OsStr`.
@ -274,8 +304,21 @@ impl OsStr {
/// other methods like `OsString::with_capacity` to avoid reallocations. /// other methods like `OsString::with_capacity` to avoid reallocations.
/// ///
/// See `OsStr` introduction for more information about encoding. /// See `OsStr` introduction for more information about encoding.
///
/// # Examples
///
/// ```
/// use std::ffi::OsStr;
///
/// let os_str = OsStr::new("");
/// assert_eq!(os_str.len(), 0);
///
/// let os_str = OsStr::new("foo");
/// assert_eq!(os_str.len(), 3);
/// ```
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.inner.len() self.inner.inner.len()
} }
/// Gets the underlying byte representation. /// Gets the underlying byte representation.
@ -285,46 +328,42 @@ impl OsStr {
fn bytes(&self) -> &[u8] { fn bytes(&self) -> &[u8] {
unsafe { mem::transmute(&self.inner) } unsafe { mem::transmute(&self.inner) }
} }
/// Re-encodes an `OsStr` as a wide character sequence,
/// i.e. potentially ill-formed UTF-16.
/// This is lossless. Note that the encoding does not include a final
/// null.
///
/// NOTE: This function was copied from the windows implementation of OsStrExt
pub fn encode_wide(&self) -> EncodeWide {
self.inner.encode_wide()
}
} }
#[stable(feature = "osstring_default", since = "1.9.0")]
impl<'a> Default for &'a OsStr { impl<'a> Default for &'a OsStr {
/// Creates an empty `OsStr`.
#[inline] #[inline]
fn default() -> &'a OsStr { fn default() -> &'a OsStr {
OsStr::new("") OsStr::new("")
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr { impl PartialEq for OsStr {
fn eq(&self, other: &OsStr) -> bool { fn eq(&self, other: &OsStr) -> bool {
self.bytes().eq(other.bytes()) self.bytes().eq(other.bytes())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr { impl PartialEq<str> for OsStr {
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
*self == *OsStr::new(other) *self == *OsStr::new(other)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str { impl PartialEq<OsStr> for str {
fn eq(&self, other: &OsStr) -> bool { fn eq(&self, other: &OsStr) -> bool {
*other == *OsStr::new(self) *other == *OsStr::new(self)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {} impl Eq for OsStr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsStr { impl PartialOrd for OsStr {
#[inline] #[inline]
fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
@ -340,6 +379,7 @@ impl PartialOrd for OsStr {
fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) } fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr { impl PartialOrd<str> for OsStr {
#[inline] #[inline]
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
@ -350,6 +390,7 @@ impl PartialOrd<str> for OsStr {
// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules. // have more flexible coherence rules.
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr { impl Ord for OsStr {
#[inline] #[inline]
fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
@ -357,16 +398,19 @@ impl Ord for OsStr {
macro_rules! impl_cmp { macro_rules! impl_cmp {
($lhs:ty, $rhs: ty) => { ($lhs:ty, $rhs: ty) => {
#[stable(feature = "cmp_os_str", since = "1.8.0")]
impl<'a, 'b> PartialEq<$rhs> for $lhs { impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline] #[inline]
fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) } fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
} }
#[stable(feature = "cmp_os_str", since = "1.8.0")]
impl<'a, 'b> PartialEq<$lhs> for $rhs { impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline] #[inline]
fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) } fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
} }
#[stable(feature = "cmp_os_str", since = "1.8.0")]
impl<'a, 'b> PartialOrd<$rhs> for $lhs { impl<'a, 'b> PartialOrd<$rhs> for $lhs {
#[inline] #[inline]
fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
@ -374,6 +418,7 @@ macro_rules! impl_cmp {
} }
} }
#[stable(feature = "cmp_os_str", since = "1.8.0")]
impl<'a, 'b> PartialOrd<$lhs> for $rhs { impl<'a, 'b> PartialOrd<$lhs> for $rhs {
#[inline] #[inline]
fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
@ -389,6 +434,7 @@ impl_cmp!(Cow<'a, OsStr>, OsStr);
impl_cmp!(Cow<'a, OsStr>, &'b OsStr); impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
impl_cmp!(Cow<'a, OsStr>, OsString); impl_cmp!(Cow<'a, OsStr>, OsString);
#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsStr { impl Hash for OsStr {
#[inline] #[inline]
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
@ -396,59 +442,66 @@ impl Hash for OsStr {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsStr { impl Debug for OsStr {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.inner.fmt(formatter) self.inner.fmt(formatter)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString { impl Borrow<OsStr> for OsString {
fn borrow(&self) -> &OsStr { &self[..] } fn borrow(&self) -> &OsStr { &self[..] }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr { impl ToOwned for OsStr {
type Owned = OsString; type Owned = OsString;
fn to_owned(&self) -> OsString { self.to_os_string() } fn to_owned(&self) -> OsString { self.to_os_string() }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsStr { impl AsRef<OsStr> for OsStr {
fn as_ref(&self) -> &OsStr { fn as_ref(&self) -> &OsStr {
self self
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsString { impl AsRef<OsStr> for OsString {
fn as_ref(&self) -> &OsStr { fn as_ref(&self) -> &OsStr {
self self
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str { impl AsRef<OsStr> for str {
fn as_ref(&self) -> &OsStr { fn as_ref(&self) -> &OsStr {
OsStr::from_inner(Wtf8::from_str(self)) OsStr::from_inner(Slice::from_str(self))
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String { impl AsRef<OsStr> for String {
fn as_ref(&self) -> &OsStr { fn as_ref(&self) -> &OsStr {
(&**self).as_ref() (&**self).as_ref()
} }
} }
impl FromInner<Wtf8Buf> for OsString { impl FromInner<Buf> for OsString {
fn from_inner(buf: Wtf8Buf) -> OsString { fn from_inner(buf: Buf) -> OsString {
OsString { inner: buf } OsString { inner: buf }
} }
} }
impl IntoInner<Wtf8Buf> for OsString { impl IntoInner<Buf> for OsString {
fn into_inner(self) -> Wtf8Buf { fn into_inner(self) -> Buf {
self.inner self.inner
} }
} }
impl AsInner<Wtf8> for OsStr { impl AsInner<Slice> for OsStr {
fn as_inner(&self) -> &Wtf8 { fn as_inner(&self) -> &Slice {
&self.inner &self.inner
} }
} }
@ -456,29 +509,29 @@ impl AsInner<Wtf8> for OsStr {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use sys::{AsInner, IntoInner}; use sys_common::{AsInner, IntoInner};
#[test] #[test]
fn test_os_string_with_capacity() { fn test_os_string_with_capacity() {
let os_string = OsString::with_capacity(0); let os_string = OsString::with_capacity(0);
assert_eq!(0, os_string.inner.capacity()); assert_eq!(0, os_string.inner.into_inner().capacity());
let os_string = OsString::with_capacity(10); let os_string = OsString::with_capacity(10);
assert_eq!(10, os_string.inner.capacity()); assert_eq!(10, os_string.inner.into_inner().capacity());
let mut os_string = OsString::with_capacity(0); let mut os_string = OsString::with_capacity(0);
os_string.push("abc"); os_string.push("abc");
assert!(os_string.inner.capacity() >= 3); assert!(os_string.inner.into_inner().capacity() >= 3);
} }
#[test] #[test]
fn test_os_string_clear() { fn test_os_string_clear() {
let mut os_string = OsString::from("abc"); let mut os_string = OsString::from("abc");
assert_eq!(3, os_string.inner.len()); assert_eq!(3, os_string.inner.as_inner().len());
os_string.clear(); os_string.clear();
assert_eq!(&os_string, ""); assert_eq!(&os_string, "");
assert_eq!(0, os_string.inner.len()); assert_eq!(0, os_string.inner.as_inner().len());
} }
#[test] #[test]

1153
ctr-std/src/io/buffered.rs

File diff suppressed because it is too large Load Diff

600
ctr-std/src/io/cursor.rs

@ -0,0 +1,600 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use io::prelude::*;
use core::convert::TryInto;
use cmp;
use io::{self, SeekFrom, Error, ErrorKind};
/// A `Cursor` wraps another type and provides it with a
/// [`Seek`] implementation.
///
/// `Cursor`s are typically used with in-memory buffers to allow them to
/// implement [`Read`] and/or [`Write`], allowing these buffers to be used
/// anywhere you might use a reader or writer that does actual I/O.
///
/// The standard library implements some I/O traits on various types which
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
/// `Cursor<`[`&[u8]`][bytes]`>`.
///
/// # Examples
///
/// We may want to write bytes to a [`File`] in our production
/// code, but use an in-memory buffer in our tests. We can do this with
/// `Cursor`:
///
/// [`Seek`]: trait.Seek.html
/// [`Read`]: ../../std/io/trait.Read.html
/// [`Write`]: ../../std/io/trait.Write.html
/// [`Vec`]: ../../std/vec/struct.Vec.html
/// [bytes]: ../../std/primitive.slice.html
/// [`File`]: ../fs/struct.File.html
///
/// ```no_run
/// use std::io::prelude::*;
/// use std::io::{self, SeekFrom};
/// use std::fs::File;
///
/// // a library function we've written
/// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> {
/// try!(writer.seek(SeekFrom::End(-10)));
///
/// for i in 0..10 {
/// try!(writer.write(&[i]));
/// }
///
/// // all went well
/// Ok(())
/// }
///
/// # fn foo() -> io::Result<()> {
/// // Here's some code that uses this library function.
/// //
/// // We might want to use a BufReader here for efficiency, but let's
/// // keep this example focused.
/// let mut file = try!(File::create("foo.txt"));
///
/// try!(write_ten_bytes_at_end(&mut file));
/// # Ok(())
/// # }
///
/// // now let's write a test
/// #[test]
/// fn test_writes_bytes() {
/// // setting up a real File is much more slow than an in-memory buffer,
/// // let's use a cursor instead
/// use std::io::Cursor;
/// let mut buff = Cursor::new(vec![0; 15]);
///
/// write_ten_bytes_at_end(&mut buff).unwrap();
///
/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone, Debug)]
pub struct Cursor<T> {
inner: T,
pos: u64,
}
impl<T> Cursor<T> {
/// Creates a new cursor wrapping the provided underlying I/O object.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner: inner }
}
/// Consumes this cursor, returning the underlying value.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let vec = buff.into_inner();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> T { self.inner }
/// Gets a reference to the underlying value in this cursor.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let reference = buff.get_ref();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_ref(&self) -> &T { &self.inner }
/// Gets a mutable reference to the underlying value in this cursor.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying value as it may corrupt this cursor's position.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let reference = buff.get_mut();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
/// Returns the current position of this cursor.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
/// use std::io::prelude::*;
/// use std::io::SeekFrom;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.position(), 0);
///
/// buff.seek(SeekFrom::Current(2)).unwrap();
/// assert_eq!(buff.position(), 2);
///
/// buff.seek(SeekFrom::Current(-1)).unwrap();
/// assert_eq!(buff.position(), 1);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn position(&self) -> u64 { self.pos }
/// Sets the position of this cursor.
///
/// # Examples
///
/// ```
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.position(), 0);
///
/// buff.set_position(2);
/// assert_eq!(buff.position(), 2);
///
/// buff.set_position(4);
/// assert_eq!(buff.position(), 4);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> {
fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
let pos = match style {
SeekFrom::Start(n) => { self.pos = n; return Ok(n) }
SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n,
SeekFrom::Current(n) => self.pos as i64 + n,
};
if pos < 0 {
Err(Error::new(ErrorKind::InvalidInput,
"invalid seek to a negative position"))
} else {
self.pos = pos as u64;
Ok(self.pos)
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = Read::read(&mut self.fill_buf()?, buf)?;
self.pos += n as u64;
Ok(n)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
Ok(&self.inner.as_ref()[(amt as usize)..])
}
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> {
#[inline]
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let pos = cmp::min(self.pos, self.inner.len() as u64);
let amt = (&mut self.inner[(pos as usize)..]).write(data)?;
self.pos += amt as u64;
Ok(amt)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Cursor<Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let pos: usize = self.position().try_into().map_err(|_| {
Error::new(ErrorKind::InvalidInput,
"cursor position exceeds maximum possible vector length")
})?;
// Make sure the internal buffer is as least as big as where we
// currently are
let len = self.inner.len();
if len < pos {
// use `resize` so that the zero filling is as efficient as possible
self.inner.resize(pos, 0);
}
// Figure out what bytes will be used to overwrite what's currently
// there (left), and what will be appended on the end (right)
{
let space = self.inner.len() - pos;
let (left, right) = buf.split_at(cmp::min(space, buf.len()));
self.inner[pos..pos + left.len()].copy_from_slice(left);
self.inner.extend_from_slice(right);
}
// Bump us forward
self.set_position((pos + buf.len()) as u64);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[stable(feature = "cursor_box_slice", since = "1.5.0")]
impl Write for Cursor<Box<[u8]>> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let pos = cmp::min(self.pos, self.inner.len() as u64);
let amt = (&mut self.inner[(pos as usize)..]).write(buf)?;
self.pos += amt as u64;
Ok(amt)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[cfg(test)]
mod tests {
use io::prelude::*;
use io::{Cursor, SeekFrom};
#[test]
fn test_vec_writer() {
let mut writer = Vec::new();
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(writer, b);
}
#[test]
fn test_mem_writer() {
let mut writer = Cursor::new(Vec::new());
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(&writer.get_ref()[..], b);
}
#[test]
fn test_box_slice_writer() {
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
assert_eq!(writer.position(), 0);
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.position(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
assert_eq!(writer.position(), 8);
assert_eq!(writer.write(&[]).unwrap(), 0);
assert_eq!(writer.position(), 8);
assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
assert_eq!(writer.write(&[10]).unwrap(), 0);
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(&**writer.get_ref(), b);
}
#[test]
fn test_buf_writer() {
let mut buf = [0 as u8; 9];
{
let mut writer = Cursor::new(&mut buf[..]);
assert_eq!(writer.position(), 0);
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.position(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
assert_eq!(writer.position(), 8);
assert_eq!(writer.write(&[]).unwrap(), 0);
assert_eq!(writer.position(), 8);
assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
assert_eq!(writer.write(&[10]).unwrap(), 0);
}
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(buf, b);
}
#[test]
fn test_buf_writer_seek() {
let mut buf = [0 as u8; 8];
{
let mut writer = Cursor::new(&mut buf[..]);
assert_eq!(writer.position(), 0);
assert_eq!(writer.write(&[1]).unwrap(), 1);
assert_eq!(writer.position(), 1);
assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2);
assert_eq!(writer.position(), 2);
assert_eq!(writer.write(&[2]).unwrap(), 1);
assert_eq!(writer.position(), 3);
assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1);
assert_eq!(writer.position(), 1);
assert_eq!(writer.write(&[3]).unwrap(), 1);
assert_eq!(writer.position(), 2);
assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
assert_eq!(writer.position(), 7);
assert_eq!(writer.write(&[4]).unwrap(), 1);
assert_eq!(writer.position(), 8);
}
let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4];
assert_eq!(buf, b);
}
#[test]
fn test_buf_writer_error() {
let mut buf = [0 as u8; 2];
let mut writer = Cursor::new(&mut buf[..]);
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.write(&[0, 0]).unwrap(), 1);
assert_eq!(writer.write(&[0, 0]).unwrap(), 0);
}
#[test]
fn test_mem_reader() {
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
let mut buf = [];
assert_eq!(reader.read(&mut buf).unwrap(), 0);
assert_eq!(reader.position(), 0);
let mut buf = [0];
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.position(), 1);
let b: &[_] = &[0];
assert_eq!(buf, b);
let mut buf = [0; 4];
assert_eq!(reader.read(&mut buf).unwrap(), 4);
assert_eq!(reader.position(), 5);
let b: &[_] = &[1, 2, 3, 4];
assert_eq!(buf, b);
assert_eq!(reader.read(&mut buf).unwrap(), 3);
let b: &[_] = &[5, 6, 7];
assert_eq!(&buf[..3], b);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
}
#[test]
fn test_boxed_slice_reader() {
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
let mut buf = [];
assert_eq!(reader.read(&mut buf).unwrap(), 0);
assert_eq!(reader.position(), 0);
let mut buf = [0];
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.position(), 1);
let b: &[_] = &[0];
assert_eq!(buf, b);
let mut buf = [0; 4];
assert_eq!(reader.read(&mut buf).unwrap(), 4);
assert_eq!(reader.position(), 5);
let b: &[_] = &[1, 2, 3, 4];
assert_eq!(buf, b);
assert_eq!(reader.read(&mut buf).unwrap(), 3);
let b: &[_] = &[5, 6, 7];
assert_eq!(&buf[..3], b);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
}
#[test]
fn read_to_end() {
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
let mut v = Vec::new();
reader.read_to_end(&mut v).unwrap();
assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
}
#[test]
fn test_slice_reader() {
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
let mut reader = &mut &in_buf[..];
let mut buf = [];
assert_eq!(reader.read(&mut buf).unwrap(), 0);
let mut buf = [0];
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.len(), 7);
let b: &[_] = &[0];
assert_eq!(&buf[..], b);
let mut buf = [0; 4];
assert_eq!(reader.read(&mut buf).unwrap(), 4);
assert_eq!(reader.len(), 3);
let b: &[_] = &[1, 2, 3, 4];
assert_eq!(&buf[..], b);
assert_eq!(reader.read(&mut buf).unwrap(), 3);
let b: &[_] = &[5, 6, 7];
assert_eq!(&buf[..3], b);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
}
#[test]
fn test_buf_reader() {
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
let mut reader = Cursor::new(&in_buf[..]);
let mut buf = [];
assert_eq!(reader.read(&mut buf).unwrap(), 0);
assert_eq!(reader.position(), 0);
let mut buf = [0];
assert_eq!(reader.read(&mut buf).unwrap(), 1);
assert_eq!(reader.position(), 1);
let b: &[_] = &[0];
assert_eq!(buf, b);
let mut buf = [0; 4];
assert_eq!(reader.read(&mut buf).unwrap(), 4);
assert_eq!(reader.position(), 5);
let b: &[_] = &[1, 2, 3, 4];
assert_eq!(buf, b);
assert_eq!(reader.read(&mut buf).unwrap(), 3);
let b: &[_] = &[5, 6, 7];
assert_eq!(&buf[..3], b);
assert_eq!(reader.read(&mut buf).unwrap(), 0);
}
#[test]
fn test_read_char() {
let b = &b"Vi\xE1\xBB\x87t"[..];
let mut c = Cursor::new(b).chars();
assert_eq!(c.next().unwrap().unwrap(), 'V');
assert_eq!(c.next().unwrap().unwrap(), 'i');
assert_eq!(c.next().unwrap().unwrap(), 'ệ');
assert_eq!(c.next().unwrap().unwrap(), 't');
assert!(c.next().is_none());
}
#[test]
fn test_read_bad_char() {
let b = &b"\x80"[..];
let mut c = Cursor::new(b).chars();
assert!(c.next().unwrap().is_err());
}
#[test]
fn seek_past_end() {
let buf = [0xff];
let mut r = Cursor::new(&buf[..]);
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(r.read(&mut [0]).unwrap(), 0);
let mut r = Cursor::new(vec![10]);
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(r.read(&mut [0]).unwrap(), 0);
let mut buf = [0];
let mut r = Cursor::new(&mut buf[..]);
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(r.write(&[3]).unwrap(), 0);
let mut r = Cursor::new(vec![10].into_boxed_slice());
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(r.write(&[3]).unwrap(), 0);
}
#[test]
fn seek_before_0() {
let buf = [0xff];
let mut r = Cursor::new(&buf[..]);
assert!(r.seek(SeekFrom::End(-2)).is_err());
let mut r = Cursor::new(vec![10]);
assert!(r.seek(SeekFrom::End(-2)).is_err());
let mut buf = [0];
let mut r = Cursor::new(&mut buf[..]);
assert!(r.seek(SeekFrom::End(-2)).is_err());
let mut r = Cursor::new(vec![10].into_boxed_slice());
assert!(r.seek(SeekFrom::End(-2)).is_err());
}
#[test]
fn test_seekable_mem_writer() {
let mut writer = Cursor::new(Vec::<u8>::new());
assert_eq!(writer.position(), 0);
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.position(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
assert_eq!(writer.position(), 8);
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(&writer.get_ref()[..], b);
assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(writer.position(), 0);
assert_eq!(writer.write(&[3, 4]).unwrap(), 2);
let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
assert_eq!(&writer.get_ref()[..], b);
assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3);
assert_eq!(writer.write(&[0, 1]).unwrap(), 2);
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
assert_eq!(&writer.get_ref()[..], b);
assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
assert_eq!(writer.write(&[1, 2]).unwrap(), 2);
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
assert_eq!(&writer.get_ref()[..], b);
assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10);
assert_eq!(writer.write(&[1]).unwrap(), 1);
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
assert_eq!(&writer.get_ref()[..], b);
}
#[test]
fn vec_seek_past_end() {
let mut r = Cursor::new(Vec::new());
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(r.write(&[3]).unwrap(), 1);
}
#[test]
fn vec_seek_before_0() {
let mut r = Cursor::new(Vec::new());
assert!(r.seek(SeekFrom::End(-2)).is_err());
}
#[test]
#[cfg(target_pointer_width = "32")]
fn vec_seek_and_write_past_usize_max() {
let mut c = Cursor::new(Vec::new());
c.set_position(<usize>::max_value() as u64 + 1);
assert!(c.write_all(&[1, 2, 3]).is_err());
}
}

594
ctr-std/src/io/error.rs

@ -0,0 +1,594 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use error;
use fmt;
use result;
use sys;
use convert::From;
/// A specialized [`Result`](../result/enum.Result.html) type for I/O
/// operations.
///
/// This type is broadly used across `std::io` for any operation which may
/// produce an error.
///
/// This typedef is generally used to avoid writing out `io::Error` directly and
/// is otherwise a direct mapping to `Result`.
///
/// While usual Rust style is to import types directly, aliases of `Result`
/// often are not, to make it easier to distinguish between them. `Result` is
/// generally assumed to be `std::result::Result`, and so users of this alias
/// will generally use `io::Result` instead of shadowing the prelude's import
/// of `std::result::Result`.
///
/// # Examples
///
/// A convenience function that bubbles an `io::Result` to its caller:
///
/// ```
/// use std::io;
///
/// fn get_string() -> io::Result<String> {
/// let mut buffer = String::new();
///
/// try!(io::stdin().read_line(&mut buffer));
///
/// Ok(buffer)
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub type Result<T> = result::Result<T, Error>;
/// The error type for I/O operations of the `Read`, `Write`, `Seek`, and
/// associated traits.
///
/// Errors mostly originate from the underlying OS, but custom instances of
/// `Error` can be created with crafted error messages and a particular value of
/// [`ErrorKind`].
///
/// [`ErrorKind`]: enum.ErrorKind.html
#[derive(Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Error {
repr: Repr,
}
enum Repr {
Os(i32),
Simple(ErrorKind),
Custom(Box<Custom>),
}
#[derive(Debug)]
struct Custom {
kind: ErrorKind,
error: Box<error::Error+Send+Sync>,
}
/// A list specifying general categories of I/O error.
///
/// This list is intended to grow over time and it is not recommended to
/// exhaustively match against it.
///
/// It is used with the [`io::Error`] type.
///
/// [`io::Error`]: struct.Error.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
pub enum ErrorKind {
/// An entity was not found, often a file.
#[stable(feature = "rust1", since = "1.0.0")]
NotFound,
/// The operation lacked the necessary privileges to complete.
#[stable(feature = "rust1", since = "1.0.0")]
PermissionDenied,
/// The connection was refused by the remote server.
#[stable(feature = "rust1", since = "1.0.0")]
ConnectionRefused,
/// The connection was reset by the remote server.
#[stable(feature = "rust1", since = "1.0.0")]
ConnectionReset,
/// The connection was aborted (terminated) by the remote server.
#[stable(feature = "rust1", since = "1.0.0")]
ConnectionAborted,
/// The network operation failed because it was not connected yet.
#[stable(feature = "rust1", since = "1.0.0")]
NotConnected,
/// A socket address could not be bound because the address is already in
/// use elsewhere.
#[stable(feature = "rust1", since = "1.0.0")]
AddrInUse,
/// A nonexistent interface was requested or the requested address was not
/// local.
#[stable(feature = "rust1", since = "1.0.0")]
AddrNotAvailable,
/// The operation failed because a pipe was closed.
#[stable(feature = "rust1", since = "1.0.0")]
BrokenPipe,
/// An entity already exists, often a file.
#[stable(feature = "rust1", since = "1.0.0")]
AlreadyExists,
/// The operation needs to block to complete, but the blocking operation was
/// requested to not occur.
#[stable(feature = "rust1", since = "1.0.0")]
WouldBlock,
/// A parameter was incorrect.
#[stable(feature = "rust1", since = "1.0.0")]
InvalidInput,
/// Data not valid for the operation were encountered.
///
/// Unlike [`InvalidInput`], this typically means that the operation
/// parameters were valid, however the error was caused by malformed
/// input data.
///
/// For example, a function that reads a file into a string will error with
/// `InvalidData` if the file's contents are not valid UTF-8.
///
/// [`InvalidInput`]: #variant.InvalidInput
#[stable(feature = "io_invalid_data", since = "1.2.0")]
InvalidData,
/// The I/O operation's timeout expired, causing it to be canceled.
#[stable(feature = "rust1", since = "1.0.0")]
TimedOut,
/// An error returned when an operation could not be completed because a
/// call to [`write()`] returned [`Ok(0)`].
///
/// This typically means that an operation could only succeed if it wrote a
/// particular number of bytes but only a smaller number of bytes could be
/// written.
///
/// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
/// [`Ok(0)`]: ../../std/io/type.Result.html
#[stable(feature = "rust1", since = "1.0.0")]
WriteZero,
/// This operation was interrupted.
///
/// Interrupted operations can typically be retried.
#[stable(feature = "rust1", since = "1.0.0")]
Interrupted,
/// Any I/O error not part of this list.
#[stable(feature = "rust1", since = "1.0.0")]
Other,
/// An error returned when an operation could not be completed because an
/// "end of file" was reached prematurely.
///
/// This typically means that an operation could only succeed if it read a
/// particular number of bytes but only a smaller number of bytes could be
/// read.
#[stable(feature = "read_exact", since = "1.6.0")]
UnexpectedEof,
/// A marker variant that tells the compiler that users of this enum cannot
/// match it exhaustively.
#[unstable(feature = "io_error_internals",
reason = "better expressed through extensible enums that this \
enum cannot be exhaustively matched against",
issue = "0")]
#[doc(hidden)]
__Nonexhaustive,
}
impl ErrorKind {
fn as_str(&self) -> &'static str {
match *self {
ErrorKind::NotFound => "entity not found",
ErrorKind::PermissionDenied => "permission denied",
ErrorKind::ConnectionRefused => "connection refused",
ErrorKind::ConnectionReset => "connection reset",
ErrorKind::ConnectionAborted => "connection aborted",
ErrorKind::NotConnected => "not connected",
ErrorKind::AddrInUse => "address in use",
ErrorKind::AddrNotAvailable => "address not available",
ErrorKind::BrokenPipe => "broken pipe",
ErrorKind::AlreadyExists => "entity already exists",
ErrorKind::WouldBlock => "operation would block",
ErrorKind::InvalidInput => "invalid input parameter",
ErrorKind::InvalidData => "invalid data",
ErrorKind::TimedOut => "timed out",
ErrorKind::WriteZero => "write zero",
ErrorKind::Interrupted => "operation interrupted",
ErrorKind::Other => "other os error",
ErrorKind::UnexpectedEof => "unexpected end of file",
ErrorKind::__Nonexhaustive => unreachable!()
}
}
}
/// Intended for use for errors not exposed to the user, where allocating onto
/// the heap (for normal construction via Error::new) is too costly.
#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error {
repr: Repr::Simple(kind)
}
}
}
impl Error {
/// Creates a new I/O error from a known kind of error as well as an
/// arbitrary error payload.
///
/// This function is used to generically create I/O errors which do not
/// originate from the OS itself. The `error` argument is an arbitrary
/// payload which will be contained in this `Error`.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// // errors can be created from strings
/// let custom_error = Error::new(ErrorKind::Other, "oh no!");
///
/// // errors can also be created from other errors
/// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where E: Into<Box<error::Error+Send+Sync>>
{
Self::_new(kind, error.into())
}
fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
Error {
repr: Repr::Custom(Box::new(Custom {
kind: kind,
error: error,
}))
}
}
/// Returns an error representing the last OS error which occurred.
///
/// This function reads the value of `errno` for the target platform (e.g.
/// `GetLastError` on Windows) and will return a corresponding instance of
/// `Error` for the error code.
///
/// # Examples
///
/// ```
/// use std::io::Error;
///
/// println!("last OS error: {:?}", Error::last_os_error());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn last_os_error() -> Error {
Error::from_raw_os_error(sys::os::errno() as i32)
}
/// Creates a new instance of an `Error` from a particular OS error code.
///
/// # Examples
///
/// On Linux:
///
/// ```
/// # if cfg!(target_os = "linux") {
/// use std::io;
///
/// let error = io::Error::from_raw_os_error(98);
/// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
/// # }
/// ```
///
/// On Windows:
///
/// ```
/// # if cfg!(windows) {
/// use std::io;
///
/// let error = io::Error::from_raw_os_error(10048);
/// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_raw_os_error(code: i32) -> Error {
Error { repr: Repr::Os(code) }
}
/// Returns the OS error that this error represents (if any).
///
/// If this `Error` was constructed via `last_os_error` or
/// `from_raw_os_error`, then this function will return `Some`, otherwise
/// it will return `None`.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// fn print_os_error(err: &Error) {
/// if let Some(raw_os_err) = err.raw_os_error() {
/// println!("raw OS error: {:?}", raw_os_err);
/// } else {
/// println!("Not an OS error");
/// }
/// }
///
/// fn main() {
/// // Will print "raw OS error: ...".
/// print_os_error(&Error::last_os_error());
/// // Will print "Not an OS error".
/// print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn raw_os_error(&self) -> Option<i32> {
match self.repr {
Repr::Os(i) => Some(i),
Repr::Custom(..) => None,
Repr::Simple(..) => None,
}
}
/// Returns a reference to the inner error wrapped by this error (if any).
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// fn print_error(err: &Error) {
/// if let Some(inner_err) = err.get_ref() {
/// println!("Inner error: {:?}", inner_err);
/// } else {
/// println!("No inner error");
/// }
/// }
///
/// fn main() {
/// // Will print "No inner error".
/// print_error(&Error::last_os_error());
/// // Will print "Inner error: ...".
/// print_error(&Error::new(ErrorKind::Other, "oh no!"));
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
Repr::Custom(ref c) => Some(&*c.error),
}
}
/// Returns a mutable reference to the inner error wrapped by this error
/// (if any).
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
/// use std::{error, fmt};
/// use std::fmt::Display;
///
/// #[derive(Debug)]
/// struct MyError {
/// v: String,
/// }
///
/// impl MyError {
/// fn new() -> MyError {
/// MyError {
/// v: "oh no!".to_owned()
/// }
/// }
///
/// fn change_message(&mut self, new_message: &str) {
/// self.v = new_message.to_owned();
/// }
/// }
///
/// impl error::Error for MyError {
/// fn description(&self) -> &str { &self.v }
/// }
///
/// impl Display for MyError {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "MyError: {}", &self.v)
/// }
/// }
///
/// fn change_error(mut err: Error) -> Error {
/// if let Some(inner_err) = err.get_mut() {
/// inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
/// }
/// err
/// }
///
/// fn print_error(err: &Error) {
/// if let Some(inner_err) = err.get_ref() {
/// println!("Inner error: {}", inner_err);
/// } else {
/// println!("No inner error");
/// }
/// }
///
/// fn main() {
/// // Will print "No inner error".
/// print_error(&change_error(Error::last_os_error()));
/// // Will print "Inner error: ...".
/// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
Repr::Custom(ref mut c) => Some(&mut *c.error),
}
}
/// Consumes the `Error`, returning its inner error (if any).
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// fn print_error(err: Error) {
/// if let Some(inner_err) = err.into_inner() {
/// println!("Inner error: {}", inner_err);
/// } else {
/// println!("No inner error");
/// }
/// }
///
/// fn main() {
/// // Will print "No inner error".
/// print_error(Error::last_os_error());
/// // Will print "Inner error: ...".
/// print_error(Error::new(ErrorKind::Other, "oh no!"));
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
Repr::Custom(c) => Some(c.error)
}
}
/// Returns the corresponding `ErrorKind` for this error.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// fn print_error(err: Error) {
/// println!("{:?}", err.kind());
/// }
///
/// fn main() {
/// // Will print "No inner error".
/// print_error(Error::last_os_error());
/// // Will print "Inner error: ...".
/// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn kind(&self) -> ErrorKind {
match self.repr {
Repr::Os(code) => sys::decode_error_kind(code),
Repr::Custom(ref c) => c.kind,
Repr::Simple(kind) => kind,
}
}
}
impl fmt::Debug for Repr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
Repr::Os(ref code) =>
fmt.debug_struct("Os").field("code", code)
.field("message", &sys::os::error_string(*code)).finish(),
Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.repr {
Repr::Os(code) => {
let detail = sys::os::error_string(code);
write!(fmt, "{} (os error {})", detail, code)
}
Repr::Custom(ref c) => c.error.fmt(fmt),
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl error::Error for Error {
fn description(&self) -> &str {
match self.repr {
Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
Repr::Custom(ref c) => c.error.description(),
}
}
fn cause(&self) -> Option<&error::Error> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
Repr::Custom(ref c) => c.error.cause(),
}
}
}
fn _assert_error_is_sync_send() {
fn _is_sync_send<T: Sync+Send>() {}
_is_sync_send::<Error>();
}
#[cfg(test)]
mod test {
use super::{Error, ErrorKind};
use error;
use fmt;
use sys::os::error_string;
#[test]
fn test_debug_error() {
let code = 6;
let msg = error_string(code);
let err = Error { repr: super::Repr::Os(code) };
let expected = format!("Error {{ repr: Os {{ code: {:?}, message: {:?} }} }}", code, msg);
assert_eq!(format!("{:?}", err), expected);
}
#[test]
fn test_downcasting() {
#[derive(Debug)]
struct TestError;
impl fmt::Display for TestError {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
Ok(())
}
}
impl error::Error for TestError {
fn description(&self) -> &str {
"asdf"
}
}
// we have to call all of these UFCS style right now since method
// resolution won't implicitly drop the Send+Sync bounds
let mut err = Error::new(ErrorKind::Other, TestError);
assert!(err.get_ref().unwrap().is::<TestError>());
assert_eq!("asdf", err.get_ref().unwrap().description());
assert!(err.get_mut().unwrap().is::<TestError>());
let extracted = err.into_inner().unwrap();
extracted.downcast::<TestError>().unwrap();
}
}

296
ctr-std/src/io/impls.rs

@ -0,0 +1,296 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use cmp;
use io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind};
use fmt;
use mem;
// =============================================================================
// Forwarding implementations
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, R: Read + ?Sized> Read for &'a mut R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
}
#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_to_end(buf)
}
#[inline]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_to_string(buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
(**self).read_exact(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, W: Write + ?Sized> Write for &'a mut W {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
#[inline]
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
(**self).write_all(buf)
}
#[inline]
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
(**self).write_fmt(fmt)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
#[inline]
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
#[inline]
fn consume(&mut self, amt: usize) { (**self).consume(amt) }
#[inline]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_until(byte, buf)
}
#[inline]
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_line(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
}
#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_to_end(buf)
}
#[inline]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_to_string(buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
(**self).read_exact(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for Box<W> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
#[inline]
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
(**self).write_all(buf)
}
#[inline]
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
(**self).write_fmt(fmt)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for Box<S> {
#[inline]
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
#[inline]
fn consume(&mut self, amt: usize) { (**self).consume(amt) }
#[inline]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_until(byte, buf)
}
#[inline]
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_line(buf)
}
}
// =============================================================================
// In-memory buffer implementations
/// Read is implemented for `&[u8]` by copying from the slice.
///
/// Note that reading updates the slice to point to the yet unread part.
/// The slice will be empty when EOF is reached.
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a [u8] {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);
buf[..amt].copy_from_slice(a);
*self = b;
Ok(amt)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
if buf.len() > self.len() {
return Err(Error::new(ErrorKind::UnexpectedEof,
"failed to fill whole buffer"));
}
let (a, b) = self.split_at(buf.len());
buf.copy_from_slice(a);
*self = b;
Ok(())
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for &'a [u8] {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
#[inline]
fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
}
/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
/// its data.
///
/// Note that writing updates the slice to point to the yet unwritten part.
/// The slice will be empty when it has been completely overwritten.
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a mut [u8] {
#[inline]
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let amt = cmp::min(data.len(), self.len());
let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
a.copy_from_slice(&data[..amt]);
*self = b;
Ok(amt)
}
#[inline]
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
}
}
#[inline]
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
/// Write is implemented for `Vec<u8>` by appending to the vector.
/// The vector will grow as needed.
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Vec<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.extend_from_slice(buf);
Ok(())
}
#[inline]
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[cfg(test)]
mod tests {
use io::prelude::*;
use test;
#[bench]
fn bench_read_slice(b: &mut test::Bencher) {
let buf = [5; 1024];
let mut dst = [0; 128];
b.iter(|| {
let mut rd = &buf[..];
for _ in 0..8 {
let _ = rd.read(&mut dst);
test::black_box(&dst);
}
})
}
#[bench]
fn bench_write_slice(b: &mut test::Bencher) {
let mut buf = [0; 1024];
let src = [5; 128];
b.iter(|| {
let mut wr = &mut buf[..];
for _ in 0..8 {
let _ = wr.write_all(&src);
test::black_box(&wr);
}
})
}
#[bench]
fn bench_read_vec(b: &mut test::Bencher) {
let buf = vec![5; 1024];
let mut dst = [0; 128];
b.iter(|| {
let mut rd = &buf[..];
for _ in 0..8 {
let _ = rd.read(&mut dst);
test::black_box(&dst);
}
})
}
#[bench]
fn bench_write_vec(b: &mut test::Bencher) {
let mut buf = Vec::with_capacity(1024);
let src = [5; 128];
b.iter(|| {
let mut wr = &mut buf[..];
for _ in 0..8 {
let _ = wr.write_all(&src);
test::black_box(&wr);
}
})
}
}

1990
ctr-std/src/io/mod.rs

File diff suppressed because it is too large Load Diff

24
ctr-std/src/io/prelude.rs

@ -0,0 +1,24 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The I/O Prelude
//!
//! The purpose of this module is to alleviate imports of many common I/O traits
//! by adding a glob import to the top of I/O heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use std::io::prelude::*;
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub use super::{Read, Write, BufRead, Seek};

33
ctr-std/src/io/print.rs

@ -0,0 +1,33 @@
use fmt;
use io::{self, Write};
// NOTE: We're just gonna use the spin mutex until we figure out how to properly
// implement mutexes with ctrulib functions
use spin::Mutex;
use libc;
pub static STDOUT: Mutex<StdoutRaw> = Mutex::new(StdoutRaw(()));
pub struct StdoutRaw(());
#[stable(feature = "3ds", since = "1.0.0")]
impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
unsafe {
// devkitPro's version of write(2) fails if zero bytes are written,
// so let's just exit if the buffer size is zero
if buf.is_empty() {
return Ok(buf.len())
}
libc::write(libc::STDOUT_FILENO, buf.as_ptr() as *const _, buf.len());
Ok(buf.len())
}
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
STDOUT.lock().write_fmt(args).unwrap();
}

215
ctr-std/src/io/util.rs

@ -0,0 +1,215 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(missing_copy_implementations)]
use io::{self, Read, Write, ErrorKind, BufRead};
/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
where R: Read, W: Write
{
let mut buf = [0; super::DEFAULT_BUF_SIZE];
let mut written = 0;
loop {
let len = match reader.read(&mut buf) {
Ok(0) => return Ok(written),
Ok(len) => len,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
writer.write_all(&buf[..len])?;
written += len as u64;
}
}
/// A reader which is always at EOF.
///
/// This struct is generally created by calling [`empty()`][empty]. Please see
/// the documentation of `empty()` for more details.
///
/// [empty]: fn.empty.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }
/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io::{self, Read};
///
/// let mut buffer = String::new();
/// io::empty().read_to_string(&mut buffer).unwrap();
/// assert!(buffer.is_empty());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
fn consume(&mut self, _n: usize) {}
}
/// A reader which yields one byte over and over and over and over and over and...
///
/// This struct is generally created by calling [`repeat()`][repeat]. Please
/// see the documentation of `repeat()` for more details.
///
/// [repeat]: fn.repeat.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }
/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
///
/// # Examples
///
/// ```
/// use std::io::{self, Read};
///
/// let mut buffer = [0; 3];
/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
for slot in &mut *buf {
*slot = self.byte;
}
Ok(buf.len())
}
}
/// A writer which will move data into the void.
///
/// This struct is generally created by calling [`sink()`][sink]. Please
/// see the documentation of `sink()` for more details.
///
/// [sink]: fn.sink.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }
/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
///
/// # Examples
///
/// ```rust
/// use std::io::{self, Write};
///
/// let buffer = vec![1, 2, 3, 5, 8];
/// let num_bytes = io::sink().write(&buffer).unwrap();
/// assert_eq!(num_bytes, 5);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[cfg(test)]
mod tests {
use io::prelude::*;
use io::{copy, sink, empty, repeat};
#[test]
fn copy_copies() {
let mut r = repeat(0).take(4);
let mut w = sink();
assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
let mut r = repeat(0).take(1 << 17);
assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17);
}
#[test]
fn sink_sinks() {
let mut s = sink();
assert_eq!(s.write(&[]).unwrap(), 0);
assert_eq!(s.write(&[0]).unwrap(), 1);
assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
}
#[test]
fn empty_reads() {
let mut e = empty();
assert_eq!(e.read(&mut []).unwrap(), 0);
assert_eq!(e.read(&mut [0]).unwrap(), 0);
assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
}
#[test]
fn repeat_repeats() {
let mut r = repeat(4);
let mut b = [0; 1024];
assert_eq!(r.read(&mut b).unwrap(), 1024);
assert!(b.iter().all(|b| *b == 4));
}
#[test]
fn take_some_bytes() {
assert_eq!(repeat(4).take(100).bytes().count(), 100);
assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
}
}

174
ctr-std/src/lib.rs

@ -0,0 +1,174 @@
#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(compiler_builtins_lib)]
#![feature(core_intrinsics)]
#![feature(char_escape_debug)]
#![feature(float_extras)]
#![feature(fused)]
#![feature(int_error_internals)]
#![feature(lang_items)]
#![feature(macro_reexport)]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(raw)]
#![feature(slice_concat_ext)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(thread_local)]
#![feature(try_from)]
#![feature(unicode)]
#![feature(zero_one)]
#![allow(non_camel_case_types, dead_code, unused_features)]
#![no_std]
#![stable(feature = "rust1", since = "1.0.0")]
#[prelude_import]
#[allow(unused)]
use prelude::v1::*;
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
unreachable, unimplemented, write, writeln, try)]
extern crate core as __core;
#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;
extern crate alloc;
extern crate std_unicode;
extern crate alloc_system;
// compiler-rt intrinsics
extern crate compiler_builtins;
// 3ds-specific dependencies
extern crate ctr_libc as libc;
// stealing spin's mutex implementation for now
extern crate spin;
// The standard macros that are not built-in to the compiler.
#[macro_use]
mod macros;
// The Rust prelude
pub mod prelude;
// Public module declarations and reexports
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::any;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::cell;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::clone;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::cmp;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::convert;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::default;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::hash;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::intrinsics;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::iter;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::marker;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::mem;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::ops;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::ptr;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::raw;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::result;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::option;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::isize;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::i8;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::i16;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::i32;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::i64;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::usize;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::u8;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::u16;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::u32;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::u64;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::boxed;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::rc;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::borrow;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::fmt;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::slice;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::str;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;
#[stable(feature = "rust1", since = "1.0.0")]
pub use std_unicode::char;
pub mod f32;
pub mod f64;
pub mod ascii;
pub mod error;
pub mod ffi;
pub mod io;
pub mod num;
pub mod os;
pub mod path;
pub mod sync;
// Platform-abstraction modules
#[macro_use]
mod sys_common;
mod sys;
// Private support modules
mod panicking;
mod memchr;
// The runtime entry point and a few unstable public functions used by the
// compiler
pub mod rt;
// NOTE: These two are "undefined" symbols that LLVM emits but that
// we never actually use
#[doc(hidden)]
#[stable(feature = "3ds", since = "1.0.0")]
#[no_mangle]
pub unsafe extern "C" fn __aeabi_unwind_cpp_pr0() {
intrinsics::unreachable()
}
#[stable(feature = "3ds", since = "1.0.0")]
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn __aeabi_unwind_cpp_pr1() {
intrinsics::unreachable()
}

481
ctr-std/src/macros.rs

@ -0,0 +1,481 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Standard library macros
//!
//! This modules contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.
/// The entry point for panic of Rust threads.
///
/// This macro is used to inject panic into a Rust thread, causing the thread to
/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
/// and the single-argument form of the `panic!` macro will be the value which
/// is transmitted.
///
/// The multi-argument form of this macro panics with a string and has the
/// `format!` syntax for building a string.
///
/// # Examples
///
/// ```should_panic
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! panic {
() => ({
panic!("explicit panic")
});
($msg:expr) => ({
$crate::rt::begin_panic($msg, {
// static requires less code at runtime, more constant data
static _FILE_LINE: (&'static str, u32) = (file!(), line!());
&_FILE_LINE
})
});
($fmt:expr, $($arg:tt)+) => ({
$crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), {
// The leading _'s are to avoid dead code warnings if this is
// used inside a dead function. Just `#[allow(dead_code)]` is
// insufficient, since the user may have
// `#[forbid(dead_code)]` and which cannot be overridden.
static _FILE_LINE: (&'static str, u32) = (file!(), line!());
&_FILE_LINE
})
});
}
/// Macro for printing to the standard output.
///
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
///
/// Note that stdout is frequently line-buffered by default so it may be
/// necessary to use `io::stdout().flush()` to ensure the output is emitted
/// immediately.
///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples
///
/// ```
/// use std::io::{self, Write};
///
/// print!("this ");
/// print!("will ");
/// print!("be ");
/// print!("on ");
/// print!("the ");
/// print!("same ");
/// print!("line ");
///
/// io::stdout().flush().unwrap();
///
/// print!("this string has a newline, why not choose println! instead?\n");
///
/// io::stdout().flush().unwrap();
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! print {
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}
/// Macro for printing to the standard output, with a newline. On all
/// platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.
///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples
///
/// ```
/// println!();
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! println {
() => (print!("\n"));
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Examples
///
/// ```
/// #![feature(mpsc_select)]
///
/// use std::thread;
/// use std::sync::mpsc;
///
/// // two placeholder functions for now
/// fn long_running_thread() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); });
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
///
/// select! {
/// _ = rx1.recv() => println!("the long running thread finished first"),
/// answer = rx2.recv() => {
/// println!("the answer was: {}", answer.unwrap());
/// }
/// }
/// # drop(rx1.recv());
/// # drop(rx2.recv());
/// ```
///
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "mpsc_select", issue = "27800")]
macro_rules! select {
(
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+
) => ({
use $crate::sync::mpsc::Select;
let sel = Select::new();
$( let mut $rx = sel.handle(&$rx); )+
unsafe {
$( $rx.add(); )+
}
let ret = sel.wait();
$( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
{ unreachable!() }
})
}
#[cfg(test)]
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
}
/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(dox)]
pub mod builtin {
/// The core macro for formatted string creation & output.
///
/// This macro produces a value of type [`fmt::Arguments`]. This value can be
/// passed to the functions in [`std::fmt`] for performing useful functions.
/// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
/// proxied through this one.
///
/// For more information, see the documentation in [`std::fmt`].
///
/// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
/// [`std::fmt`]: ../std/fmt/index.html
/// [`format!`]: ../std/macro.format.html
/// [`write!`]: ../std/macro.write.html
/// [`println!`]: ../std/macro.println.html
///
/// # Examples
///
/// ```
/// use std::fmt;
///
/// let s = fmt::format(format_args!("hello {}", "world"));
/// assert_eq!(s, format!("hello {}", "world"));
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
/* compiler built-in */
}) }
/// Inspect an environment variable at compile time.
///
/// This macro will expand to the value of the named environment variable at
/// compile time, yielding an expression of type `&'static str`.
///
/// If the environment variable is not defined, then a compilation error
/// will be emitted. To not emit a compile error, use the `option_env!`
/// macro instead.
///
/// # Examples
///
/// ```
/// let path: &'static str = env!("PATH");
/// println!("the $PATH variable at the time of compiling was: {}", path);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }
/// Optionally inspect an environment variable at compile time.
///
/// If the named environment variable is present at compile time, this will
/// expand into an expression of type `Option<&'static str>` whose value is
/// `Some` of the value of the environment variable. If the environment
/// variable is not present, then this will expand to `None`.
///
/// A compile time error is never emitted when using this macro regardless
/// of whether the environment variable is present or not.
///
/// # Examples
///
/// ```
/// let key: Option<&'static str> = option_env!("SECRET_KEY");
/// println!("the secret key might be: {:?}", key);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }
/// Concatenate identifiers into one identifier.
///
/// This macro takes any number of comma-separated identifiers, and
/// concatenates them all into one, yielding an expression which is a new
/// identifier. Note that hygiene makes it such that this macro cannot
/// capture local variables. Also, as a general rule, macros are only
/// allowed in item, statement or expression position. That means while
/// you may use this macro for referring to existing variables, functions or
/// modules etc, you cannot define a new one with it.
///
/// # Examples
///
/// ```
/// #![feature(concat_idents)]
///
/// # fn main() {
/// fn foobar() -> u32 { 23 }
///
/// let f = concat_idents!(foo, bar);
/// println!("{}", f());
///
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
/// # }
/// ```
#[unstable(feature = "concat_idents_macro", issue = "29599")]
#[macro_export]
macro_rules! concat_idents {
($($e:ident),*) => ({ /* compiler built-in */ })
}
/// Concatenates literals into a static string slice.
///
/// This macro takes any number of comma-separated literals, yielding an
/// expression of type `&'static str` which represents all of the literals
/// concatenated left-to-right.
///
/// Integer and floating point literals are stringified in order to be
/// concatenated.
///
/// # Examples
///
/// ```
/// let s = concat!("test", 10, 'b', true);
/// assert_eq!(s, "test10btrue");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }
/// A macro which expands to the line number on which it was invoked.
///
/// The expanded expression has type `u32`, and the returned line is not
/// the invocation of the `line!()` macro itself, but rather the first macro
/// invocation leading up to the invocation of the `line!()` macro.
///
/// # Examples
///
/// ```
/// let current_line = line!();
/// println!("defined on line: {}", current_line);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! line { () => ({ /* compiler built-in */ }) }
/// A macro which expands to the column number on which it was invoked.
///
/// The expanded expression has type `u32`, and the returned column is not
/// the invocation of the `column!()` macro itself, but rather the first macro
/// invocation leading up to the invocation of the `column!()` macro.
///
/// # Examples
///
/// ```
/// let current_col = column!();
/// println!("defined on column: {}", current_col);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! column { () => ({ /* compiler built-in */ }) }
/// A macro which expands to the file name from which it was invoked.
///
/// The expanded expression has type `&'static str`, and the returned file
/// is not the invocation of the `file!()` macro itself, but rather the
/// first macro invocation leading up to the invocation of the `file!()`
/// macro.
///
/// # Examples
///
/// ```
/// let this_file = file!();
/// println!("defined in file: {}", this_file);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! file { () => ({ /* compiler built-in */ }) }
/// A macro which stringifies its argument.
///
/// This macro will yield an expression of type `&'static str` which is the
/// stringification of all the tokens passed to the macro. No restrictions
/// are placed on the syntax of the macro invocation itself.
///
/// Note that the expanded results of the input tokens may change in the
/// future. You should be careful if you rely on the output.
///
/// # Examples
///
/// ```
/// let one_plus_one = stringify!(1 + 1);
/// assert_eq!(one_plus_one, "1 + 1");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }
/// Includes a utf8-encoded file as a string.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
///
/// This macro will yield an expression of type `&'static str` which is the
/// contents of the file.
///
/// # Examples
///
/// ```rust,ignore
/// let secret_key = include_str!("secret-key.ascii");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }
/// Includes a file as a reference to a byte array.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
///
/// This macro will yield an expression of type `&'static [u8; N]` which is
/// the contents of the file.
///
/// # Examples
///
/// ```rust,ignore
/// let secret_key = include_bytes!("secret-key.bin");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }
/// Expands to a string that represents the current module path.
///
/// The current module path can be thought of as the hierarchy of modules
/// leading back up to the crate root. The first component of the path
/// returned is the name of the crate currently being compiled.
///
/// # Examples
///
/// ```
/// mod test {
/// pub fn foo() {
/// assert!(module_path!().ends_with("test"));
/// }
/// }
///
/// test::foo();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
/// Boolean evaluation of configuration flags.
///
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
/// boolean expression evaluation of configuration flags. This frequently
/// leads to less duplicated code.
///
/// The syntax given to this macro is the same syntax as [the `cfg`
/// attribute](../reference.html#conditional-compilation).
///
/// # Examples
///
/// ```
/// let my_directory = if cfg!(windows) {
/// "windows-specific-directory"
/// } else {
/// "unix-directory"
/// };
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
/// Parse a file as an expression or an item according to the context.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
///
/// Using this macro is often a bad idea, because if the file is
/// parsed as an expression, it is going to be placed in the
/// surrounding code unhygenically. This could result in variables
/// or functions being different from what the file expected if
/// there are variables or functions that have the same name in
/// the current file.
///
/// # Examples
///
/// ```ignore
/// fn foo() {
/// include!("/path/to/a/file")
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[macro_export]
macro_rules! include { ($file:expr) => ({ /* compiler built-in */ }) }
}

143
ctr-std/src/memchr.rs

@ -0,0 +1,143 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
#[inline]
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
::sys::memchr::memchr(needle, haystack)
}
/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
#[inline]
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
::sys::memchr::memrchr(needle, haystack)
}
#[cfg(test)]
mod tests {
// test the implementations for the current plattform
use super::{memchr, memrchr};
#[test]
fn matches_one() {
assert_eq!(Some(0), memchr(b'a', b"a"));
}
#[test]
fn matches_begin() {
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
}
#[test]
fn matches_end() {
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
}
#[test]
fn matches_nul() {
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul() {
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
}
#[test]
fn no_match_empty() {
assert_eq!(None, memchr(b'a', b""));
}
#[test]
fn no_match() {
assert_eq!(None, memchr(b'a', b"xyz"));
}
#[test]
fn matches_one_reversed() {
assert_eq!(Some(0), memrchr(b'a', b"a"));
}
#[test]
fn matches_begin_reversed() {
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
}
#[test]
fn matches_end_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
}
#[test]
fn matches_nul_reversed() {
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
}
#[test]
fn no_match_empty_reversed() {
assert_eq!(None, memrchr(b'a', b""));
}
#[test]
fn no_match_reversed() {
assert_eq!(None, memrchr(b'a', b"xyz"));
}
#[test]
fn each_alignment() {
let mut data = [1u8; 64];
let needle = 2;
let pos = 40;
data[pos] = needle;
for start in 0..16 {
assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
}
}
}

293
ctr-std/src/num.rs

@ -0,0 +1,293 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Additional functionality for numerics.
//!
//! This module provides some extra types that are useful when doing numerical
//! work. See the individual documentation for each piece for more information.
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
pub use core::num::{Zero, One};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::num::Wrapping;
#[cfg(test)] use fmt;
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T) where
T: PartialEq
+ Add<Output=T> + Sub<Output=T>
+ Mul<Output=T> + Div<Output=T>
+ Rem<Output=T> + fmt::Debug
+ Copy
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}
#[cfg(test)]
mod tests {
use u8;
use u16;
use u32;
use u64;
use usize;
use ops::Mul;
#[test]
fn test_saturating_add_uint() {
use usize::MAX;
assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
assert_eq!(3_usize.saturating_add(MAX-1), MAX);
assert_eq!(MAX.saturating_add(MAX), MAX);
assert_eq!((MAX-2).saturating_add(1), MAX-1);
}
#[test]
fn test_saturating_sub_uint() {
use usize::MAX;
assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
assert_eq!((MAX-1).saturating_sub(MAX), 0);
}
#[test]
fn test_saturating_add_int() {
use isize::{MIN,MAX};
assert_eq!(3i32.saturating_add(5), 8);
assert_eq!(3isize.saturating_add(MAX-1), MAX);
assert_eq!(MAX.saturating_add(MAX), MAX);
assert_eq!((MAX-2).saturating_add(1), MAX-1);
assert_eq!(3i32.saturating_add(-5), -2);
assert_eq!(MIN.saturating_add(-1), MIN);
assert_eq!((-2isize).saturating_add(-MAX), MIN);
}
#[test]
fn test_saturating_sub_int() {
use isize::{MIN,MAX};
assert_eq!(3i32.saturating_sub(5), -2);
assert_eq!(MIN.saturating_sub(1), MIN);
assert_eq!((-2isize).saturating_sub(MAX), MIN);
assert_eq!(3i32.saturating_sub(-5), 8);
assert_eq!(3isize.saturating_sub(-(MAX-1)), MAX);
assert_eq!(MAX.saturating_sub(-MAX), MAX);
assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
}
#[test]
fn test_checked_add() {
let five_less = usize::MAX - 5;
assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
assert_eq!(five_less.checked_add(5), Some(usize::MAX));
assert_eq!(five_less.checked_add(6), None);
assert_eq!(five_less.checked_add(7), None);
}
#[test]
fn test_checked_sub() {
assert_eq!(5_usize.checked_sub(0), Some(5));
assert_eq!(5_usize.checked_sub(1), Some(4));
assert_eq!(5_usize.checked_sub(2), Some(3));
assert_eq!(5_usize.checked_sub(3), Some(2));
assert_eq!(5_usize.checked_sub(4), Some(1));
assert_eq!(5_usize.checked_sub(5), Some(0));
assert_eq!(5_usize.checked_sub(6), None);
assert_eq!(5_usize.checked_sub(7), None);
}
#[test]
fn test_checked_mul() {
let third = usize::MAX / 3;
assert_eq!(third.checked_mul(0), Some(0));
assert_eq!(third.checked_mul(1), Some(third));
assert_eq!(third.checked_mul(2), Some(third * 2));
assert_eq!(third.checked_mul(3), Some(third * 3));
assert_eq!(third.checked_mul(4), None);
}
macro_rules! test_is_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).is_power_of_two(), false);
assert_eq!((1 as $T).is_power_of_two(), true);
assert_eq!((2 as $T).is_power_of_two(), true);
assert_eq!((3 as $T).is_power_of_two(), false);
assert_eq!((4 as $T).is_power_of_two(), true);
assert_eq!((5 as $T).is_power_of_two(), false);
assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
}
)
}
test_is_power_of_two!{ test_is_power_of_two_u8, u8 }
test_is_power_of_two!{ test_is_power_of_two_u16, u16 }
test_is_power_of_two!{ test_is_power_of_two_u32, u32 }
test_is_power_of_two!{ test_is_power_of_two_u64, u64 }
test_is_power_of_two!{ test_is_power_of_two_uint, usize }
macro_rules! test_next_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).next_power_of_two(), 1);
let mut next_power = 1;
for i in 1 as $T..40 {
assert_eq!(i.next_power_of_two(), next_power);
if i == next_power { next_power *= 2 }
}
}
)
}
test_next_power_of_two! { test_next_power_of_two_u8, u8 }
test_next_power_of_two! { test_next_power_of_two_u16, u16 }
test_next_power_of_two! { test_next_power_of_two_u32, u32 }
test_next_power_of_two! { test_next_power_of_two_u64, u64 }
test_next_power_of_two! { test_next_power_of_two_uint, usize }
macro_rules! test_checked_next_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
assert_eq!($T::MAX.checked_next_power_of_two(), None);
let mut next_power = 1;
for i in 1 as $T..40 {
assert_eq!(i.checked_next_power_of_two(), Some(next_power));
if i == next_power { next_power *= 2 }
}
}
)
}
test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
#[test]
fn test_pow() {
fn naive_pow<T: Mul<Output=T> + Copy>(one: T, base: T, exp: usize) -> T {
(0..exp).fold(one, |acc, _| acc * base)
}
macro_rules! assert_pow {
(($num:expr, $exp:expr) => $expected:expr) => {{
let result = $num.pow($exp);
assert_eq!(result, $expected);
assert_eq!(result, naive_pow(1, $num, $exp));
}}
}
assert_pow!((3u32, 0 ) => 1);
assert_pow!((5u32, 1 ) => 5);
assert_pow!((-4i32, 2 ) => 16);
assert_pow!((8u32, 3 ) => 512);
assert_pow!((2u64, 50) => 1125899906842624);
}
#[test]
fn test_uint_to_str_overflow() {
let mut u8_val: u8 = 255;
assert_eq!(u8_val.to_string(), "255");
u8_val = u8_val.wrapping_add(1);
assert_eq!(u8_val.to_string(), "0");
let mut u16_val: u16 = 65_535;
assert_eq!(u16_val.to_string(), "65535");
u16_val = u16_val.wrapping_add(1);
assert_eq!(u16_val.to_string(), "0");
let mut u32_val: u32 = 4_294_967_295;
assert_eq!(u32_val.to_string(), "4294967295");
u32_val = u32_val.wrapping_add(1);
assert_eq!(u32_val.to_string(), "0");
let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(u64_val.to_string(), "18446744073709551615");
u64_val = u64_val.wrapping_add(1);
assert_eq!(u64_val.to_string(), "0");
}
fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
::str::FromStr::from_str(t).ok()
}
#[test]
fn test_uint_from_str_overflow() {
let mut u8_val: u8 = 255;
assert_eq!(from_str::<u8>("255"), Some(u8_val));
assert_eq!(from_str::<u8>("256"), None);
u8_val = u8_val.wrapping_add(1);
assert_eq!(from_str::<u8>("0"), Some(u8_val));
assert_eq!(from_str::<u8>("-1"), None);
let mut u16_val: u16 = 65_535;
assert_eq!(from_str::<u16>("65535"), Some(u16_val));
assert_eq!(from_str::<u16>("65536"), None);
u16_val = u16_val.wrapping_add(1);
assert_eq!(from_str::<u16>("0"), Some(u16_val));
assert_eq!(from_str::<u16>("-1"), None);
let mut u32_val: u32 = 4_294_967_295;
assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
assert_eq!(from_str::<u32>("4294967296"), None);
u32_val = u32_val.wrapping_add(1);
assert_eq!(from_str::<u32>("0"), Some(u32_val));
assert_eq!(from_str::<u32>("-1"), None);
let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
assert_eq!(from_str::<u64>("18446744073709551616"), None);
u64_val = u64_val.wrapping_add(1);
assert_eq!(from_str::<u64>("0"), Some(u64_val));
assert_eq!(from_str::<u64>("-1"), None);
}
}
#[cfg(test)]
mod bench {
extern crate test;
use self::test::Bencher;
#[bench]
fn bench_pow_function(b: &mut Bencher) {
let v = (0..1024).collect::<Vec<u32>>();
b.iter(|| {v.iter().fold(0u32, |old, new| old.pow(*new as u32));});
}
}

17
ctr-std/src/os/mod.rs

@ -0,0 +1,17 @@
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! OS-specific functionality.
#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, bad_style)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use sys::ext as unix;

34
src/panic.rs → ctr-std/src/panicking.rs

@ -11,11 +11,9 @@
//! Implementation of various bits and pieces of the `panic!` macro and //! Implementation of various bits and pieces of the `panic!` macro and
//! associated runtime pieces. //! associated runtime pieces.
use core::fmt::{self, Display, Write}; use any::Any;
use core::any::Any; use fmt;
use __core::fmt::Display;
use collections::String;
use collections::boxed::Box;
///The compiler wants this to be here. Otherwise it won't be happy. And we like happy compilers. ///The compiler wants this to be here. Otherwise it won't be happy. And we like happy compilers.
#[lang = "eh_personality"] #[lang = "eh_personality"]
@ -23,7 +21,7 @@ extern fn eh_personality() {}
/// Entry point of panic from the libcore crate. /// Entry point of panic from the libcore crate.
#[lang = "panic_fmt"] #[lang = "panic_fmt"]
extern fn panic_fmt(msg: fmt::Arguments, file: &'static str, line: u32) -> ! { extern fn rust_begin_panic(msg: fmt::Arguments, file: &'static str, line: u32) -> ! {
begin_panic_fmt(&msg, &(file, line)) begin_panic_fmt(&msg, &(file, line))
} }
@ -33,9 +31,13 @@ extern fn panic_fmt(msg: fmt::Arguments, file: &'static str, line: u32) -> ! {
/// site as much as possible (so that `panic!()` has as low an impact /// site as much as possible (so that `panic!()` has as low an impact
/// on (e.g.) the inlining of other functions as possible), by moving /// on (e.g.) the inlining of other functions as possible), by moving
/// the actual formatting into this shared place. /// the actual formatting into this shared place.
#[inline(never)] #[unstable(feature = "libstd_sys_internals",
#[cold] reason = "used by the panic! macro",
issue = "0")]
#[inline(never)] #[cold]
pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) -> ! { pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
use fmt::Write;
let mut s = String::new(); let mut s = String::new();
let _ = s.write_fmt(*msg); let _ = s.write_fmt(*msg);
begin_panic(s, file_line); begin_panic(s, file_line);
@ -45,21 +47,13 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) ->
#[inline(never)] #[inline(never)]
#[cold] #[cold]
pub fn begin_panic<M: Any + Send + Display>(msg: M, file_line: &(&'static str, u32)) -> ! { pub fn begin_panic<M: Any + Send + Display>(msg: M, file_line: &(&'static str, u32)) -> ! {
use gfx::Screen;
use console::Console;
let msg = Box::new(msg); let msg = Box::new(msg);
let (file, line) = *file_line; let (file, line) = *file_line;
let mut error_top = Console::init(Screen::Top); print!("--------------------------------------------------");
let mut error_bottom = Console::init(Screen::Bottom); println!("PANIC in {} at line {}:", file, line);
println!(" {}", msg);
write!(error_top, "--------------------------------------------------").unwrap(); print!("\x1b[29;00H--------------------------------------------------");
writeln!(error_top, "PANIC in {} at line {}:", file, line).unwrap();
writeln!(error_top, " {}", msg).unwrap();
write!(error_top, "\x1b[29;00H--------------------------------------------------").unwrap();
write!(error_bottom, "").unwrap();
loop {} loop {}
} }

617
src/path.rs → ctr-std/src/path.rs

File diff suppressed because it is too large Load Diff

146
ctr-std/src/prelude/mod.rs

@ -0,0 +1,146 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Rust Prelude.
//!
//! Rust comes with a variety of things in its standard library. However, if
//! you had to manually import every single thing that you used, it would be
//! very verbose. But importing a lot of things that a program never uses isn't
//! good either. A balance needs to be struck.
//!
//! The *prelude* is the list of things that Rust automatically imports into
//! every Rust program. It's kept as small as possible, and is focused on
//! things, particularly traits, which are used in almost every single Rust
//! program.
//!
//! On a technical level, Rust inserts
//!
//! ```ignore
//! extern crate std;
//! ```
//!
//! into the crate root of every crate, and
//!
//! ```ignore
//! use std::prelude::v1::*;
//! ```
//!
//! into every module.
//!
//! # Other preludes
//!
//! Preludes can be seen as a pattern to make using multiple types more
//! convenient. As such, you'll find other preludes in the standard library,
//! such as [`std::io::prelude`]. Various libraries in the Rust ecosystem may
//! also define their own preludes.
//!
//! [`std::io::prelude`]: ../io/prelude/index.html
//!
//! The difference between 'the prelude' and these other preludes is that they
//! are not automatically `use`'d, and must be imported manually. This is still
//! easier than importing all of their constituent components.
//!
//! # Prelude contents
//!
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`], and reexports the following.
//!
//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`]}. The marker
//! traits indicate fundamental properties of types.
//! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}. Various
//! operations for both destructors and overloading `()`.
//! * [`std::mem`]::[`drop`], a convenience function for explicitly dropping a
//! value.
//! * [`std::boxed`]::[`Box`], a way to allocate values on the heap.
//! * [`std::borrow`]::[`ToOwned`], The conversion trait that defines
//! [`to_owned()`], the generic method for creating an owned type from a
//! borrowed type.
//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines [`clone()`],
//! the method for producing a copy of a value.
//! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] }. The
//! comparison traits, which implement the comparison operators and are often
//! seen in trait bounds.
//! * [`std::convert`]::{[`AsRef`], [`AsMut`], [`Into`], [`From`]}. Generic
//! conversions, used by savvy API authors to create overloaded methods.
//! * [`std::default`]::[`Default`], types that have default values.
//! * [`std::iter`]::{[`Iterator`], [`Extend`], [`IntoIterator`],
//! [`DoubleEndedIterator`], [`ExactSizeIterator`]}. Iterators of various
//! kinds.
//! * [`std::option`]::[`Option`]::{`self`, `Some`, `None`}. A type which
//! expresses the presence or absence of a value. This type is so commonly
//! used, its variants are also exported.
//! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions
//! that may succeed or fail. Like [`Option`], its variants are exported as
//! well.
//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical
//! reasons, but shouldn't have to exist. It provides a few useful methods on
//! slices.
//! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings.
//! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated
//! vector.
//!
//! [`AsMut`]: ../convert/trait.AsMut.html
//! [`AsRef`]: ../convert/trait.AsRef.html
//! [`Box`]: ../boxed/struct.Box.html
//! [`Clone`]: ../clone/trait.Clone.html
//! [`Copy`]: ../marker/trait.Copy.html
//! [`Default`]: ../default/trait.Default.html
//! [`DoubleEndedIterator`]: ../iter/trait.DoubleEndedIterator.html
//! [`Drop`]: ../ops/trait.Drop.html
//! [`Eq`]: ../cmp/trait.Eq.html
//! [`ExactSizeIterator`]: ../iter/trait.ExactSizeIterator.html
//! [`Extend`]: ../iter/trait.Extend.html
//! [`FnMut`]: ../ops/trait.FnMut.html
//! [`FnOnce`]: ../ops/trait.FnOnce.html
//! [`Fn`]: ../ops/trait.Fn.html
//! [`From`]: ../convert/trait.From.html
//! [`IntoIterator`]: ../iter/trait.IntoIterator.html
//! [`Into`]: ../convert/trait.Into.html
//! [`Iterator`]: ../iter/trait.Iterator.html
//! [`Option`]: ../option/enum.Option.html
//! [`Ord`]: ../cmp/trait.Ord.html
//! [`PartialEq`]: ../cmp/trait.PartialEq.html
//! [`PartialOrd`]: ../cmp/trait.PartialOrd.html
//! [`Result`]: ../result/enum.Result.html
//! [`Send`]: ../marker/trait.Send.html
//! [`Sized`]: ../marker/trait.Sized.html
//! [`SliceConcatExt`]: ../slice/trait.SliceConcatExt.html
//! [`String`]: ../string/struct.String.html
//! [`Sync`]: ../marker/trait.Sync.html
//! [`ToOwned`]: ../borrow/trait.ToOwned.html
//! [`ToString`]: ../string/trait.ToString.html
//! [`Vec`]: ../vec/struct.Vec.html
//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
//! [`drop`]: ../mem/fn.drop.html
//! [`std::borrow`]: ../borrow/index.html
//! [`std::boxed`]: ../boxed/index.html
//! [`std::clone`]: ../clone/index.html
//! [`std::cmp`]: ../cmp/index.html
//! [`std::convert`]: ../convert/index.html
//! [`std::default`]: ../default/index.html
//! [`std::iter`]: ../iter/index.html
//! [`std::marker`]: ../marker/index.html
//! [`std::mem`]: ../mem/index.html
//! [`std::ops`]: ../ops/index.html
//! [`std::option`]: ../option/index.html
//! [`std::prelude::v1`]: v1/index.html
//! [`std::result`]: ../result/index.html
//! [`std::slice`]: ../slice/index.html
//! [`std::string`]: ../string/index.html
//! [`std::vec`]: ../vec/index.html
//! [`to_owned()`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
//! [book-closures]: ../../book/closures.html
//! [book-dtor]: ../../book/drop.html
//! [book-enums]: ../../book/enums.html
//! [book-iter]: ../../book/iterators.html
#![stable(feature = "rust1", since = "1.0.0")]
pub mod v1;

53
ctr-std/src/prelude/v1.rs

@ -0,0 +1,53 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The first version of the prelude of The Rust Standard Library.
//!
//! See the [module-level documentation](../index.html) for more.
#![stable(feature = "rust1", since = "1.0.0")]
// Reexported core operators
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
// Reexported functions
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use mem::drop;
// Reexported types and traits
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use boxed::Box;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use borrow::ToOwned;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use clone::Clone;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use default::Default;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use option::Option::{self, Some, None};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use result::Result::{self, Ok, Err};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use slice::SliceConcatExt;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use string::{String, ToString};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use vec::Vec;

36
ctr-std/src/rt.rs

@ -0,0 +1,36 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.
#![unstable(feature = "rt",
reason = "this public module should not exist and is highly likely \
to disappear",
issue = "0")]
#![doc(hidden)]
use mem;
// Reexport some of our utilities which are expected by other crates.
pub use panicking::{begin_panic, begin_panic_fmt};
//TODO: Handle argc/argv arguments
#[lang = "start"]
#[allow(unused_variables)]
fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
unsafe { mem::transmute::<_, fn()>(main)(); }
0
}

29
ctr-std/src/sync/mod.rs

@ -0,0 +1,29 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Useful synchronization primitives.
//!
//! This module contains useful safe and unsafe synchronization primitives.
//! Most of the primitives in this module do not provide any sort of locking
//! and/or blocking at all, but rather provide the necessary tools to build
//! other types of concurrent primitives.
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::arc::{Arc, Weak};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::sync::atomic;
// Easy cheat until we get proper locks based on libctru code
#[stable(feature = "3ds", since = "1.0.0")]
pub use spin::{Mutex, MutexGuard};
#[stable(feature = "3ds", since = "1.0.0")]
pub use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};

37
ctr-std/src/sys/mod.rs

@ -0,0 +1,37 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Platform-dependent platform abstraction
//!
//! The `std::sys` module is the abstracted interface through which
//! `std` talks to the underlying operating system. It has different
//! implementations for different operating system families, today
//! just Unix and Windows.
//!
//! The centralization of platform-specific code in this module is
//! enforced by the "platform abstraction layer" tidy script in
//! `tools/tidy/pal.rs`.
//!
//! This module is closely related to the platform-independent system
//! integration code in `std::sys_common`. See that module's
//! documentation for details.
//!
//! In the future it would be desirable for the indepedent
//! implementations of this module to be extracted to their own crates
//! that `std` can link to, thus enabling their implementation
//! out-of-tree via crate replacement. Though due to the complex
//! inter-dependencies within `std` that will be a challenging goal to
//! achieve.
pub use self::imp::*;
#[cfg(unix)]
#[path = "unix/mod.rs"]
mod imp;

61
ctr-std/src/sys/unix/ext/ffi.rs

@ -0,0 +1,61 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Unix-specific extension to the primitives in the `std::ffi` module
#![stable(feature = "rust1", since = "1.0.0")]
use ffi::{OsStr, OsString};
use mem;
use sys::os_str::Buf;
use sys_common::{FromInner, IntoInner, AsInner};
/// Unix-specific extensions to `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
/// Creates an `OsString` from a byte vector.
#[stable(feature = "rust1", since = "1.0.0")]
fn from_vec(vec: Vec<u8>) -> Self;
/// Yields the underlying byte vector of this `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
fn into_vec(self) -> Vec<u8>;
}
#[stable(feature = "rust1", since = "1.0.0")]
impl OsStringExt for OsString {
fn from_vec(vec: Vec<u8>) -> OsString {
FromInner::from_inner(Buf { inner: vec })
}
fn into_vec(self) -> Vec<u8> {
self.into_inner().inner
}
}
/// Unix-specific extensions to `OsStr`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
#[stable(feature = "rust1", since = "1.0.0")]
fn from_bytes(slice: &[u8]) -> &Self;
/// Gets the underlying byte view of the `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
fn as_bytes(&self) -> &[u8];
}
#[stable(feature = "rust1", since = "1.0.0")]
impl OsStrExt for OsStr {
fn from_bytes(slice: &[u8]) -> &OsStr {
unsafe { mem::transmute(slice) }
}
fn as_bytes(&self) -> &[u8] {
&self.as_inner().inner
}
}

41
ctr-std/src/sys/unix/ext/mod.rs

@ -0,0 +1,41 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Experimental extensions to `std` for Unix platforms.
//!
//! For now, this module is limited to extracting file descriptors,
//! but its functionality will grow over time.
//!
//! # Example
//!
//! ```no_run
//! use std::fs::File;
//! use std::os::unix::prelude::*;
//!
//! fn main() {
//! let f = File::create("foo.txt").unwrap();
//! let fd = f.as_raw_fd();
//!
//! // use fd with native unix bindings
//! }
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
pub mod ffi;
/// A prelude for conveniently writing platform-specific code.
///
/// Includes all extension traits, and some important type definitions.
#[stable(feature = "rust1", since = "1.0.0")]
pub mod prelude {
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::ffi::{OsStrExt, OsStringExt};
}

51
ctr-std/src/sys/unix/memchr.rs

@ -0,0 +1,51 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
use libc;
let p = unsafe {
libc::memchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len())
};
if p.is_null() {
None
} else {
Some(p as usize - (haystack.as_ptr() as usize))
}
}
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
#[cfg(target_os = "linux")]
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
use libc;
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
if haystack.is_empty() {return None}
let p = unsafe {
libc::memrchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len())
};
if p.is_null() {
None
} else {
Some(p as usize - (haystack.as_ptr() as usize))
}
}
memrchr_specific(needle, haystack)
}

50
ctr-std/src/sys/unix/mod.rs

@ -0,0 +1,50 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(missing_docs, bad_style)]
pub mod ext;
pub mod memchr;
pub mod os;
pub mod os_str;
pub mod path;
use io::ErrorKind;
use libc;
pub fn decode_error_kind(errno: i32) -> ErrorKind {
match errno as libc::c_int {
libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
libc::ECONNRESET => ErrorKind::ConnectionReset,
libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
libc::EPIPE => ErrorKind::BrokenPipe,
libc::ENOTCONN => ErrorKind::NotConnected,
libc::ECONNABORTED => ErrorKind::ConnectionAborted,
libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
libc::EADDRINUSE => ErrorKind::AddrInUse,
libc::ENOENT => ErrorKind::NotFound,
libc::EINTR => ErrorKind::Interrupted,
libc::EINVAL => ErrorKind::InvalidInput,
libc::ETIMEDOUT => ErrorKind::TimedOut,
libc::EEXIST => ErrorKind::AlreadyExists,
// These two constants can have the same value on some systems,
// but different values on others, so we can't use a match
// clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
ErrorKind::WouldBlock,
_ => ErrorKind::Other,
}
}
pub unsafe fn abort_internal() -> ! {
::libc::abort()
}

123
ctr-std/src/sys/unix/os.rs

@ -0,0 +1,123 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Implementation of `std::os` functionality for unix systems
#![allow(unused_imports)] // lots of cfg code here
use os::unix::prelude::*;
use error::Error as StdError;
use ffi::{CString, CStr, OsString, OsStr};
use fmt;
use io;
use iter;
use libc::{self, c_int, c_char, c_void};
use marker::PhantomData;
use mem;
use memchr;
use path::{self, PathBuf};
use ptr;
use slice;
use str;
use vec;
const TMPBUF_SZ: usize = 128;
extern "C" {
fn __errno() -> *mut c_int;
}
/// Returns the platform-specific value of errno
pub fn errno() -> i32 {
unsafe {
(*__errno()) as i32
}
}
/// Gets a detailed string description for the given error number.
pub fn error_string(errno: i32) -> String {
extern {
#[cfg_attr(any(target_os = "linux", target_env = "newlib"),
link_name = "__xpg_strerror_r")]
fn strerror_r(errnum: c_int, buf: *mut c_char,
buflen: libc::size_t) -> c_int;
}
let mut buf = [0 as c_char; TMPBUF_SZ];
let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
let p = p as *const _;
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
}
}
pub struct SplitPaths<'a> {
iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
fn(&'a [u8]) -> PathBuf>,
}
pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
fn bytes_to_path(b: &[u8]) -> PathBuf {
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
}
fn is_colon(b: &u8) -> bool { *b == b':' }
let unparsed = unparsed.as_bytes();
SplitPaths {
iter: unparsed.split(is_colon as fn(&u8) -> bool)
.map(bytes_to_path as fn(&[u8]) -> PathBuf)
}
}
impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[derive(Debug)]
pub struct JoinPathsError;
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
where I: Iterator<Item=T>, T: AsRef<OsStr>
{
let mut joined = Vec::new();
let sep = b':';
for (i, path) in paths.enumerate() {
let path = path.as_ref().as_bytes();
if i > 0 { joined.push(sep) }
if path.contains(&sep) {
return Err(JoinPathsError)
}
joined.extend_from_slice(path);
}
Ok(OsStringExt::from_vec(joined))
}
impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
"path segment contains separator `:`".fmt(f)
}
}
impl StdError for JoinPathsError {
fn description(&self) -> &str { "failed to join paths" }
}
pub fn exit(code: i32) -> ! {
unsafe { libc::exit(code as c_int) }
}

119
ctr-std/src/sys/unix/os_str.rs

@ -0,0 +1,119 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/// The underlying OsString/OsStr implementation on Unix systems: just
/// a `Vec<u8>`/`[u8]`.
use borrow::Cow;
use fmt::{self, Debug};
use str;
use mem;
use sys_common::{AsInner, IntoInner};
#[derive(Clone, Hash)]
pub struct Buf {
pub inner: Vec<u8>
}
pub struct Slice {
pub inner: [u8]
}
impl Debug for Slice {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.to_string_lossy().fmt(formatter)
}
}
impl Debug for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.as_slice().fmt(formatter)
}
}
impl IntoInner<Vec<u8>> for Buf {
fn into_inner(self) -> Vec<u8> {
self.inner
}
}
impl AsInner<[u8]> for Buf {
fn as_inner(&self) -> &[u8] {
&self.inner
}
}
impl Buf {
pub fn from_string(s: String) -> Buf {
Buf { inner: s.into_bytes() }
}
#[inline]
pub fn with_capacity(capacity: usize) -> Buf {
Buf {
inner: Vec::with_capacity(capacity)
}
}
#[inline]
pub fn clear(&mut self) {
self.inner.clear()
}
#[inline]
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}
pub fn as_slice(&self) -> &Slice {
unsafe { mem::transmute(&*self.inner) }
}
pub fn into_string(self) -> Result<String, Buf> {
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
}
pub fn push_slice(&mut self, s: &Slice) {
self.inner.extend_from_slice(&s.inner)
}
}
impl Slice {
fn from_u8_slice(s: &[u8]) -> &Slice {
unsafe { mem::transmute(s) }
}
pub fn from_str(s: &str) -> &Slice {
Slice::from_u8_slice(s.as_bytes())
}
pub fn to_str(&self) -> Option<&str> {
str::from_utf8(&self.inner).ok()
}
pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(&self.inner)
}
pub fn to_owned(&self) -> Buf {
Buf { inner: self.inner.to_vec() }
}
}

29
ctr-std/src/sys/unix/path.rs

@ -0,0 +1,29 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use path::Prefix;
use ffi::OsStr;
#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/'
}
#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/'
}
pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
None
}
pub const MAIN_SEP_STR: &'static str = "/";
pub const MAIN_SEP: char = '/';

179
ctr-std/src/sys_common/io.rs

@ -0,0 +1,179 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use io;
use io::ErrorKind;
use io::Read;
use slice::from_raw_parts_mut;
pub const DEFAULT_BUF_SIZE: usize = 8 * 1024;
// Provides read_to_end functionality over an uninitialized buffer.
// This function is unsafe because it calls the underlying
// read function with a slice into uninitialized memory. The default
// implementation of read_to_end for readers will zero out new memory in
// the buf before passing it to read, but avoiding this zero can often
// lead to a fairly significant performance win.
//
// Implementations using this method have to adhere to two guarantees:
// * The implementation of read never reads the buffer provided.
// * The implementation of read correctly reports how many bytes were written.
pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::Result<usize> {
let start_len = buf.len();
buf.reserve(16);
// Always try to read into the empty space of the vector (from the length to the capacity).
// If the vector ever fills up then we reserve an extra byte which should trigger the normal
// reallocation routines for the vector, which will likely double the size.
//
// This function is similar to the read_to_end function in std::io, but the logic about
// reservations and slicing is different enough that this is duplicated here.
loop {
if buf.len() == buf.capacity() {
buf.reserve(1);
}
let buf_slice = from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize),
buf.capacity() - buf.len());
match r.read(buf_slice) {
Ok(0) => { return Ok(buf.len() - start_len); }
Ok(n) => { let len = buf.len() + n; buf.set_len(len); },
Err(ref e) if e.kind() == ErrorKind::Interrupted => { }
Err(e) => { return Err(e); }
}
}
}
#[cfg(test)]
#[allow(dead_code)] // not used on emscripten
pub mod test {
use path::{Path, PathBuf};
use env;
use rand::{self, Rng};
use fs;
pub struct TempDir(PathBuf);
impl TempDir {
pub fn join(&self, path: &str) -> PathBuf {
let TempDir(ref p) = *self;
p.join(path)
}
pub fn path<'a>(&'a self) -> &'a Path {
let TempDir(ref p) = *self;
p
}
}
impl Drop for TempDir {
fn drop(&mut self) {
// Gee, seeing how we're testing the fs module I sure hope that we
// at least implement this correctly!
let TempDir(ref p) = *self;
fs::remove_dir_all(p).unwrap();
}
}
pub fn tmpdir() -> TempDir {
let p = env::temp_dir();
let mut r = rand::thread_rng();
let ret = p.join(&format!("rust-{}", r.next_u32()));
fs::create_dir(&ret).unwrap();
TempDir(ret)
}
}
#[cfg(test)]
mod tests {
use io::prelude::*;
use super::*;
use io;
use io::{ErrorKind, Take, Repeat, repeat};
use slice::from_raw_parts;
struct ErrorRepeat {
lr: Take<Repeat>
}
fn error_repeat(byte: u8, limit: u64) -> ErrorRepeat {
ErrorRepeat { lr: repeat(byte).take(limit) }
}
impl Read for ErrorRepeat {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let ret = self.lr.read(buf);
if let Ok(0) = ret {
return Err(io::Error::new(ErrorKind::Other, ""))
}
ret
}
}
fn init_vec_data() -> Vec<u8> {
let mut vec = vec![10u8; 200];
unsafe { vec.set_len(0); }
vec
}
fn assert_all_eq(buf: &[u8], value: u8) {
for n in buf {
assert_eq!(*n, value);
}
}
fn validate(buf: &Vec<u8>, good_read_len: usize) {
assert_all_eq(buf, 1u8);
let cap = buf.capacity();
let end_slice = unsafe { from_raw_parts(buf.as_ptr().offset(good_read_len as isize),
cap - good_read_len) };
assert_all_eq(end_slice, 10u8);
}
#[test]
fn read_to_end_uninit_error() {
let mut er = error_repeat(1,100);
let mut vec = init_vec_data();
if let Err(_) = unsafe { read_to_end_uninitialized(&mut er, &mut vec) } {
validate(&vec, 100);
} else {
assert!(false);
}
}
#[test]
fn read_to_end_uninit_zero_len_vec() {
let mut er = repeat(1).take(100);
let mut vec = Vec::new();
let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() };
assert_all_eq(&vec, 1u8);
assert_eq!(vec.len(), n);
}
#[test]
fn read_to_end_uninit_good() {
let mut er = repeat(1).take(100);
let mut vec = init_vec_data();
let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() };
validate(&vec, 100);
assert_eq!(vec.len(), n);
}
#[bench]
#[cfg_attr(target_os = "emscripten", ignore)]
fn bench_uninitialized(b: &mut ::test::Bencher) {
b.iter(|| {
let mut lr = repeat(1).take(10000000);
let mut vec = Vec::with_capacity(1024);
unsafe { read_to_end_uninitialized(&mut lr, &mut vec) }
});
}
}

76
ctr-std/src/sys_common/mod.rs

@ -0,0 +1,76 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Platform-independent platform abstraction
//!
//! This is the platform-independent portion of the standard libraries
//! platform abstraction layer, whereas `std::sys` is the
//! platform-specific portion.
//!
//! The relationship between `std::sys_common`, `std::sys` and the
//! rest of `std` is complex, with dependencies going in all
//! directions: `std` depending on `sys_common`, `sys_common`
//! depending on `sys`, and `sys` depending on `sys_common` and `std`.
//! Ideally `sys_common` would be split into two and the dependencies
//! between them all would form a dag, facilitating the extraction of
//! `std::sys` from the standard library.
#![allow(missing_docs)]
pub mod io;
// common error constructors
/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInner<Inner: ?Sized> {
fn as_inner(&self) -> &Inner;
}
/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInnerMut<Inner: ?Sized> {
fn as_inner_mut(&mut self) -> &mut Inner;
}
/// A trait for extracting representations from std types
#[doc(hidden)]
pub trait IntoInner<Inner> {
fn into_inner(self) -> Inner;
}
/// A trait for creating std types from internal representations
#[doc(hidden)]
pub trait FromInner<Inner> {
fn from_inner(inner: Inner) -> Self;
}
macro_rules! rtabort {
($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*)))
}
// Computes (value*numer)/denom without overflow, as long as both
// (numer*denom) and the overall result fit into i64 (which is the case
// for our time conversions).
#[allow(dead_code)] // not used on all platforms
pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 {
let q = value / denom;
let r = value % denom;
// Decompose value as (value/denom*denom + value%denom),
// substitute into (value*numer)/denom and simplify.
// r < denom, so (denom*numer) is the upper bound of (r*numer)
q * numer + r * numer / denom
}
#[test]
fn test_muldiv() {
assert_eq!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000),
1_000_000_000_001_000);
}

31
ctru-rs/3ds.json

@ -0,0 +1,31 @@
{
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"llvm-target": "arm-none-eabihf",
"linker": "arm-none-eabi-gcc",
"ar": "arm-none-eabi-ar",
"target-endian": "little",
"target-pointer-width": "32",
"target-family": "unix",
"arch": "arm",
"os": "linux",
"env": "newlib",
"cpu": "mpcore",
"features": "+vfp2",
"relocation-model": "static",
"executables": true,
"exe-suffix": ".elf",
"panic-strategy": "abort",
"pre-link-args": [
"-specs=3dsx.specs",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-mtp=soft"
],
"post-link-args": [
"-lc",
"-lm",
"-lsysbase",
"-lc"
]
}

19
Cargo.toml → ctru-rs/Cargo.toml

@ -1,18 +1,19 @@
[package] [package]
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
build = "build.rs"
description = "A safe wrapper around smealum's ctrulib." description = "A safe wrapper around smealum's ctrulib."
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
links = "ctru"
name = "ctru-rs" name = "ctru-rs"
version = "0.4.0" version = "0.5.0"
[dependencies.ctru-sys]
path = "ctru-sys"
[dependencies.alloc_system3ds]
git = "https://github.com/rust3ds/alloc_system3ds"
[lib] [lib]
crate-type = ["rlib"] crate-type = ["rlib"]
name = "ctru" name = "ctru"
[dependencies.ctru-sys]
path = "../ctru-sys"
[dependencies.bitflags]
version = "0.7.0"
[dependencies.widestring]
version = "0.2.2"

44
ctru-rs/README.md

@ -0,0 +1,44 @@
# ctru-rs
A Rust wrapper library for smealum's
[ctrulib](https://github.com/smealum/ctrulib).
See the [3DS project template](https://github.com/rust3ds/rust3ds-template) for instructions on how to use this library.
## Structure
This library is meant to expose 3DS-specific functionality. Common functionality is implemented in `ctr-std` when possible.
## Contributing
PR's are welcome. Organization of rust specific features and wrapper functionality are still being decided on.
## License
Copyright (C) Rust 3DS Project authors, 2015-2016
See AUTHORS.md.
As with the original ctrulib, this library is licensed under zlib. This
applies to every file in the tree, unless otherwise noted.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.
See [LICENSE-APACHE](https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE), [LICENSE-MIT](https://github.com/rust-lang/rust/blob/master/LICENSE-MIT), and [COPYRIGHT](https://github.com/rust-lang/rust/blob/master/COPYRIGHT) for details.

9
ctru-rs/Xargo.toml

@ -0,0 +1,9 @@
[dependencies.collections]
[dependencies.ctr-libc]
path = "../ctr-libc"
stage = 1
[dependencies.std]
path = "../ctr-std"
stage = 2

37
ctru-rs/src/console.rs

@ -0,0 +1,37 @@
use std::default::Default;
use std::ptr;
use gfx::Screen;
use libctru::console::*;
pub struct Console {
context: PrintConsole,
}
impl Console {
pub fn init(screen: Screen) -> Self {
unsafe {
let ret = *(consoleInit(screen.into(), ptr::null_mut()));
Console { context: ret }
}
}
pub fn select(&mut self) {
unsafe { consoleSelect(&mut self.context); }
}
pub fn set_window(&mut self, x: i32, y: i32, width: i32, height: i32) {
unsafe { consoleSetWindow(&mut self.context, x, y, width, height) }
}
pub fn clear(&mut self) {
unsafe { consoleClear() }
}
}
impl Default for Console {
fn default() -> Self {
Console::init(Screen::Top)
}
}

38
ctru-rs/src/error.rs

@ -0,0 +1,38 @@
use std::error;
use std::fmt;
pub type Result<T> = ::std::result::Result<T, Error>;
/// The error type returned by all libctru functions.
pub enum Error {
Os(i32),
}
impl From<i32> for Error {
fn from(err: i32) -> Self {
Error::Os(err)
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Os(err) => write!(f, "libctru result code: {:08X}", err),
}
}
}
// TODO: Expand libctru result code into human-readable error message
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Os(err) => write!(f, "libctru result code: 0x{:08X}", err),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"error originating from a libctru function"
}
}

14
src/gfx.rs → ctru-rs/src/gfx.rs

@ -1,8 +1,8 @@
use libctru::gfx; use libctru::gfx;
use core::default::Default; use std::default::Default;
use core::marker::PhantomData; use std::marker::PhantomData;
use core::ops::Drop; use std::ops::Drop;
use services::gspgpu::FramebufferFormat; use services::gspgpu::FramebufferFormat;
@ -82,9 +82,9 @@ impl Gfx {
} }
pub fn get_framebuffer(&mut self, screen: Screen, side: Side) -> (&'static mut [u8], u16, u16) { pub fn get_framebuffer(&mut self, screen: Screen, side: Side) -> (&'static mut [u8], u16, u16) {
use core::convert::Into; use std::convert::Into;
unsafe { unsafe {
use core::slice::from_raw_parts_mut; use std::slice::from_raw_parts_mut;
let mut w: u16 = 0; let mut w: u16 = 0;
let mut h: u16 = 0; let mut h: u16 = 0;
@ -112,12 +112,12 @@ impl Gfx {
} }
pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat { pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat {
use core::convert::Into; use std::convert::Into;
unsafe { gfx::gfxGetScreenFormat(screen.into()).into() } unsafe { gfx::gfxGetScreenFormat(screen.into()).into() }
} }
pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) { pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) {
use core::convert::Into; use std::convert::Into;
unsafe { gfx::gfxSetScreenFormat(screen.into(), fmt.into()) } unsafe { gfx::gfxSetScreenFormat(screen.into(), fmt.into()) }
} }

21
ctru-rs/src/lib.rs

@ -0,0 +1,21 @@
#![crate_type = "rlib"]
#![crate_name = "ctru"]
#[macro_use]
extern crate bitflags;
extern crate widestring;
extern crate ctru_sys as libctru;
pub mod console;
pub mod error;
pub mod srv;
pub mod gfx;
pub mod services;
pub mod sdmc;
pub use error::{Result, Error};
pub use srv::Srv;
pub use gfx::Gfx;
pub use sdmc::Sdmc;

6
src/sdmc.rs → ctru-rs/src/sdmc.rs

@ -1,4 +1,4 @@
use core::marker::PhantomData; use std::marker::PhantomData;
use libctru::sdmc::*; use libctru::sdmc::*;
@ -7,11 +7,11 @@ pub struct Sdmc {
} }
impl Sdmc { impl Sdmc {
pub fn init() -> Result<Sdmc, i32> { pub fn init() -> ::Result<Sdmc> {
unsafe { unsafe {
let r = sdmcInit(); let r = sdmcInit();
if r < 0 { if r < 0 {
Err(r) Err(::Error::from(r))
} else { } else {
Ok(Sdmc { pd: PhantomData }) Ok(Sdmc { pd: PhantomData })
} }

36
ctru-rs/src/services/apt.rs

@ -0,0 +1,36 @@
use std::marker::PhantomData;
use libctru::services::apt;
pub struct Apt {
pd: PhantomData<i32>
}
impl Apt {
pub fn init() -> ::Result<Apt> {
unsafe {
let r = apt::aptInit();
if r < 0 {
Err(::Error::from(r))
} else {
Ok(Apt { pd: PhantomData })
}
}
}
pub fn main_loop(&self) -> bool {
unsafe {
match apt::aptMainLoop() {
1 => true,
0 => false,
_ => unreachable!(),
}
}
}
}
impl Drop for Apt {
fn drop(&mut self) {
unsafe { apt::aptExit() };
}
}

286
src/services/fs.rs → ctru-rs/src/services/fs.rs

@ -3,19 +3,47 @@
//! This module contains basic methods to manipulate the contents of the 3DS's filesystem. //! This module contains basic methods to manipulate the contents of the 3DS's filesystem.
//! Only the SD card is currently supported. //! Only the SD card is currently supported.
use std::io::{Read, Write, Seek, SeekFrom};
use std::io::Error as IoError;
use std::io::Result as IoResult;
use std::io::ErrorKind as IoErrorKind;
use core::marker::PhantomData; use std::ffi::OsString;
use core::ptr; use std::marker::PhantomData;
use core::slice; use std::ptr;
use core::mem; use std::slice;
use alloc::arc::Arc; use std::mem;
use collections::Vec; use std::path::{Path, PathBuf};
use std::sync::Arc;
use path::{Path, PathBuf}; use widestring::{WideCString, WideCStr};
use ffi::OsString;
use libctru::services::fs::*; use libctru::services::fs::*;
bitflags! {
flags FsOpen: u32 {
const FS_OPEN_READ = 1,
const FS_OPEN_WRITE = 2,
const FS_OPEN_CREATE = 4,
}
}
bitflags! {
flags FsWrite: u32 {
const FS_WRITE_FLUSH = 1,
const FS_WRITE_UPDATE_TIME = 256,
}
}
bitflags! {
flags FsAttribute: u32 {
const FS_ATTRIBUTE_DIRECTORY = 1,
const FS_ATTRIBUTE_HIDDEN = 256,
const FS_ATTRIBUTE_ARCHIVE = 65536,
const FS_ATTRIBUTE_READ_ONLY = 16777216,
}
}
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum PathType { pub enum PathType {
Invalid, Invalid,
@ -82,6 +110,63 @@ pub struct Archive {
/// on what options It was opened with. /// on what options It was opened with.
/// ///
/// Files are automatically closed when they go out of scope. /// Files are automatically closed when they go out of scope.
///
/// # Examples
///
/// Create a new file and write bytes to it:
///
/// ```no_run
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// # fn foo() -> std::io::Result<()> {
/// let fs = Fs::init()?;
/// let sdmc = fs.sdmc()?;
///
/// let mut file = File::create(&sdmc, "/foo.txt")?;
/// file.write_all(b"Hello, world!")?;
/// # Ok(())
/// #}
/// ```
///
/// Read the contents of a file into a `String`::
///
/// ```no_run
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// # fn foo() -> std::io::Result<()> {
/// let fs = Fs::init()?;
/// let sdmc = fs.sdmc()?;
///
/// let mut file = File::open(&sdmc, "/foo.txt")?;
/// let mut contents = String::new();
/// file.read_to_string(&mut contents)?;
/// assert_eq!(contents, "Hello, world!");
/// # Ok(())
/// #}
/// ```
///
/// It can be more efficient to read the contents of a file with a buffered
/// `Read`er. This can be accomplished with `BufReader<R>`:
///
/// ```no_run
/// use std::io::BufReader;
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// # fn foo() -> std::io::Result<()> {
/// let fs = Fs::init()?;
/// let sdmc = fs.sdmc()?;
///
/// let file = File::open(&sdmc, "/foo.txt")?;
/// let mut buf_reader = BufReader::new(file);
/// let mut contents = String::new();
/// buf_reader.read_to_string(&mut contents)?;
/// assert_eq!(contents, "Hello, world!");
/// # Ok(())
/// # }
/// ```
pub struct File { pub struct File {
handle: u32, handle: u32,
offset: u64, offset: u64,
@ -215,11 +300,11 @@ impl Fs {
/// ctrulib services are reference counted, so this function may be called /// ctrulib services are reference counted, so this function may be called
/// as many times as desired and the service will not exit until all /// as many times as desired and the service will not exit until all
/// instances of Fs drop out of scope. /// instances of Fs drop out of scope.
pub fn init() -> Result<Fs, i32> { pub fn init() -> ::Result<Fs> {
unsafe { unsafe {
let r = fsInit(); let r = fsInit();
if r < 0 { if r < 0 {
Err(r) Err(::Error::from(r))
} else { } else {
Ok(Fs { pd: PhantomData }) Ok(Fs { pd: PhantomData })
} }
@ -227,14 +312,14 @@ impl Fs {
} }
/// Returns a handle to the SDMC (memory card) Archive. /// Returns a handle to the SDMC (memory card) Archive.
pub fn sdmc(&self) -> Result<Archive, i32> { pub fn sdmc(&self) -> ::Result<Archive> {
unsafe { unsafe {
let mut handle = 0; let mut handle = 0;
let id = ArchiveID::Sdmc; let id = ArchiveID::Sdmc;
let path = fsMakePath(PathType::Empty.into(), ptr::null() as _); let path = fsMakePath(PathType::Empty.into(), ptr::null() as _);
let r = FSUSER_OpenArchive(&mut handle, id.into(), path); let r = FSUSER_OpenArchive(&mut handle, id.into(), path);
if r < 0 { if r < 0 {
Err(r) Err(::Error::from(r))
} else { } else {
Ok(Archive { Ok(Archive {
handle: handle, handle: handle,
@ -275,7 +360,7 @@ impl File {
/// let sdmc_archive = fs.sdmc().unwrap() /// let sdmc_archive = fs.sdmc().unwrap()
/// let mut f = File::open(&sdmc_archive, "/foo.txt").unwrap(); /// let mut f = File::open(&sdmc_archive, "/foo.txt").unwrap();
/// ``` /// ```
pub fn open<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<File, i32> { pub fn open<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<File> {
OpenOptions::new().read(true).archive(arch).open(path.as_ref()) OpenOptions::new().read(true).archive(arch).open(path.as_ref())
} }
@ -301,7 +386,7 @@ impl File {
/// let sdmc_archive = fs.sdmc().unwrap() /// let sdmc_archive = fs.sdmc().unwrap()
/// let mut f = File::create(&sdmc_archive, "/foo.txt").unwrap(); /// let mut f = File::create(&sdmc_archive, "/foo.txt").unwrap();
/// ``` /// ```
pub fn create<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<File, i32> { pub fn create<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<File> {
OpenOptions::new().write(true).create(true).archive(arch).open(path.as_ref()) OpenOptions::new().write(true).create(true).archive(arch).open(path.as_ref())
} }
@ -310,11 +395,15 @@ impl File {
/// If the size is less than the current file's size, then the file will be shrunk. If it is /// If the size is less than the current file's size, then the file will be shrunk. If it is
/// greater than the current file's size, then the file will be extended to size and have all /// greater than the current file's size, then the file will be extended to size and have all
/// of the intermediate data filled in with 0s. /// of the intermediate data filled in with 0s.
pub fn set_len(&mut self, size: u64) -> Result<(), i32> { ///
/// # Errors
///
/// This function will return an error if the file is not opened for writing.
pub fn set_len(&mut self, size: u64) -> IoResult<()> {
unsafe { unsafe {
let r = FSFILE_SetSize(self.handle, size); let r = FSFILE_SetSize(self.handle, size);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::PermissionDenied, ::Error::from(r)))
} else { } else {
Ok(()) Ok(())
} }
@ -322,26 +411,21 @@ impl File {
} }
/// Queries metadata about the underlying file. /// Queries metadata about the underlying file.
pub fn metadata(&self) -> Result<Metadata, i32> { pub fn metadata(&self) -> IoResult<Metadata> {
// The only metadata we have for files right now is file size. // The only metadata we have for files right now is file size.
// This is likely to change in the future. // This is likely to change in the future.
unsafe { unsafe {
let mut size = 0; let mut size = 0;
let r = FSFILE_GetSize(self.handle, &mut size); let r = FSFILE_GetSize(self.handle, &mut size);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::PermissionDenied, ::Error::from(r)))
} else { } else {
Ok(Metadata { attributes: 0, size: size }) Ok(Metadata { attributes: 0, size: size })
} }
} }
} }
/// Pull some bytes from the file into the specified buffer, returning fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
/// how many bytes were read.
///
/// This function will become private when std::io support is ported
/// to this library.
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, i32> {
unsafe { unsafe {
let mut n_read = 0; let mut n_read = 0;
let r = FSFILE_Read( let r = FSFILE_Read(
@ -353,28 +437,18 @@ impl File {
); );
self.offset += n_read as u64; self.offset += n_read as u64;
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(n_read as usize) Ok(n_read as usize)
} }
} }
} }
/// Read all bytes until EOF in this source, placing them into buf. fn read_to_end(&mut self, buf: &mut Vec<u8>) -> IoResult<usize> {
/// unsafe { read_to_end_uninitialized(self, buf) }
/// This function will become private when std::io support is ported
/// to this library.
pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, i32> {
unsafe {
read_to_end_uninitialized(self, buf)
}
} }
/// Write a buffer into this object, returning how many bytes were written. fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
///
/// This function will become private when std::io support is ported
/// to this library.
pub fn write(&mut self, buf: &[u8]) -> Result<usize, i32> {
unsafe { unsafe {
let mut n_written = 0; let mut n_written = 0;
let r = FSFILE_Write( let r = FSFILE_Write(
@ -383,11 +457,11 @@ impl File {
self.offset, self.offset,
buf.as_ptr() as _, buf.as_ptr() as _,
buf.len() as u32, buf.len() as u32,
FS_WRITE_UPDATE_TIME FS_WRITE_UPDATE_TIME.bits()
); );
self.offset += n_written as u64; self.offset += n_written as u64;
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(n_written as usize) Ok(n_written as usize)
} }
@ -398,7 +472,7 @@ impl File {
impl Metadata { impl Metadata {
/// Returns whether this metadata is for a directory. /// Returns whether this metadata is for a directory.
pub fn is_dir(&self) -> bool { pub fn is_dir(&self) -> bool {
self.attributes == self.attributes | FS_ATTRIBUTE_DIRECTORY self.attributes == self.attributes | FS_ATTRIBUTE_DIRECTORY.bits
} }
/// Returns whether this metadata is for a regular file. /// Returns whether this metadata is for a regular file.
@ -507,38 +581,38 @@ impl OpenOptions {
/// * Invalid combinations of open options. /// * Invalid combinations of open options.
/// ///
/// [`Archive`]: struct.Archive.html /// [`Archive`]: struct.Archive.html
pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<File, i32> { pub fn open<P: AsRef<Path>>(&self, path: P) -> IoResult<File> {
self._open(path.as_ref(), self.get_open_flags()) self._open(path.as_ref(), self.get_open_flags())
} }
fn _open(&self, path: &Path, flags: u32) -> Result<File, i32> { fn _open(&self, path: &Path, flags: FsOpen) -> IoResult<File> {
unsafe { unsafe {
let mut file_handle = 0; let mut file_handle = 0;
let path = to_utf16(path); let path = to_utf16(path);
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_OpenFile(&mut file_handle, self.arch_handle, fs_path, flags, 0); let r = FSUSER_OpenFile(&mut file_handle, self.arch_handle, fs_path, flags.bits, 0);
if r < 0 { if r < 0 {
return Err(r); return Err(IoError::new(IoErrorKind::Other, ::Error::from(r)));
} }
let mut file = File { handle: file_handle, offset: 0 }; let mut file = File { handle: file_handle, offset: 0 };
if self.append { if self.append {
let metadata = try!(file.metadata()); let metadata = file.metadata()?;
file.offset = metadata.len(); file.offset = metadata.len();
} }
// set the offset to 0 just in case both append and truncate were // set the offset to 0 just in case both append and truncate were
// set to true // set to true
if self.truncate { if self.truncate {
try!(file.set_len(0)); file.set_len(0)?;
file.offset = 0; file.offset = 0;
} }
Ok(file) Ok(file)
} }
} }
fn get_open_flags(&self) -> u32 { fn get_open_flags(&self) -> FsOpen {
match (self.read, self.write || self.append, self.create) { match (self.read, self.write || self.append, self.create) {
(true, false, false) => FS_OPEN_READ, (true, false, false) => FS_OPEN_READ,
(false, true, false) => FS_OPEN_WRITE, (false, true, false) => FS_OPEN_WRITE,
@ -546,15 +620,15 @@ impl OpenOptions {
(true, false, true) => FS_OPEN_READ | FS_OPEN_CREATE, (true, false, true) => FS_OPEN_READ | FS_OPEN_CREATE,
(true, true, false) => FS_OPEN_READ | FS_OPEN_WRITE, (true, true, false) => FS_OPEN_READ | FS_OPEN_WRITE,
(true, true, true) => FS_OPEN_READ | FS_OPEN_WRITE | FS_OPEN_CREATE, (true, true, true) => FS_OPEN_READ | FS_OPEN_WRITE | FS_OPEN_CREATE,
_ => 0, //failure case _ => FsOpen::empty(), //failure case
} }
} }
} }
impl<'a> Iterator for ReadDir<'a> { impl<'a> Iterator for ReadDir<'a> {
type Item = Result<DirEntry<'a>, i32>; type Item = IoResult<DirEntry<'a>>;
fn next(&mut self) -> Option<Result<DirEntry<'a>, i32>> { fn next(&mut self) -> Option<IoResult<DirEntry<'a>>> {
unsafe { unsafe {
let mut ret = DirEntry { let mut ret = DirEntry {
entry: mem::zeroed(), entry: mem::zeroed(),
@ -566,7 +640,7 @@ impl<'a> Iterator for ReadDir<'a> {
let r = FSDIR_Read(self.handle.0, &mut entries_read, entry_count, &mut ret.entry); let r = FSDIR_Read(self.handle.0, &mut entries_read, entry_count, &mut ret.entry);
if r < 0 { if r < 0 {
return Some(Err(r)) return Some(Err(IoError::new(IoErrorKind::Other, ::Error::from(r))))
} }
if entries_read != entry_count { if entries_read != entry_count {
return None return None
@ -586,15 +660,18 @@ impl<'a> DirEntry<'a> {
} }
/// Return the metadata for the file that this entry points at. /// Return the metadata for the file that this entry points at.
pub fn metadata(&self) -> Result<Metadata, i32> { pub fn metadata(&self) -> IoResult<Metadata> {
metadata(self.arch, self.path()) metadata(self.arch, self.path())
} }
/// Returns the bare file name of this directory entry without any other leading path /// Returns the bare file name of this directory entry without any other leading path
/// component. /// component.
pub fn file_name(&self) -> OsString { pub fn file_name(&self) -> OsString {
let filename = truncate_utf16_at_nul(&self.entry.name); unsafe {
OsString::from_wide(filename) let filename = truncate_utf16_at_nul(&self.entry.name);
let filename = WideCStr::from_ptr_str(filename.as_ptr());
filename.to_os_string()
}
} }
} }
@ -606,13 +683,13 @@ impl<'a> DirEntry<'a> {
/// but is not limited to just these cases: /// but is not limited to just these cases:
/// ///
/// * User lacks permissions to create directory at `path` /// * User lacks permissions to create directory at `path`
pub fn create_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { pub fn create_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<()> {
unsafe { unsafe {
let path = to_utf16(path.as_ref()); let path = to_utf16(path.as_ref());
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_CreateDirectory(arch.handle, fs_path, FS_ATTRIBUTE_DIRECTORY); let r = FSUSER_CreateDirectory(arch.handle, fs_path, FS_ATTRIBUTE_DIRECTORY.bits);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(()) Ok(())
} }
@ -628,7 +705,7 @@ pub fn create_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> {
/// ///
/// * If any directory in the path specified by `path` does not already exist /// * If any directory in the path specified by `path` does not already exist
/// and it could not be created otherwise. /// and it could not be created otherwise.
pub fn create_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { pub fn create_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<()> {
let path = path.as_ref(); let path = path.as_ref();
let mut dir = PathBuf::new(); let mut dir = PathBuf::new();
let mut result = Ok(()); let mut result = Ok(());
@ -642,13 +719,13 @@ pub fn create_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32
} }
/// Given a path, query the file system to get information about a file, directory, etc /// Given a path, query the file system to get information about a file, directory, etc
pub fn metadata<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<Metadata, i32> { pub fn metadata<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<Metadata> {
let maybe_file = File::open(&arch, path.as_ref()); let maybe_file = File::open(&arch, path.as_ref());
let maybe_dir = read_dir(&arch, path.as_ref()); let maybe_dir = read_dir(&arch, path.as_ref());
match (maybe_file, maybe_dir) { match (maybe_file, maybe_dir) {
(Ok(file), _) => file.metadata(), (Ok(file), _) => file.metadata(),
(_, Ok(_dir)) => Ok(Metadata { attributes: FS_ATTRIBUTE_DIRECTORY, size: 0 }), (_, Ok(_dir)) => Ok(Metadata { attributes: FS_ATTRIBUTE_DIRECTORY.bits, size: 0 }),
(Err(r), _) => Err(r), (Err(e), _) => Err(e),
} }
} }
@ -661,13 +738,13 @@ pub fn metadata<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<Metadata, i32
/// ///
/// * The user lacks permissions to remove the directory at the provided path. /// * The user lacks permissions to remove the directory at the provided path.
/// * The directory isn't empty. /// * The directory isn't empty.
pub fn remove_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { pub fn remove_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<()> {
unsafe { unsafe {
let path = to_utf16(path.as_ref()); let path = to_utf16(path.as_ref());
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_DeleteDirectory(arch.handle, fs_path); let r = FSUSER_DeleteDirectory(arch.handle, fs_path);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(()) Ok(())
} }
@ -679,13 +756,13 @@ pub fn remove_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> {
/// # Errors /// # Errors
/// ///
/// see `file::remove_file` and `fs::remove_dir` /// see `file::remove_file` and `fs::remove_dir`
pub fn remove_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { pub fn remove_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<()> {
unsafe { unsafe {
let path = to_utf16(path.as_ref()); let path = to_utf16(path.as_ref());
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_DeleteDirectoryRecursively(arch.handle, fs_path); let r = FSUSER_DeleteDirectoryRecursively(arch.handle, fs_path);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(()) Ok(())
} }
@ -703,7 +780,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32
/// * The provided path doesn't exist. /// * The provided path doesn't exist.
/// * The process lacks permissions to view the contents. /// * The process lacks permissions to view the contents.
/// * The path points at a non-directory file. /// * The path points at a non-directory file.
pub fn read_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<ReadDir, i32> { pub fn read_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<ReadDir> {
unsafe { unsafe {
let mut handle = 0; let mut handle = 0;
let root = Arc::new(path.as_ref().to_path_buf()); let root = Arc::new(path.as_ref().to_path_buf());
@ -711,7 +788,7 @@ pub fn read_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<ReadDir, i32>
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_OpenDirectory(&mut handle, arch.handle, fs_path); let r = FSUSER_OpenDirectory(&mut handle, arch.handle, fs_path);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(ReadDir { handle: Dir(handle), root: root, arch: arch}) Ok(ReadDir { handle: Dir(handle), root: root, arch: arch})
} }
@ -727,13 +804,13 @@ pub fn read_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<ReadDir, i32>
/// ///
/// * path points to a directory. /// * path points to a directory.
/// * The user lacks permissions to remove the file. /// * The user lacks permissions to remove the file.
pub fn remove_file<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { pub fn remove_file<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<()> {
unsafe { unsafe {
let path = to_utf16(path.as_ref()); let path = to_utf16(path.as_ref());
let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _); let fs_path = fsMakePath(PathType::UTF16.into(), path.as_ptr() as _);
let r = FSUSER_DeleteFile(arch.handle, fs_path); let r = FSUSER_DeleteFile(arch.handle, fs_path);
if r < 0 { if r < 0 {
Err(r) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} else { } else {
Ok(()) Ok(())
} }
@ -750,7 +827,7 @@ pub fn remove_file<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> {
/// ///
/// * from does not exist. /// * from does not exist.
/// * The user lacks permissions to view contents. /// * The user lacks permissions to view contents.
pub fn rename<P, Q>(arch: &Archive, from: P, to: Q) -> Result<(), i32> pub fn rename<P, Q>(arch: &Archive, from: P, to: Q) -> IoResult<()>
where P: AsRef<Path>, where P: AsRef<Path>,
Q: AsRef<Path> { Q: AsRef<Path> {
@ -769,13 +846,13 @@ pub fn rename<P, Q>(arch: &Archive, from: P, to: Q) -> Result<(), i32>
if r == 0 { if r == 0 {
return Ok(()) return Ok(())
} }
Err((r)) Err(IoError::new(IoErrorKind::Other, ::Error::from(r)))
} }
} }
// TODO: Determine if we should check UTF-16 paths for interior NULs // TODO: Determine if we should check UTF-16 paths for interior NULs
fn to_utf16(path: &Path) -> Vec<u16> { fn to_utf16(path: &Path) -> WideCString {
path.as_os_str().encode_wide().collect::<Vec<_>>() WideCString::from_str(path).unwrap()
} }
// Adapted from sys/windows/fs.rs in libstd // Adapted from sys/windows/fs.rs in libstd
@ -787,8 +864,19 @@ fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
} }
} }
// Adapted from sys/common/io.rs in libstd // Copied from sys/common/io.rs in libstd
unsafe fn read_to_end_uninitialized(f: &mut File, buf: &mut Vec<u8>) -> Result<usize, i32> {
// Provides read_to_end functionality over an uninitialized buffer.
// This function is unsafe because it calls the underlying
// read function with a slice into uninitialized memory. The default
// implementation of read_to_end for readers will zero out new memory in
// the buf before passing it to read, but avoiding this zero can often
// lead to a fairly significant performance win.
//
// Implementations using this method have to adhere to two guarantees:
// * The implementation of read never reads the buffer provided.
// * The implementation of read correctly reports how many bytes were written.
unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> IoResult<usize> {
let start_len = buf.len(); let start_len = buf.len();
buf.reserve(16); buf.reserve(16);
@ -806,14 +894,56 @@ unsafe fn read_to_end_uninitialized(f: &mut File, buf: &mut Vec<u8>) -> Result<u
let buf_slice = slice::from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize), let buf_slice = slice::from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize),
buf.capacity() - buf.len()); buf.capacity() - buf.len());
match f.read(buf_slice) { match r.read(buf_slice) {
Ok(0) => { return Ok(buf.len() - start_len); } Ok(0) => { return Ok(buf.len() - start_len); }
Ok(n) => { let len = buf.len() + n; buf.set_len(len); }, Ok(n) => { let len = buf.len() + n; buf.set_len(len); },
Err(ref e) if e.kind() == IoErrorKind::Interrupted => { }
Err(e) => { return Err(e); } Err(e) => { return Err(e); }
} }
} }
} }
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
self.read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> IoResult<usize> {
self.read_to_end(buf)
}
}
impl Write for File {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
self.write(buf)
}
fn flush(&mut self) -> IoResult<()> {
Ok(())
}
}
impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> {
match pos {
SeekFrom::Start(off) => {
self.offset = off;
},
SeekFrom::End(off) => {
let mut temp = self.metadata()?.len() as i64;
temp += off;
self.offset = temp as u64;
},
SeekFrom::Current(off) => {
let mut temp = self.offset as i64;
temp += off;
self.offset = temp as u64;
},
}
Ok(self.offset)
}
}
impl Drop for Fs { impl Drop for Fs {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
@ -874,7 +1004,7 @@ impl From<ArchiveID> for FS_ArchiveID {
SdmcWriteOnly => ARCHIVE_SDMC_WRITE_ONLY, SdmcWriteOnly => ARCHIVE_SDMC_WRITE_ONLY,
BossExtdata => ARCHIVE_BOSS_EXTDATA, BossExtdata => ARCHIVE_BOSS_EXTDATA,
CardSpiFS => ARCHIVE_CARD_SPIFS, CardSpiFS => ARCHIVE_CARD_SPIFS,
ExtDataAndBossExtdata => ARCHIVE_EXTDATA_AND_BOSS_EXTDATA, ExtDataAndBossExtdata => ARCHIVE_EXTDATA_AND_BOSS_EXTDATA,
SystemSaveData2 => ARCHIVE_SYSTEM_SAVEDATA2, SystemSaveData2 => ARCHIVE_SYSTEM_SAVEDATA2,
NandRW => ARCHIVE_NAND_RW, NandRW => ARCHIVE_NAND_RW,
NandRO => ARCHIVE_NAND_RO, NandRO => ARCHIVE_NAND_RO,

2
src/services/gspgpu.rs → ctru-rs/src/services/gspgpu.rs

@ -1,6 +1,6 @@
use libctru::services::gspgpu; use libctru::services::gspgpu;
use core::convert::From; use std::convert::From;
pub enum Event { pub enum Event {
Psc0, Psc0,

8
src/services/hid.rs → ctru-rs/src/services/hid.rs

@ -1,5 +1,5 @@
use core::convert::Into; use std::convert::Into;
use core::marker::PhantomData; use std::marker::PhantomData;
use libctru::services::hid; use libctru::services::hid;
@ -78,11 +78,11 @@ pub struct Hid {
} }
impl Hid { impl Hid {
pub fn init() -> Result<Hid, i32> { pub fn init() -> ::Result<Hid> {
unsafe { unsafe {
let r = hid::hidInit(); let r = hid::hidInit();
if r < 0 { if r < 0 {
Err(r) Err(::Error::from(r))
} else { } else {
Ok(Hid { pd: PhantomData }) Ok(Hid { pd: PhantomData })
} }

0
src/services/mod.rs → ctru-rs/src/services/mod.rs

6
src/srv.rs → ctru-rs/src/srv.rs

@ -1,17 +1,17 @@
use libctru::srv::*; use libctru::srv::*;
use core::marker::PhantomData; use std::marker::PhantomData;
pub struct Srv { pub struct Srv {
pd: PhantomData<i32>, pd: PhantomData<i32>,
} }
impl Srv { impl Srv {
pub fn init() -> Result<Srv, i32> { pub fn init() -> ::Result<Srv> {
unsafe { unsafe {
let r = srvInit(); let r = srvInit();
if r < 0 { if r < 0 {
Err(r) Err(::Error::from(r))
} else { } else {
Ok(Srv { pd: PhantomData }) Ok(Srv { pd: PhantomData })
} }

5
ctru-sys/Cargo.toml

@ -1,5 +1,8 @@
[package] [package]
name = "ctru-sys" name = "ctru-sys"
version = "0.2.0" version = "0.3.0"
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
[dependencies]
ctr-libc = { path = "../ctr-libc" }

1
ctru-sys/src/applets/mod.rs

@ -0,0 +1 @@
pub mod swkbd;

258
ctru-sys/src/applets/swkbd.rs

@ -0,0 +1,258 @@
// automatically generated by rust-bindgen
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum SwkbdType {
SWKBD_TYPE_NORMAL = 0,
SWKBD_TYPE_QWERTY = 1,
SWKBD_TYPE_NUMPAD = 2,
SWKBD_TYPE_WESTERN = 3,
}
pub const SWKBD_NOTBLANK_NOTEMPTY: SwkbdValidInput = SwkbdValidInput::SWKBD_NOTEMPTY_NOTBLANK;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum SwkbdValidInput {
SWKBD_ANYTHING = 0,
SWKBD_NOTEMPTY = 1,
SWKBD_NOTEMPTY_NOTBLANK = 2,
SWKBD_NOTBLANK = 3,
SWKBD_FIXEDLEN = 4,
}
pub const SWKBD_BUTTON_CONFIRM: SwkbdButton = SwkbdButton::SWKBD_BUTTON_RIGHT;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum SwkbdButton {
SWKBD_BUTTON_LEFT = 0,
SWKBD_BUTTON_MIDDLE = 1,
SWKBD_BUTTON_RIGHT = 2,
SWKBD_BUTTON_NONE = 3,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum SwkbdPasswordMode {
SWKBD_PASSWORD_NONE = 0,
SWKBD_PASSWORD_HIDE = 1,
SWKBD_PASSWORD_HIDE_DELAY = 2,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 {
SWKBD_FILTER_DIGITS = 1,
SWKBD_FILTER_AT = 2,
SWKBD_FILTER_PERCENT = 4,
SWKBD_FILTER_BACKSLASH = 8,
SWKBD_FILTER_PROFANITY = 16,
SWKBD_FILTER_CALLBACK = 32,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed2 {
SWKBD_PARENTAL = 1,
SWKBD_DARKEN_TOP_SCREEN = 2,
SWKBD_PREDICTIVE_INPUT = 4,
SWKBD_MULTILINE = 8,
SWKBD_FIXED_WIDTH = 16,
SWKBD_ALLOW_HOME = 32,
SWKBD_ALLOW_RESET = 64,
SWKBD_ALLOW_POWER = 128,
SWKBD_DEFAULT_QWERTY = 512,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum SwkbdCallbackResult {
SWKBD_CALLBACK_OK = 0,
SWKBD_CALLBACK_CLOSE = 1,
SWKBD_CALLBACK_CONTINUE = 2,
}
#[derive(Copy, Clone)]
#[repr(i32)]
#[derive(Debug)]
pub enum SwkbdResult {
SWKBD_NONE = -1,
SWKBD_INVALID_INPUT = -2,
SWKBD_OUTOFMEM = -3,
SWKBD_D0_CLICK = 0,
SWKBD_D1_CLICK0 = 1,
SWKBD_D1_CLICK1 = 2,
SWKBD_D2_CLICK0 = 3,
SWKBD_D2_CLICK1 = 4,
SWKBD_D2_CLICK2 = 5,
SWKBD_HOMEPRESSED = 10,
SWKBD_RESETPRESSED = 11,
SWKBD_POWERPRESSED = 12,
SWKBD_PARENTAL_OK = 20,
SWKBD_PARENTAL_FAIL = 21,
SWKBD_BANNED_INPUT = 30,
}
#[repr(C)]
#[derive(Copy)]
pub struct SwkbdDictWord {
pub reading: [u16; 41usize],
pub word: [u16; 41usize],
pub language: u8,
pub all_languages: u8,
}
impl ::core::clone::Clone for SwkbdDictWord {
fn clone(&self) -> Self {
*self
}
}
impl ::core::default::Default for SwkbdDictWord {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
pub type SwkbdCallbackFn =
::core::option::Option<unsafe extern "C" fn(user: *mut ::libc::c_void,
ppMessage: *mut *const u8,
text: *const u8,
textlen: usize)
-> SwkbdCallbackResult>;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct SwkbdStatusData {
pub data: [u32; 17usize],
}
impl ::core::default::Default for SwkbdStatusData {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy)]
pub struct SwkbdLearningData {
pub data: [u32; 10523usize],
}
impl ::core::clone::Clone for SwkbdLearningData {
fn clone(&self) -> Self {
*self
}
}
impl ::core::default::Default for SwkbdLearningData {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct SwkbdExtra {
pub initial_text: *const u8,
pub dict: *const SwkbdDictWord,
pub status_data: *mut SwkbdStatusData,
pub learning_data: *mut SwkbdLearningData,
pub callback: SwkbdCallbackFn,
pub callback_user: *mut ::libc::c_void,
}
impl ::core::default::Default for SwkbdExtra {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy)]
pub struct SwkbdState {
pub type_: i32,
pub num_buttons_m1: i32,
pub valid_input: i32,
pub password_mode: i32,
pub is_parental_screen: i32,
pub darken_top_screen: i32,
pub filter_flags: u32,
pub save_state_flags: u32,
pub max_text_len: u16,
pub dict_word_count: u16,
pub max_digits: u16,
pub button_text: [[u16; 17usize]; 3usize],
pub numpad_keys: [u16; 2usize],
pub hint_text: [u16; 65usize],
pub predictive_input: u8,
pub multiline: u8,
pub fixed_width: u8,
pub allow_home: u8,
pub allow_reset: u8,
pub allow_power: u8,
pub unknown: u8,
pub default_qwerty: u8,
pub button_submits_text: [u8; 4usize],
pub language: u16,
pub initial_text_offset: i32,
pub dict_offset: i32,
pub initial_status_offset: i32,
pub initial_learning_offset: i32,
pub shared_memory_size: usize,
pub version: u32,
pub result: SwkbdResult,
pub status_offset: i32,
pub learning_offset: i32,
pub text_offset: i32,
pub text_length: u16,
pub callback_result: i32,
pub callback_msg: [u16; 257usize],
pub skip_at_check: u8,
pub union: _bindgen_data_1_,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union _bindgen_data_1_ {
pub reserved: [u8; 171usize],
pub extra: SwkbdExtra,
}
impl ::core::clone::Clone for SwkbdState {
fn clone(&self) -> Self {
*self
}
}
impl ::core::default::Default for SwkbdState {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
extern "C" {
pub fn swkbdInit(swkbd: *mut SwkbdState,
type_: SwkbdType,
numButtons: i32,
maxTextLength: i32);
pub fn swkbdSetFeatures(swkbd: *mut SwkbdState, features: u32);
pub fn swkbdSetHintText(swkbd: *mut SwkbdState, text: *const u8);
pub fn swkbdSetButton(swkbd: *mut SwkbdState,
button: SwkbdButton,
text: *const u8,
submit: u8);
pub fn swkbdSetInitialText(swkbd: *mut SwkbdState, text: *const u8);
pub fn swkbdSetDictWord(word: *mut SwkbdDictWord,
reading: *const u8,
text: *const u8);
pub fn swkbdSetDictionary(swkbd: *mut SwkbdState,
dict: *const SwkbdDictWord,
wordCount: i32);
pub fn swkbdSetStatusData(swkbd: *mut SwkbdState,
data: *mut SwkbdStatusData,
in_: u8,
out: u8);
pub fn swkbdSetLearningData(swkbd: *mut SwkbdState,
data: *mut SwkbdLearningData,
in_: u8,
out: u8);
pub fn swkbdSetFilterCallback(swkbd: *mut SwkbdState,
callback: SwkbdCallbackFn,
user: *mut ::libc::c_void);
pub fn swkbdInputText(swkbd: *mut SwkbdState,
buf: *mut u8,
bufsize: usize)
-> SwkbdButton;
}

37
ctru-sys/src/gpu/gpu.rs

@ -1,26 +1,27 @@
/* automatically generated by rust-bindgen */ /* automatically generated by rust-bindgen */
#[inline] #![allow(dead_code,
pub fn GPUCMD_HEADER(incremental: u32, mask: u32, reg: u32) -> u32{ non_camel_case_types,
(((incremental)<<31)|(((mask)&0xF)<<16)|((reg)&0x3FF)) non_upper_case_globals,
non_snake_case)]
extern "C" {
pub static mut gpuCmdBuf: *mut u32_;
pub static mut gpuCmdBufSize: u32_;
pub static mut gpuCmdBufOffset: u32_;
} }
extern "C" { extern "C" {
pub static mut gpuCmdBuf: *mut u32; pub fn GPUCMD_SetBuffer(adr: *mut u32_, size: u32_, offset: u32_);
pub static mut gpuCmdBufSize: u32; pub fn GPUCMD_SetBufferOffset(offset: u32_);
pub static mut gpuCmdBufOffset: u32; pub fn GPUCMD_GetBuffer(adr: *mut *mut u32_, size: *mut u32_,
offset: *mut u32_);
pub fn GPUCMD_SetBuffer(adr: *mut u32, size: u32, offset: u32); pub fn GPUCMD_AddRawCommands(cmd: *const u32_, size: u32_);
pub fn GPUCMD_SetBufferOffset(offset: u32);
pub fn GPUCMD_GetBuffer(adr: *mut *mut u32, size: *mut u32,
offset: *mut u32);
pub fn GPUCMD_AddRawCommands(cmd: *mut u32, size: u32);
pub fn GPUCMD_Run(); pub fn GPUCMD_Run();
pub fn GPUCMD_FlushAndRun(); pub fn GPUCMD_FlushAndRun();
pub fn GPUCMD_Add(header: u32, param: *mut u32, paramlength: u32); pub fn GPUCMD_Add(header: u32_, param: *const u32_, paramlength: u32_);
pub fn GPUCMD_Finalize(); pub fn GPUCMD_Finalize();
pub fn f32tof16(f: f32) -> u32; pub fn f32tof16(f: f32) -> u32_;
pub fn f32tof20(f: f32) -> u32; pub fn f32tof20(f: f32) -> u32_;
pub fn f32tof24(f: f32) -> u32; pub fn f32tof24(f: f32) -> u32_;
pub fn f32tof31(f: f32) -> u32; pub fn f32tof31(f: f32) -> u32_;
} }
use ::types::*;

133
ctru-sys/src/gpu/gx.rs

@ -1,94 +1,55 @@
use ::Result; /* automatically generated by rust-bindgen */
#[inline] #![allow(dead_code,
pub fn GX_BUFFER_DIM(w: u32, h: u32) { non_camel_case_types,
(((h)<<16)|((w)&0xFFFF)); non_upper_case_globals,
} non_snake_case)]
#[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
pub enum GX_TRANSFER_FORMAT #[derive(Debug)]
{ pub enum GX_TRANSFER_FORMAT {
GX_TRANSFER_FMT_RGBA8 = 0, GX_TRANSFER_FMT_RGBA8 = 0,
GX_TRANSFER_FMT_RGB8 = 1, GX_TRANSFER_FMT_RGB8 = 1,
GX_TRANSFER_FMT_RGB565 = 2, GX_TRANSFER_FMT_RGB565 = 2,
GX_TRANSFER_FMT_RGB5A1 = 3, GX_TRANSFER_FMT_RGB5A1 = 3,
GX_TRANSFER_FMT_RGBA4 = 4, GX_TRANSFER_FMT_RGBA4 = 4,
} }
#[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
pub enum GX_TRANSFER_SCALE #[derive(Debug)]
{ pub enum GX_TRANSFER_SCALE {
GX_TRANSFER_SCALE_NO = 0, GX_TRANSFER_SCALE_NO = 0,
GX_TRANSFER_SCALE_X = 1, GX_TRANSFER_SCALE_X = 1,
GX_TRANSFER_SCALE_Y = 2, GX_TRANSFER_SCALE_XY = 2,
} }
#[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
#[derive(Debug)]
pub enum GX_FILL_CONTROL { pub enum GX_FILL_CONTROL {
GX_FILL_TRIGGER = 0x001, GX_FILL_TRIGGER = 1,
GX_FILL_FINISHED = 0x002, GX_FILL_FINISHED = 2,
GX_FILL_16BIT_DEPTH = 0x000, GX_FILL_16BIT_DEPTH = 0,
GX_FILL_24BIT_DEPTH = 0x100, GX_FILL_24BIT_DEPTH = 256,
GX_FILL_32BIT_DEPTH = 0x200, GX_FILL_32BIT_DEPTH = 512,
}
#[inline]
pub fn GX_TRANSFER_FLIP_VERT(x: i32) {
((x)<<0);
}
#[inline]
pub fn GX_TRANSFER_OUT_TILED(x: i32) {
((x)<<1);
}
#[inline]
pub fn GX_TRANSFER_RAW_COPY(x: i32) {
((x)<<3);
} }
extern "C" {
#[inline] pub static mut gxCmdBuf: *mut u32_;
pub fn GX_TRANSFER_IN_FORMAT(x: i32) {
((x)<<8);
}
#[inline]
pub fn GX_TRANSFER_OUT_FORMAT(x: i32) {
((x)<<12);
}
#[inline]
pub fn GX_TRANSFER_SCALING(x: i32) {
((x)<<24);
}
#[inline]
pub fn GX_CMDLIST_BIT0() {
(1u32<<(0));
}
#[inline]
pub fn GX_CMNDLIST_FLUSH() {
(1u32<<(1));
} }
extern "C" { extern "C" {
pub static mut gxCmdBuf: *mut u32; pub fn GX_RequestDma(src: *mut u32_, dst: *mut u32_, length: u32_)
pub fn GX_RequestDma(src: *mut u32, dst: *mut u32, length: u32)
-> Result; -> Result;
pub fn GX_ProcessCommandList(buf0a: *mut u32, buf0s: u32, flags: u8) pub fn GX_ProcessCommandList(buf0a: *mut u32_, buf0s: u32_, flags: u8_)
-> Result; -> Result;
pub fn GX_MemoryFill(buf0a: *mut u32, buf0v: u32, buf0e: *mut u32, pub fn GX_MemoryFill(buf0a: *mut u32_, buf0v: u32_, buf0e: *mut u32_,
control0: u16, buf1a: *mut u32, buf1v: u32, control0: u16_, buf1a: *mut u32_, buf1v: u32_,
buf1e: *mut u32, control1: u16) -> Result; buf1e: *mut u32_, control1: u16_) -> Result;
pub fn GX_DisplayTransfer(inadr: *mut u32, indim: u32, pub fn GX_DisplayTransfer(inadr: *mut u32_, indim: u32_,
outadr: *mut u32, outdim: u32, flags: u32) outadr: *mut u32_, outdim: u32_, flags: u32_)
-> Result; -> Result;
pub fn GX_TextureCopy(inadr: *mut u32, indim: u32, outadr: *mut u32, pub fn GX_TextureCopy(inadr: *mut u32_, indim: u32_, outadr: *mut u32_,
outdim: u32, size: u32, flags: u32) -> Result; outdim: u32_, size: u32_, flags: u32_) -> Result;
pub fn GX_FlushCacheRegions(buf0a: *mut u32, buf0s: u32, pub fn GX_FlushCacheRegions(buf0a: *mut u32_, buf0s: u32_,
buf1a: *mut u32, buf1s: u32, buf1a: *mut u32_, buf1s: u32_,
buf2a: *mut u32, buf2s: u32) -> Result; buf2a: *mut u32_, buf2s: u32_) -> Result;
} }
use ::types::*;

91
ctru-sys/src/gpu/shaderProgram.rs

@ -1,89 +1,68 @@
use ::Result; /* automatically generated by rust-bindgen */
use ::types::*;
use gpu::shbin::*;
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed1 { #[derive(Debug)]
pub id: u32, pub struct float24Uniform_s {
pub data: [u32; 3usize], pub id: u32_,
} pub data: [u32_; 3usize],
impl ::core::clone::Clone for Struct_Unnamed1 {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for Struct_Unnamed1 { impl ::core::default::Default for float24Uniform_s {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type float24Uniform_s = Struct_Unnamed1;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed2 { #[derive(Debug)]
pub struct shaderInstance_s {
pub dvle: *mut DVLE_s, pub dvle: *mut DVLE_s,
pub boolUniforms: u16, pub boolUniforms: u16_,
pub boolUniformMask: u16, pub boolUniformMask: u16_,
pub intUniforms: [u32; 4usize], pub intUniforms: [u32_; 4usize],
pub float24Uniforms: *mut float24Uniform_s, pub float24Uniforms: *mut float24Uniform_s,
pub intUniformMask: u8, pub intUniformMask: u8_,
pub numFloat24Uniforms: u8, pub numFloat24Uniforms: u8_,
} }
impl ::core::clone::Clone for Struct_Unnamed2 { impl ::core::default::Default for shaderInstance_s {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed2 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type shaderInstance_s = Struct_Unnamed2;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed3 { #[derive(Debug)]
pub struct shaderProgram_s {
pub vertexShader: *mut shaderInstance_s, pub vertexShader: *mut shaderInstance_s,
pub geometryShader: *mut shaderInstance_s, pub geometryShader: *mut shaderInstance_s,
pub geoShaderInputPermutation: [u32; 2usize], pub geoShaderInputPermutation: [u32_; 2usize],
pub geoShaderInputStride: u8, pub geoShaderInputStride: u8_,
pub geoShaderMode: u8,
}
impl ::core::clone::Clone for Struct_Unnamed3 {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for Struct_Unnamed3 { impl ::core::default::Default for shaderProgram_s {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type shaderProgram_s = Struct_Unnamed3;
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum Enum_Unnamed4 {
GSH_NORMAL = 0,
GSH_PARTICLE = 1,
GSH_SUBDIVISION_LOOP = 2,
GSH_SUBDIVISION_CATMULL_CLARK = 3,
}
pub type geoShaderMode = Enum_Unnamed4;
extern "C" { extern "C" {
pub fn shaderInstanceInit(si: *mut shaderInstance_s, dvle: *mut DVLE_s) pub fn shaderInstanceInit(si: *mut shaderInstance_s, dvle: *mut DVLE_s)
-> Result; -> Result;
pub fn shaderInstanceFree(si: *mut shaderInstance_s) -> Result; pub fn shaderInstanceFree(si: *mut shaderInstance_s) -> Result;
pub fn shaderInstanceSetBool(si: *mut shaderInstance_s, pub fn shaderInstanceSetBool(si: *mut shaderInstance_s, id: ::libc::c_int,
id: i32, value: u8) value: u8) -> Result;
-> Result; pub fn shaderInstanceGetBool(si: *mut shaderInstance_s, id: ::libc::c_int,
pub fn shaderInstanceGetBool(si: *mut shaderInstance_s, value: *mut u8) -> Result;
id: i32, value: *mut u8)
-> Result;
pub fn shaderInstanceGetUniformLocation(si: *mut shaderInstance_s, pub fn shaderInstanceGetUniformLocation(si: *mut shaderInstance_s,
name: name: *const ::libc::c_char)
*const u8)
-> s8; -> s8;
pub fn shaderProgramInit(sp: *mut shaderProgram_s) -> Result; pub fn shaderProgramInit(sp: *mut shaderProgram_s) -> Result;
pub fn shaderProgramFree(sp: *mut shaderProgram_s) -> Result; pub fn shaderProgramFree(sp: *mut shaderProgram_s) -> Result;
pub fn shaderProgramSetVsh(sp: *mut shaderProgram_s, dvle: *mut DVLE_s) pub fn shaderProgramSetVsh(sp: *mut shaderProgram_s, dvle: *mut DVLE_s)
-> Result; -> Result;
pub fn shaderProgramSetGsh(sp: *mut shaderProgram_s, dvle: *mut DVLE_s, pub fn shaderProgramSetGsh(sp: *mut shaderProgram_s, dvle: *mut DVLE_s,
stride: u8) -> Result; stride: u8_) -> Result;
pub fn shaderProgramSetGshInputPermutation(sp: *mut shaderProgram_s, pub fn shaderProgramSetGshInputPermutation(sp: *mut shaderProgram_s,
permutation: u64) -> Result; permutation: u64_) -> Result;
pub fn shaderProgramSetGshMode(sp: *mut shaderProgram_s,
mode: geoShaderMode) -> Result;
pub fn shaderProgramConfigure(sp: *mut shaderProgram_s, sendVshCode: u8, pub fn shaderProgramConfigure(sp: *mut shaderProgram_s, sendVshCode: u8,
sendGshCode: u8) -> Result; sendGshCode: u8) -> Result;
pub fn shaderProgramUse(sp: *mut shaderProgram_s) -> Result; pub fn shaderProgramUse(sp: *mut shaderProgram_s) -> Result;
} }
use ::types::*;
use super::shbin::*;

172
ctru-sys/src/gpu/shbin.rs

@ -1,23 +1,25 @@
use ::types::*; /* automatically generated by rust-bindgen */
#[derive(Clone, Copy)] #![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)] #[repr(u32)]
pub enum Enum_Unnamed1 { #[derive(Debug)]
VERTEX_SHDR = 0, pub enum DVLE_type { VERTEX_SHDR = 0, GEOMETRY_SHDR = 1, }
GEOMETRY_SHDR = 1, #[derive(Copy, Clone)]
}
pub type DVLE_type = Enum_Unnamed1;
#[derive(Clone, Copy)]
#[repr(u32)] #[repr(u32)]
pub enum Enum_Unnamed2 { #[derive(Debug)]
pub enum DVLE_constantType {
DVLE_CONST_BOOL = 0, DVLE_CONST_BOOL = 0,
DVLE_CONST_u8 = 1, DVLE_CONST_u8 = 1,
DVLE_CONST_FLOAT24 = 2, DVLE_CONST_FLOAT24 = 2,
} }
pub type DVLE_constantType = Enum_Unnamed2; #[derive(Copy, Clone)]
#[derive(Clone, Copy)]
#[repr(u32)] #[repr(u32)]
pub enum Enum_Unnamed3 { #[derive(Debug)]
pub enum DVLE_outputAttribute_t {
RESULT_POSITION = 0, RESULT_POSITION = 0,
RESULT_NORMALQUAT = 1, RESULT_NORMALQUAT = 1,
RESULT_COLOR = 2, RESULT_COLOR = 2,
@ -26,111 +28,107 @@ pub enum Enum_Unnamed3 {
RESULT_TEXCOORD1 = 5, RESULT_TEXCOORD1 = 5,
RESULT_TEXCOORD2 = 6, RESULT_TEXCOORD2 = 6,
RESULT_VIEW = 8, RESULT_VIEW = 8,
RESULT_DUMMY = 9,
} }
pub type DVLE_outputAttribute_t = Enum_Unnamed3; #[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
#[derive(Copy)] #[derive(Debug)]
pub struct Struct_Unnamed4 { pub enum DVLE_geoShaderMode {
pub codeSize: u32, GSH_POINT = 0,
pub codeData: *mut u32, GSH_VARIABLE_PRIM = 1,
pub opdescSize: u32, GSH_FIXED_PRIM = 2,
pub opcdescData: *mut u32,
}
impl ::core::clone::Clone for Struct_Unnamed4 {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for Struct_Unnamed4 { #[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct DVLP_s {
pub codeSize: u32_,
pub codeData: *mut u32_,
pub opdescSize: u32_,
pub opcdescData: *mut u32_,
}
impl ::core::default::Default for DVLP_s {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLP_s = Struct_Unnamed4;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed5 { #[derive(Debug)]
pub _type: u16, pub struct DVLE_constEntry_s {
pub id: u16, pub type_: u16_,
pub data: [u32; 4usize], pub id: u16_,
} pub data: [u32_; 4usize],
impl ::core::clone::Clone for Struct_Unnamed5 { }
fn clone(&self) -> Self { *self } impl ::core::default::Default for DVLE_constEntry_s {
}
impl ::core::default::Default for Struct_Unnamed5 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLE_constEntry_s = Struct_Unnamed5;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed6 { #[derive(Debug)]
pub _type: u16, pub struct DVLE_outEntry_s {
pub regID: u16, pub type_: u16_,
pub mask: u8, pub regID: u16_,
pub unk: [u8; 3usize], pub mask: u8_,
} pub unk: [u8_; 3usize],
impl ::core::clone::Clone for Struct_Unnamed6 { }
fn clone(&self) -> Self { *self } impl ::core::default::Default for DVLE_outEntry_s {
}
impl ::core::default::Default for Struct_Unnamed6 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLE_outEntry_s = Struct_Unnamed6;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed7 { #[derive(Debug)]
pub symbolOffset: u32, pub struct DVLE_uniformEntry_s {
pub startReg: u16, pub symbolOffset: u32_,
pub endReg: u16, pub startReg: u16_,
} pub endReg: u16_,
impl ::core::clone::Clone for Struct_Unnamed7 { }
fn clone(&self) -> Self { *self } impl ::core::default::Default for DVLE_uniformEntry_s {
}
impl ::core::default::Default for Struct_Unnamed7 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLE_uniformEntry_s = Struct_Unnamed7;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed8 { #[derive(Debug)]
pub _type: DVLE_type, pub struct DVLE_s {
pub type_: DVLE_type,
pub mergeOutmaps: u8,
pub gshMode: DVLE_geoShaderMode,
pub gshFixedVtxStart: u8_,
pub gshVariableVtxNum: u8_,
pub gshFixedVtxNum: u8_,
pub dvlp: *mut DVLP_s, pub dvlp: *mut DVLP_s,
pub mainOffset: u32, pub mainOffset: u32_,
pub endmainOffset: u32, pub endmainOffset: u32_,
pub constTableSize: u32, pub constTableSize: u32_,
pub constTableData: *mut DVLE_constEntry_s, pub constTableData: *mut DVLE_constEntry_s,
pub outTableSize: u32, pub outTableSize: u32_,
pub outTableData: *mut DVLE_outEntry_s, pub outTableData: *mut DVLE_outEntry_s,
pub uniformTableSize: u32, pub uniformTableSize: u32_,
pub uniformTableData: *mut DVLE_uniformEntry_s, pub uniformTableData: *mut DVLE_uniformEntry_s,
pub symbolTableData: *mut u8, pub symbolTableData: *mut ::libc::c_char,
pub outmapMask: u8, pub outmapMask: u8_,
pub outmapData: [u32; 8usize], pub outmapData: [u32_; 8usize],
pub outmapMode: u32, pub outmapMode: u32_,
pub outmapClock: u32, pub outmapClock: u32_,
} }
impl ::core::clone::Clone for Struct_Unnamed8 { impl ::core::default::Default for DVLE_s {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed8 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLE_s = Struct_Unnamed8;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed9 { #[derive(Debug)]
pub numDVLE: u32, pub struct DVLB_s {
pub numDVLE: u32_,
pub DVLP: DVLP_s, pub DVLP: DVLP_s,
pub DVLE: *mut DVLE_s, pub DVLE: *mut DVLE_s,
} }
impl ::core::clone::Clone for Struct_Unnamed9 { impl ::core::default::Default for DVLB_s {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed9 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DVLB_s = Struct_Unnamed9;
extern "C" { extern "C" {
pub fn DVLB_ParseFile(shbinData: *mut u32, shbinSize: u32) pub fn DVLB_ParseFile(shbinData: *mut u32_, shbinSize: u32_)
-> *mut DVLB_s; -> *mut DVLB_s;
pub fn DVLB_Free(dvlb: *mut DVLB_s); pub fn DVLB_Free(dvlb: *mut DVLB_s);
pub fn DVLE_GetUniformRegister(dvle: *mut DVLE_s, pub fn DVLE_GetUniformRegister(dvle: *mut DVLE_s,
name: *const u8) -> s8; name: *const ::libc::c_char) -> s8;
pub fn DVLE_GenerateOutmap(dvle: *mut DVLE_s); pub fn DVLE_GenerateOutmap(dvle: *mut DVLE_s);
} }
use ::types::*;

13
ctru-sys/src/lib.rs

@ -2,19 +2,23 @@
* C bindings generation: * C bindings generation:
* bindgen --match=file.h --use-core --ctypes-prefix=libc -- --sysroot=$DEVKITARM/arm-none-eabi -I$CTRULIB/include $CTRULIB/include/3ds.h * bindgen --match=file.h --use-core --ctypes-prefix=libc -- --sysroot=$DEVKITARM/arm-none-eabi -I$CTRULIB/include $CTRULIB/include/3ds.h
* *
* bindgen --sysroot=$DEVKITARM/arm-none-eabi -I$CTRULIB/include $CTRULIB/include/3ds.h
*/ */
#![no_std] #![no_std]
#![feature(question_mark)]
#![allow(non_camel_case_types, non_snake_case, overflowing_literals)] #![allow(non_camel_case_types, non_snake_case, overflowing_literals)]
#![feature(untagged_unions)]
extern crate ctr_libc as libc;
pub mod applets;
pub mod console; pub mod console;
pub mod env; pub mod env;
pub mod gfx; pub mod gfx;
pub mod gpu; pub mod gpu;
pub mod ipc; pub mod ipc;
pub mod ndsp;
pub mod os; pub mod os;
pub mod romfs;
pub mod sdmc; pub mod sdmc;
pub mod services; pub mod services;
pub mod svc; pub mod svc;
@ -26,8 +30,3 @@ pub mod types;
pub use self::sys::*; pub use self::sys::*;
pub use self::types::*; pub use self::types::*;
pub type Result = i32;
pub type Handle = u32;
pub type ThreadFunc = Option<extern "C" fn(arg1: *mut libc::c_void) -> ()>;

82
ctru-sys/src/ndsp/channel.rs

@ -0,0 +1,82 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
use ::types::*;
use super::ndsp::ndspWaveBuf;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 {
NDSP_ENCODING_PCM8 = 0,
NDSP_ENCODING_PCM16 = 1,
NDSP_ENCODING_ADPCM = 2,
}
pub const NDSP_FORMAT_PCM8: Enum_Unnamed2 =
Enum_Unnamed2::NDSP_FORMAT_MONO_PCM8;
pub const NDSP_FORMAT_PCM16: Enum_Unnamed2 =
Enum_Unnamed2::NDSP_FORMAT_MONO_PCM16;
pub const NDSP_FORMAT_ADPCM: Enum_Unnamed2 =
Enum_Unnamed2::NDSP_FORMAT_MONO_ADPCM;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed2 {
NDSP_FORMAT_MONO_PCM8 = 1,
NDSP_FORMAT_MONO_PCM16 = 5,
NDSP_FORMAT_MONO_ADPCM = 9,
NDSP_FORMAT_STEREO_PCM8 = 2,
NDSP_FORMAT_STEREO_PCM16 = 6,
NDSP_FRONT_BYPASS = 16,
NDSP_3D_SURROUND_PREPROCESSED = 64,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ndspInterpType {
NDSP_INTERP_POLYPHASE = 0,
NDSP_INTERP_LINEAR = 1,
NDSP_INTERP_NONE = 2,
}
extern "C" {
pub fn ndspChnReset(id: ::libc::c_int);
pub fn ndspChnInitParams(id: ::libc::c_int);
pub fn ndspChnIsPlaying(id: ::libc::c_int) -> u8;
pub fn ndspChnGetSamplePos(id: ::libc::c_int) -> u32_;
pub fn ndspChnGetWaveBufSeq(id: ::libc::c_int) -> u16_;
pub fn ndspChnIsPaused(id: ::libc::c_int) -> u8;
pub fn ndspChnSetPaused(id: ::libc::c_int, paused: u8);
pub fn ndspChnSetFormat(id: ::libc::c_int, format: u16_);
pub fn ndspChnSetInterp(id: ::libc::c_int, type_: ndspInterpType);
pub fn ndspChnSetRate(id: ::libc::c_int, rate: f32);
pub fn ndspChnSetMix(id: ::libc::c_int, mix: *mut f32);
pub fn ndspChnSetAdpcmCoefs(id: ::libc::c_int, coefs: *mut u16_);
pub fn ndspChnWaveBufClear(id: ::libc::c_int);
pub fn ndspChnWaveBufAdd(id: ::libc::c_int, buf: *mut ndspWaveBuf);
pub fn ndspChnIirMonoSetEnable(id: ::libc::c_int, enable: u8);
pub fn ndspChnIirMonoSetParamsCustomFilter(id: ::libc::c_int, a0: f32,
a1: f32, b0: f32) -> u8;
pub fn ndspChnIirMonoSetParamsLowPassFilter(id: ::libc::c_int, f0: f32)
-> u8;
pub fn ndspChnIirMonoSetParamsHighPassFilter(id: ::libc::c_int, f0: f32)
-> u8;
pub fn ndspChnIirBiquadSetEnable(id: ::libc::c_int, enable: u8);
pub fn ndspChnIirBiquadSetParamsCustomFilter(id: ::libc::c_int, a0: f32,
a1: f32, a2: f32, b0: f32,
b1: f32, b2: f32) -> u8;
pub fn ndspChnIirBiquadSetParamsLowPassFilter(id: ::libc::c_int, f0: f32,
Q: f32) -> u8;
pub fn ndspChnIirBiquadSetParamsHighPassFilter(id: ::libc::c_int, f0: f32,
Q: f32) -> u8;
pub fn ndspChnIirBiquadSetParamsBandPassFilter(id: ::libc::c_int, f0: f32,
Q: f32) -> u8;
pub fn ndspChnIirBiquadSetParamsNotchFilter(id: ::libc::c_int, f0: f32,
Q: f32) -> u8;
pub fn ndspChnIirBiquadSetParamsPeakingEqualizer(id: ::libc::c_int,
f0: f32, Q: f32,
gain: f32) -> u8;
}

2
ctru-sys/src/ndsp/mod.rs

@ -0,0 +1,2 @@
pub mod channel;
pub mod ndsp;

112
ctru-sys/src/ndsp/ndsp.rs

@ -0,0 +1,112 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ndspOutputMode {
NDSP_OUTPUT_MONO = 0,
NDSP_OUTPUT_STEREO = 1,
NDSP_OUTPUT_SURROUND = 2,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ndspClippingMode { NDSP_CLIP_NORMAL = 0, NDSP_CLIP_SOFT = 1, }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ndspSpeakerPos {
NDSP_SPKPOS_SQUARE = 0,
NDSP_SPKPOS_WIDE = 1,
NDSP_SPKPOS_NUM = 2,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ndspAdpcmData {
pub index: u16_,
pub history0: s16,
pub history1: s16,
}
impl ::core::default::Default for ndspAdpcmData {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
pub type ndspWaveBuf = tag_ndspWaveBuf;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 {
NDSP_WBUF_FREE = 0,
NDSP_WBUF_QUEUED = 1,
NDSP_WBUF_PLAYING = 2,
NDSP_WBUF_DONE = 3,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct tag_ndspWaveBuf {
pub _bindgen_data_1_: [u64; 1usize],
pub nsamples: u32_,
pub adpcm_data: *mut ndspAdpcmData,
pub offset: u32_,
pub looping: u8,
pub status: u8_,
pub sequence_id: u16_,
pub next: *mut ndspWaveBuf,
}
impl tag_ndspWaveBuf {
pub unsafe fn data_pcm8(&mut self) -> *mut *mut s8 {
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_);
::core::mem::transmute(raw.offset(0))
}
pub unsafe fn data_pcm16(&mut self) -> *mut *mut s16 {
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_);
::core::mem::transmute(raw.offset(0))
}
pub unsafe fn data_adpcm(&mut self) -> *mut *mut u8_ {
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_);
::core::mem::transmute(raw.offset(0))
}
pub unsafe fn data_vaddr(&mut self) -> *mut *const ::libc::c_void {
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_);
::core::mem::transmute(raw.offset(0))
}
}
impl ::core::default::Default for tag_ndspWaveBuf {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
pub type ndspCallback =
::core::option::Option<unsafe extern "C" fn(data: *mut ::libc::c_void)>;
pub type ndspAuxCallback =
::core::option::Option<unsafe extern "C" fn(data: *mut ::libc::c_void,
nsamples: ::libc::c_int,
samples:
*mut *mut ::libc::c_void)>;
extern "C" {
pub fn ndspUseComponent(binary: *const ::libc::c_void, size: u32_,
progMask: u16_, dataMask: u16_);
pub fn ndspInit() -> Result;
pub fn ndspExit();
pub fn ndspGetDroppedFrames() -> u32_;
pub fn ndspGetFrameCount() -> u32_;
pub fn ndspSetMasterVol(volume: f32);
pub fn ndspSetOutputMode(mode: ndspOutputMode);
pub fn ndspSetClippingMode(mode: ndspClippingMode);
pub fn ndspSetOutputCount(count: ::libc::c_int);
pub fn ndspSetCapture(capture: *mut ndspWaveBuf);
pub fn ndspSetCallback(callback: ndspCallback, data: *mut ::libc::c_void);
pub fn ndspSurroundSetDepth(depth: u16_);
pub fn ndspSurroundSetPos(pos: ndspSpeakerPos);
pub fn ndspSurroundSetRearRatio(ratio: u16_);
pub fn ndspAuxSetEnable(id: ::libc::c_int, enable: u8);
pub fn ndspAuxSetFrontBypass(id: ::libc::c_int, bypass: u8);
pub fn ndspAuxSetVolume(id: ::libc::c_int, volume: f32);
pub fn ndspAuxSetCallback(id: ::libc::c_int, callback: ndspAuxCallback,
data: *mut ::libc::c_void);
}
use ::types::*;

63
ctru-sys/src/os.rs

@ -1,54 +1,47 @@
//TODO: Fix Bindgen's issues again. /* automatically generated by rust-bindgen */
use ::Result; #![allow(dead_code,
use libc::c_void; non_camel_case_types,
use types::*; non_upper_case_globals,
non_snake_case)]
#[inline] #[derive(Copy, Clone)]
pub fn SYSTEM_VERSION(major: i32, minor: i32, revision: i32) { #[repr(u32)]
(((major)<<24)|((minor)<<16)|((revision)<<8)); #[derive(Debug)]
} pub enum MemRegion {
#[derive(Clone, Copy)]
#[repr(C)]
pub enum Enum_Unnamed1 {
MEMREGION_ALL = 0, MEMREGION_ALL = 0,
MEMREGION_APPLICATION = 1, MEMREGION_APPLICATION = 1,
MEMREGION_SYSTEM = 2, MEMREGION_SYSTEM = 2,
MEMREGION_BASE = 3, MEMREGION_BASE = 3,
} }
pub type MemRegion = Enum_Unnamed1;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed2 { #[derive(Debug)]
pub build: u8, pub struct OS_VersionBin {
pub minor: u8, pub build: u8_,
pub mainver: u8, pub minor: u8_,
pub reserved_x3: u8, pub mainver: u8_,
pub region: u8, pub reserved_x3: u8_,
pub reserved_x5: [u8; 3usize], pub region: ::libc::c_char,
} pub reserved_x5: [u8_; 3usize],
impl ::core::clone::Clone for Struct_Unnamed2 {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for Struct_Unnamed2 { impl ::core::default::Default for OS_VersionBin {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type OS_VersionBin = Struct_Unnamed2;
extern "C" { extern "C" {
pub fn osConvertVirtToPhys(vaddr: *const c_void) -> u32; pub fn osConvertVirtToPhys(vaddr: *const ::libc::c_void) -> u32_;
pub fn osConvertOldLINEARMemToNew(vaddr: *const c_void) pub fn osConvertOldLINEARMemToNew(vaddr: *const ::libc::c_void)
-> *mut c_void; -> *mut ::libc::c_void;
pub fn osStrError(error: u32) -> *const u8; pub fn osStrError(error: u32_) -> *const ::libc::c_char;
pub fn osGetMemRegionUsed(region: MemRegion) -> s64; pub fn osGetMemRegionUsed(region: MemRegion) -> s64;
pub fn osGetTime() -> u64; pub fn osGetTime() -> u64_;
pub fn osSetSpeedupEnable(enable: u8); pub fn osSetSpeedupEnable(enable: u8);
pub fn osGetSystemVersionData(nver_versionbin: *mut OS_VersionBin, pub fn osGetSystemVersionData(nver_versionbin: *mut OS_VersionBin,
cver_versionbin: *mut OS_VersionBin) cver_versionbin: *mut OS_VersionBin)
-> Result; -> Result;
pub fn osGetSystemVersionDataString(nver_versionbin: *mut OS_VersionBin, pub fn osGetSystemVersionDataString(nver_versionbin: *mut OS_VersionBin,
cver_versionbin: *mut OS_VersionBin, cver_versionbin: *mut OS_VersionBin,
sysverstr: sysverstr: *mut ::libc::c_char,
*mut u8, sysverstr_maxsize: u32_) -> Result;
sysverstr_maxsize: u32) -> Result;
} }
use ::types::*;

64
ctru-sys/src/romfs.rs

@ -0,0 +1,64 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct romfs_header {
pub headerSize: u32_,
pub dirHashTableOff: u32_,
pub dirHashTableSize: u32_,
pub dirTableOff: u32_,
pub dirTableSize: u32_,
pub fileHashTableOff: u32_,
pub fileHashTableSize: u32_,
pub fileTableOff: u32_,
pub fileTableSize: u32_,
pub fileDataOff: u32_,
}
impl ::core::default::Default for romfs_header {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct romfs_dir {
pub parent: u32_,
pub sibling: u32_,
pub childDir: u32_,
pub childFile: u32_,
pub nextHash: u32_,
pub nameLen: u32_,
pub name: [u16_; 0usize],
}
impl ::core::default::Default for romfs_dir {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct romfs_file {
pub parent: u32_,
pub sibling: u32_,
pub dataOff: u64_,
pub dataSize: u64_,
pub nextHash: u32_,
pub nameLen: u32_,
pub name: [u16_; 0usize],
}
impl ::core::default::Default for romfs_file {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
pub enum romfs_mount { }
extern "C" {
pub fn romfsMount(mount: *mut *mut romfs_mount) -> Result;
pub fn romfsMountFromFile(file: Handle, offset: u32_,
mount: *mut *mut romfs_mount) -> Result;
pub fn romfsBind(mount: *mut romfs_mount) -> Result;
pub fn romfsUnmount(mount: *mut romfs_mount) -> Result;
}
use ::types::*;

24
ctru-sys/src/sdmc.rs

@ -1,7 +1,29 @@
use Result; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
use ::types::*;
use services::fs::FS_DirectoryEntry;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct sdmc_dir_t {
pub magic: u32_,
pub fd: Handle,
pub index: ::libc::ssize_t,
pub size: ::libc::size_t,
pub entry_data: [FS_DirectoryEntry; 32usize],
}
impl ::core::default::Default for sdmc_dir_t {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" { extern "C" {
pub fn sdmcInit() -> Result; pub fn sdmcInit() -> Result;
pub fn sdmcWriteSafe(enable: u8);
pub fn sdmcExit() -> Result; pub fn sdmcExit() -> Result;
pub fn sdmc_getmtime(name: *const ::libc::c_char, mtime: *mut u64_)
-> Result;
} }

9
ctru-sys/src/services/ac.rs

@ -1,8 +1,13 @@
use ::Result; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub fn acInit() -> Result; pub fn acInit() -> Result;
pub fn acExit(); pub fn acExit();
pub fn acWaitInternetConnection() -> Result; pub fn acWaitInternetConnection() -> Result;
pub fn ACU_GetWifiStatus(out: *mut u32) -> Result; pub fn ACU_GetWifiStatus(out: *mut u32_) -> Result;
} }
use ::types::*;

191
ctru-sys/src/services/am.rs

@ -1,49 +1,186 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct AM_TitleEntry { pub struct AM_TitleEntry {
pub titleID: u64, pub titleID: u64_,
pub size: u64, pub size: u64_,
pub version: u16, pub version: u16_,
pub unk: [u8; 6usize], pub unk: [u8_; 6usize],
} }
impl ::core::clone::Clone for AM_TitleEntry {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for AM_TitleEntry { impl ::core::default::Default for AM_TitleEntry {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 {
AM_STATUS_MASK_INSTALLING = 1,
AM_STATUS_MASK_AWAITING_FINALIZATION = 2,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum AM_InstallStatus {
AM_STATUS_ABORTED = 2,
AM_STATUS_SAVED = 3,
AM_STATUS_INSTALL_IN_PROGRESS = 2050,
AM_STATUS_AWAITING_FINALIZATION = 2051,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct AM_PendingTitleEntry {
pub titleId: u64_,
pub version: u16_,
pub status: u16_,
pub titleType: u32_,
pub unk: [u8_; 8usize],
}
impl ::core::default::Default for AM_PendingTitleEntry {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed2 {
AM_DELETE_PENDING_NON_SYSTEM = 1,
AM_DELETE_PENDING_SYSTEM = 2,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct AM_TWLPartitionInfo {
pub capacity: u64_,
pub freeSpace: u64_,
pub titlesCapacity: u64_,
pub titlesFreeSpace: u64_,
}
impl ::core::default::Default for AM_TWLPartitionInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" { extern "C" {
pub fn amInit() -> Result; pub fn amInit() -> Result;
pub fn amAppInit() -> Result;
pub fn amExit(); pub fn amExit();
pub fn amGetSessionHandle() -> *mut Handle; pub fn amGetSessionHandle() -> *mut Handle;
pub fn AM_GetTitleCount(mediatype: u8, count: *mut u32) -> Result; pub fn AM_GetTitleCount(mediatype: FS_MediaType, count: *mut u32_)
pub fn AM_GetTitleIdList(mediatype: u8, count: u32, titleIDs: *mut u64) -> Result;
pub fn AM_GetTitleList(titlesRead: *mut u32_, mediatype: FS_MediaType,
titleCount: u32_, titleIds: *mut u64_) -> Result;
pub fn AM_GetTitleInfo(mediatype: FS_MediaType, titleCount: u32_,
titleIds: *mut u64_, titleInfo: *mut AM_TitleEntry)
-> Result; -> Result;
pub fn AM_GetDeviceId(deviceID: *mut u32) -> Result; pub fn AM_GetTicketCount(count: *mut u32_) -> Result;
pub fn AM_ListTitles(mediatype: u8, titleCount: u32, pub fn AM_GetTicketList(ticketsRead: *mut u32_, ticketCount: u32_,
titleIdList: *mut u64, titleList: *mut AM_TitleEntry) skip: u32_, ticketIds: *mut u64_) -> Result;
pub fn AM_GetPendingTitleCount(count: *mut u32_, mediatype: FS_MediaType,
statusMask: u32_) -> Result;
pub fn AM_GetPendingTitleList(titlesRead: *mut u32_, titleCount: u32_,
mediatype: FS_MediaType, statusMask: u32_,
titleIds: *mut u64_) -> Result;
pub fn AM_GetPendingTitleInfo(titleCount: u32_, mediatype: FS_MediaType,
titleIds: *mut u64_,
titleInfo: *mut AM_PendingTitleEntry)
-> Result; -> Result;
pub fn AM_StartCiaInstall(mediatype: u8, ciaHandle: *mut Handle) pub fn AM_GetDeviceId(deviceID: *mut u32_) -> Result;
pub fn AM_ExportTwlBackup(titleID: u64_, operation: u8_,
workbuf: *mut ::libc::c_void,
workbuf_size: u32_,
filepath: *const ::libc::c_char) -> Result;
pub fn AM_ImportTwlBackup(filehandle: Handle, operation: u8_,
buffer: *mut ::libc::c_void, size: u32_)
-> Result;
pub fn AM_ReadTwlBackupInfo(filehandle: Handle,
outinfo: *mut ::libc::c_void,
outinfo_size: u32_,
workbuf: *mut ::libc::c_void,
workbuf_size: u32_,
banner: *mut ::libc::c_void,
banner_size: u32_) -> Result;
pub fn AM_GetTWLPartitionInfo(info: *mut AM_TWLPartitionInfo) -> Result;
pub fn AM_StartCiaInstall(mediatype: FS_MediaType, ciaHandle: *mut Handle)
-> Result; -> Result;
pub fn AM_StartDlpChildCiaInstall(ciaHandle: *mut Handle) -> Result; pub fn AM_StartDlpChildCiaInstall(ciaHandle: *mut Handle) -> Result;
pub fn AM_CancelCIAInstall(ciaHandle: *mut Handle) -> Result; pub fn AM_CancelCIAInstall(ciaHandle: Handle) -> Result;
pub fn AM_FinishCiaInstall(mediatype: u8, ciaHandle: *mut Handle) pub fn AM_FinishCiaInstall(ciaHandle: Handle) -> Result;
pub fn AM_DeleteTitle(mediatype: FS_MediaType, titleID: u64_) -> Result;
pub fn AM_DeleteAppTitle(mediatype: FS_MediaType, titleID: u64_)
-> Result; -> Result;
pub fn AM_DeleteTitle(mediatype: u8, titleID: u64) -> Result; pub fn AM_DeleteTicket(ticketId: u64_) -> Result;
pub fn AM_DeleteAppTitle(mediatype: u8, titleID: u64) -> Result; pub fn AM_DeletePendingTitle(mediatype: FS_MediaType, titleId: u64_)
pub fn AM_InstallNativeFirm() -> Result;
pub fn AM_InstallFirm(titleID: u64) -> Result;
pub fn AM_GetTitleProductCode(mediatype: u8, titleID: u64,
productCode: *mut u8)
-> Result; -> Result;
pub fn AM_GetCiaFileInfo(mediatype: u8, titleEntry: *mut AM_TitleEntry, pub fn AM_DeletePendingTitles(mediatype: FS_MediaType, flags: u32_)
-> Result;
pub fn AM_DeleteAllPendingTitles(mediatype: FS_MediaType) -> Result;
pub fn AM_InstallNativeFirm() -> Result;
pub fn AM_InstallFirm(titleID: u64_) -> Result;
pub fn AM_GetTitleProductCode(mediatype: FS_MediaType, titleId: u64_,
productCode: *mut ::libc::c_char) -> Result;
pub fn AM_GetTitleExtDataId(extDataId: *mut u64_, mediatype: FS_MediaType,
titleId: u64_) -> Result;
pub fn AM_GetCiaFileInfo(mediatype: FS_MediaType,
titleEntry: *mut AM_TitleEntry,
fileHandle: Handle) -> Result; fileHandle: Handle) -> Result;
pub fn AM_GetCiaIcon(icon: *mut ::libc::c_void, fileHandle: Handle)
-> Result;
pub fn AM_GetCiaDependencies(dependencies: *mut u64_, fileHandle: Handle)
-> Result;
pub fn AM_GetCiaMetaOffset(metaOffset: *mut u64_, fileHandle: Handle)
-> Result;
pub fn AM_GetCiaCoreVersion(coreVersion: *mut u32_, fileHandle: Handle)
-> Result;
pub fn AM_GetCiaRequiredSpace(requiredSpace: *mut u64_,
mediaType: FS_MediaType, fileHandle: Handle)
-> Result;
pub fn AM_GetCiaMetaSection(meta: *mut ::libc::c_void, size: u32_,
fileHandle: Handle) -> Result;
pub fn AM_InitializeExternalTitleDatabase(overwrite: u8) -> Result; pub fn AM_InitializeExternalTitleDatabase(overwrite: u8) -> Result;
pub fn AM_QueryAvailableExternalTitleDatabase(available: *mut u8) pub fn AM_QueryAvailableExternalTitleDatabase(available: *mut u8)
-> Result; -> Result;
pub fn AM_InstallTicketBegin(ticketHandle: *mut Handle) -> Result;
pub fn AM_InstallTicketAbort(ticketHandle: Handle) -> Result;
pub fn AM_InstallTicketFinish(ticketHandle: Handle) -> Result;
pub fn AM_InstallTitleBegin(mediaType: FS_MediaType, titleId: u64_,
unk: u8) -> Result;
pub fn AM_InstallTitleStop() -> Result;
pub fn AM_InstallTitleResume(mediaType: FS_MediaType, titleId: u64_)
-> Result;
pub fn AM_InstallTitleAbort() -> Result;
pub fn AM_InstallTitleFinish() -> Result;
pub fn AM_CommitImportTitles(mediaType: FS_MediaType, titleCount: u32_,
temp: u8, titleIds: *mut u64_) -> Result;
pub fn AM_InstallTmdBegin(tmdHandle: *mut Handle) -> Result;
pub fn AM_InstallTmdAbort(tmdHandle: Handle) -> Result;
pub fn AM_InstallTmdFinish(tmdHandle: Handle, unk: u8) -> Result;
pub fn AM_CreateImportContentContexts(contentCount: u32_,
contentIndices: *mut u16_)
-> Result;
pub fn AM_InstallContentBegin(contentHandle: *mut Handle, index: u16_)
-> Result;
pub fn AM_InstallContentStop(contentHandle: Handle) -> Result;
pub fn AM_InstallContentResume(contentHandle: *mut Handle,
resumeOffset: *mut u64_, index: u16_)
-> Result;
pub fn AM_InstallContentCancel(contentHandle: Handle) -> Result;
pub fn AM_InstallContentFinish(contentHandle: Handle) -> Result;
pub fn AM_ImportCertificates(cert1Size: u32_, cert1: *mut ::libc::c_void,
cert2Size: u32_, cert2: *mut ::libc::c_void,
cert3Size: u32_, cert3: *mut ::libc::c_void,
cert4Size: u32_, cert4: *mut ::libc::c_void)
-> Result;
pub fn AM_ImportCertificate(certSize: u32_, cert: *mut ::libc::c_void)
-> Result;
pub fn AM_CommitImportTitlesAndUpdateFirmwareAuto(mediaType: FS_MediaType,
titleCount: u32_,
temp: u8,
titleIds: *mut u64_)
-> Result;
} }
use ::types::*;
use super::fs::FS_MediaType;

18
ctru-sys/src/services/ampxi.rs

@ -0,0 +1,18 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" {
pub fn ampxiInit(servhandle: Handle) -> Result;
pub fn ampxiExit();
pub fn AMPXI_WriteTWLSavedata(titleid: u64_, buffer: *mut u8_, size: u32_,
image_filepos: u32_, section_type: u8_,
operation: u8_) -> Result;
pub fn AMPXI_InstallTitlesFinish(mediaType: FS_MediaType, db: u8_,
titlecount: u32_, tidlist: *mut u64_)
-> Result;
}
use ::types::*;
use super::fs::FS_MediaType;

320
ctru-sys/src/services/apt.rs

@ -1,61 +1,121 @@
use ::{Result, Handle}; /* automatically generated by rust-bindgen */
use ::libc::c_void;
#[repr(C)] #![allow(dead_code,
#[derive(Clone, Copy)] non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum NS_APPID { pub enum NS_APPID {
APPID_HOMEMENU = 0x101, // Home Menu APPID_NONE = 0,
APPID_CAMERA = 0x110, // Camera applet APPID_HOMEMENU = 257,
APPID_FRIENDS_LIST = 0x112, // Friends List applet APPID_CAMERA = 272,
APPID_GAME_NOTES = 0x113, // Game Notes applet APPID_FRIENDS_LIST = 274,
APPID_WEB = 0x114, // Internet Browser APPID_GAME_NOTES = 275,
APPID_INSTRUCTION_MANUAL = 0x115, // Instruction Manual applet APPID_WEB = 276,
APPID_NOTIFICATIONS = 0x116, // Notifications applet APPID_INSTRUCTION_MANUAL = 277,
APPID_MIIVERSE = 0x117, // Miiverse applet APPID_NOTIFICATIONS = 278,
APPID_MIIVERSE_POSTING = 0x118, APPID_MIIVERSE = 279,
APPID_AMIIBO_SETTINGS = 0x119, APPID_MIIVERSE_POSTING = 280,
APPID_APPLICATION = 0x300, // Application APPID_AMIIBO_SETTINGS = 281,
APPID_ESHOP = 0x301, APPID_APPLICATION = 768,
APPID_SOFTWARE_KEYBOARD = 0x401, // Software Keyboard APPID_ESHOP = 769,
APPID_APPLETED = 0x402, // appletEd APPID_SOFTWARE_KEYBOARD = 1025,
APPID_PNOTE_AP = 0x404, // PNOTE_AP APPID_APPLETED = 1026,
APPID_SNOTE_AP = 0x405, // SNOTE_AP APPID_PNOTE_AP = 1028,
APPID_ERROR = 0x406, // error APPID_SNOTE_AP = 1029,
APPID_MINT = 0x407, // mint APPID_ERROR = 1030,
APPID_EXTRAPAD = 0x408, // extrapad APPID_MINT = 1031,
APPID_MEMOLIB = 0x409, // memolib APPID_EXTRAPAD = 1032,
APPID_MEMOLIB = 1033,
} }
#[derive(Copy, Clone)]
#[repr(C)] #[repr(i32)]
#[derive(Clone, Copy)] #[derive(Debug)]
pub enum APT_AppStatus { pub enum APT_AppletPos {
APP_NOTINITIALIZED = 0, APTPOS_NONE = -1,
APP_RUNNING = 1, APTPOS_APP = 0,
APP_SUSPENDED = 2, APTPOS_APPLIB = 1,
APP_EXITING = 3, APTPOS_SYS = 2,
APP_SUSPENDING = 4, APTPOS_SYSLIB = 3,
APP_SLEEPMODE = 5, APTPOS_RESIDENT = 4,
APP_PREPARE_SLEEPMODE = 6,
APP_APPLETSTARTED = 7,
APP_APPLETCLOSED = 8,
} }
pub type APT_AppletAttr = u8_;
#[repr(C)] #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[derive(Debug)]
pub enum APT_QueryReply {
APTREPLY_REJECT = 0,
APTREPLY_ACCEPT = 1,
APTREPLY_LATER = 2,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum APT_Signal { pub enum APT_Signal {
APTSIGNAL_NONE = 0,
APTSIGNAL_HOMEBUTTON = 1, APTSIGNAL_HOMEBUTTON = 1,
APTSIGNAL_PREPARESLEEP = 3, APTSIGNAL_HOMEBUTTON2 = 2,
APTSIGNAL_ENTERSLEEP = 5, APTSIGNAL_SLEEP_QUERY = 3,
APTSIGNAL_WAKEUP = 6, APTSIGNAL_SLEEP_CANCEL = 4,
APTSIGNAL_ENABLE = 7, APTSIGNAL_SLEEP_ENTER = 5,
APTSIGNAL_SLEEP_WAKEUP = 6,
APTSIGNAL_SHUTDOWN = 7,
APTSIGNAL_POWERBUTTON = 8, APTSIGNAL_POWERBUTTON = 8,
APTSIGNAL_UTILITY = 9, APTSIGNAL_POWERBUTTON2 = 9,
APTSIGNAL_SLEEPSYSTEM = 10, APTSIGNAL_TRY_SLEEP = 10,
APTSIGNAL_ERROR = 11, APTSIGNAL_ORDERTOCLOSE = 11,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum APT_Command {
APTCMD_NONE = 0,
APTCMD_WAKEUP = 1,
APTCMD_REQUEST = 2,
APTCMD_RESPONSE = 3,
APTCMD_EXIT = 4,
APTCMD_MESSAGE = 5,
APTCMD_HOMEBUTTON_ONCE = 6,
APTCMD_HOMEBUTTON_TWICE = 7,
APTCMD_DSP_SLEEP = 8,
APTCMD_DSP_WAKEUP = 9,
APTCMD_WAKEUP_EXIT = 10,
APTCMD_WAKEUP_PAUSE = 11,
APTCMD_WAKEUP_CANCEL = 12,
APTCMD_WAKEUP_CANCELALL = 13,
APTCMD_WAKEUP_POWERBUTTON = 14,
APTCMD_WAKEUP_JUMPTOHOME = 15,
APTCMD_SYSAPPLET_REQUEST = 16,
APTCMD_WAKEUP_LAUNCHAPP = 17,
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct aptCaptureBufInfo {
pub size: u32_,
pub is3D: u32_,
pub top: Struct_Unnamed1,
pub bottom: Struct_Unnamed1,
}
impl ::core::default::Default for aptCaptureBufInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct Struct_Unnamed1 {
pub leftOffset: u32_,
pub rightOffset: u32_,
pub format: u32_,
}
impl ::core::default::Default for Struct_Unnamed1 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum APT_HookType { pub enum APT_HookType {
APTHOOK_ONSUSPEND = 0, APTHOOK_ONSUSPEND = 0,
APTHOOK_ONRESTORE = 1, APTHOOK_ONRESTORE = 1,
@ -64,106 +124,118 @@ pub enum APT_HookType {
APTHOOK_ONEXIT = 4, APTHOOK_ONEXIT = 4,
APTHOOK_COUNT = 5, APTHOOK_COUNT = 5,
} }
pub type aptHookFn =
pub type aptHookFn = Option<unsafe extern "C" fn(hook: APT_HookType, param: *mut c_void)>; ::core::option::Option<unsafe extern "C" fn(hook: APT_HookType,
param: *mut ::libc::c_void)>;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct aptHookCookie { #[derive(Debug)]
pub next: *mut aptHookCookie, pub struct tag_aptHookCookie {
pub next: *mut tag_aptHookCookie,
pub callback: aptHookFn, pub callback: aptHookFn,
pub param: *mut c_void, pub param: *mut ::libc::c_void,
}
impl ::core::clone::Clone for aptHookCookie {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for aptHookCookie { impl ::core::default::Default for tag_aptHookCookie {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type aptHookCookie = tag_aptHookCookie;
extern "C" { pub type aptMessageCb =
pub static mut aptEvents: [Handle; 3usize]; ::core::option::Option<unsafe extern "C" fn(user: *mut ::libc::c_void,
} sender: NS_APPID,
msg: *mut ::libc::c_void,
msgsize: ::libc::size_t)>;
extern "C" { extern "C" {
pub fn aptInit() -> Result; pub fn aptInit() -> Result;
pub fn aptExit(); pub fn aptExit();
pub fn aptOpenSession(); pub fn aptSendCommand(aptcmdbuf: *mut u32_) -> Result;
pub fn aptCloseSession(); pub fn aptIsSleepAllowed() -> u8;
pub fn aptSetStatus(status: APT_AppStatus); pub fn aptSetSleepAllowed(allowed: u8);
pub fn aptGetStatus() -> APT_AppStatus;
pub fn aptGetStatusPower() -> u32;
pub fn aptSetStatusPower(status: u32);
pub fn aptReturnToMenu();
pub fn aptWaitStatusEvent();
pub fn aptSignalReadyForSleep();
pub fn aptGetMenuAppID() -> NS_APPID;
pub fn aptMainLoop() -> u8; pub fn aptMainLoop() -> u8;
pub fn aptHook(cookie: *mut aptHookCookie, callback: aptHookFn, pub fn aptHook(cookie: *mut aptHookCookie, callback: aptHookFn,
param: *mut c_void); param: *mut ::libc::c_void);
pub fn aptUnhook(cookie: *mut aptHookCookie); pub fn aptUnhook(cookie: *mut aptHookCookie);
pub fn APT_GetLockHandle(flags: u16, lockHandle: *mut Handle) -> Result; pub fn aptSetMessageCallback(callback: aptMessageCb,
pub fn APT_Initialize(appId: NS_APPID, eventHandle1: *mut Handle, user: *mut ::libc::c_void);
eventHandle2: *mut Handle) -> Result; pub fn aptLaunchLibraryApplet(appId: NS_APPID, buf: *mut ::libc::c_void,
bufsize: ::libc::size_t, handle: Handle) -> u8;
pub fn APT_GetLockHandle(flags: u16_, lockHandle: *mut Handle) -> Result;
pub fn APT_Initialize(appId: NS_APPID, attr: APT_AppletAttr,
signalEvent: *mut Handle, resumeEvent: *mut Handle)
-> Result;
pub fn APT_Finalize(appId: NS_APPID) -> Result; pub fn APT_Finalize(appId: NS_APPID) -> Result;
pub fn APT_HardwareResetAsync() -> Result; pub fn APT_HardwareResetAsync() -> Result;
pub fn APT_Enable(a: u32) -> Result; pub fn APT_Enable(attr: APT_AppletAttr) -> Result;
pub fn APT_GetAppletManInfo(inval: u8, outval8: *mut u8, pub fn APT_GetAppletManInfo(inpos: APT_AppletPos,
outval32: *mut u32, outpos: *mut APT_AppletPos,
req_appid: *mut NS_APPID,
menu_appid: *mut NS_APPID, menu_appid: *mut NS_APPID,
active_appid: *mut NS_APPID) -> Result; active_appid: *mut NS_APPID) -> Result;
pub fn APT_GetAppletInfo(appID: NS_APPID, pProgramID: *mut u64, pub fn APT_GetAppletInfo(appID: NS_APPID, pProgramID: *mut u64_,
pMediaType: *mut u8, pRegistered: *mut u8, pMediaType: *mut u8_, pRegistered: *mut u8,
pLoadState: *mut u8, pAttributes: *mut u32) pLoadState: *mut u8,
-> Result; pAttributes: *mut APT_AppletAttr) -> Result;
pub fn APT_GetAppletProgramInfo(id: u32, flags: u32, pub fn APT_GetAppletProgramInfo(id: u32_, flags: u32_,
titleversion: *mut u16) -> Result; titleversion: *mut u16_) -> Result;
pub fn APT_GetProgramID(pProgramID: *mut u64) -> Result; pub fn APT_GetProgramID(pProgramID: *mut u64_) -> Result;
pub fn APT_PrepareToJumpToHomeMenu() -> Result; pub fn APT_PrepareToJumpToHomeMenu() -> Result;
pub fn APT_JumpToHomeMenu(param: *const u8, paramSize: usize, pub fn APT_JumpToHomeMenu(param: *const ::libc::c_void, paramSize: ::libc::size_t,
handle: Handle) -> Result; handle: Handle) -> Result;
pub fn APT_PrepareToJumpToApplication(a: u32) -> Result; pub fn APT_PrepareToJumpToApplication(exiting: u8) -> Result;
pub fn APT_JumpToApplication(param: *const u8, paramSize: usize, pub fn APT_JumpToApplication(param: *const ::libc::c_void,
handle: Handle) -> Result; paramSize: ::libc::size_t, handle: Handle) -> Result;
pub fn APT_IsRegistered(appID: NS_APPID, out: *mut u8) -> Result; pub fn APT_IsRegistered(appID: NS_APPID, out: *mut u8) -> Result;
pub fn APT_InquireNotification(appID: u32, signalType: *mut APT_Signal) pub fn APT_InquireNotification(appID: u32_, signalType: *mut APT_Signal)
-> Result; -> Result;
pub fn APT_NotifyToWait(appID: NS_APPID) -> Result; pub fn APT_NotifyToWait(appID: NS_APPID) -> Result;
pub fn APT_AppletUtility(out: *mut u32, a: u32, size1: u32, pub fn APT_AppletUtility(id: ::libc::c_int, out: *mut ::libc::c_void,
buf1: *mut u8, size2: u32, buf2: *mut u8) outSize: ::libc::size_t, in_: *const ::libc::c_void,
inSize: ::libc::size_t) -> Result;
pub fn APT_SleepIfShellClosed() -> Result;
pub fn APT_TryLockTransition(transition: u32_, succeeded: *mut u8)
-> Result;
pub fn APT_UnlockTransition(transition: u32_) -> Result;
pub fn APT_GlanceParameter(appID: NS_APPID, buffer: *mut ::libc::c_void,
bufferSize: ::libc::size_t, sender: *mut NS_APPID,
command: *mut APT_Command,
actualSize: *mut ::libc::size_t,
parameter: *mut Handle) -> Result;
pub fn APT_ReceiveParameter(appID: NS_APPID, buffer: *mut ::libc::c_void,
bufferSize: ::libc::size_t, sender: *mut NS_APPID,
command: *mut APT_Command,
actualSize: *mut ::libc::size_t,
parameter: *mut Handle) -> Result;
pub fn APT_SendParameter(source: NS_APPID, dest: NS_APPID,
command: APT_Command,
buffer: *const ::libc::c_void, bufferSize: u32_,
parameter: Handle) -> Result;
pub fn APT_CancelParameter(source: NS_APPID, dest: NS_APPID,
success: *mut u8) -> Result;
pub fn APT_SendCaptureBufferInfo(captureBuf: *const aptCaptureBufInfo)
-> Result; -> Result;
pub fn APT_GlanceParameter(appID: NS_APPID, bufferSize: u32, pub fn APT_ReplySleepQuery(appID: NS_APPID, reply: APT_QueryReply)
buffer: *mut u32, actualSize: *mut u32,
signalType: *mut u8) -> Result;
pub fn APT_ReceiveParameter(appID: NS_APPID, bufferSize: u32,
buffer: *mut u32, actualSize: *mut u32,
signalType: *mut u8) -> Result;
pub fn APT_SendParameter(src_appID: NS_APPID, dst_appID: NS_APPID,
bufferSize: u32, buffer: *mut u32,
paramhandle: Handle, signalType: u8) -> Result;
pub fn APT_SendCaptureBufferInfo(bufferSize: u32, buffer: *mut u32)
-> Result; -> Result;
pub fn APT_ReplySleepQuery(appID: NS_APPID, a: u32) -> Result;
pub fn APT_ReplySleepNotificationComplete(appID: NS_APPID) -> Result; pub fn APT_ReplySleepNotificationComplete(appID: NS_APPID) -> Result;
pub fn APT_PrepareToCloseApplication(a: u8) -> Result; pub fn APT_PrepareToCloseApplication(cancelPreload: u8) -> Result;
pub fn APT_CloseApplication(param: *const u8, paramSize: usize, pub fn APT_CloseApplication(param: *const ::libc::c_void,
handle: Handle) -> Result; paramSize: ::libc::size_t, handle: Handle) -> Result;
pub fn APT_SetAppCpuTimeLimit(percent: u32) -> Result; pub fn APT_SetAppCpuTimeLimit(percent: u32_) -> Result;
pub fn APT_GetAppCpuTimeLimit(percent: *mut u32) -> Result; pub fn APT_GetAppCpuTimeLimit(percent: *mut u32_) -> Result;
pub fn APT_CheckNew3DS_Application(out: *mut u8) -> Result;
pub fn APT_CheckNew3DS_System(out: *mut u8) -> Result;
pub fn APT_CheckNew3DS(out: *mut u8) -> Result; pub fn APT_CheckNew3DS(out: *mut u8) -> Result;
pub fn APT_PrepareToDoAppJump(flags: u8, programID: u64, mediatype: u8) pub fn APT_PrepareToDoApplicationJump(flags: u8_, programID: u64_,
-> Result; mediatype: u8_) -> Result;
pub fn APT_DoAppJump(NSbuf0Size: u32, NSbuf1Size: u32, pub fn APT_DoApplicationJump(param: *const ::libc::c_void,
NSbuf0Ptr: *mut u8, NSbuf1Ptr: *mut u8) -> Result; paramSize: ::libc::size_t,
hmac: *const ::libc::c_void) -> Result;
pub fn APT_PrepareToStartLibraryApplet(appID: NS_APPID) -> Result; pub fn APT_PrepareToStartLibraryApplet(appID: NS_APPID) -> Result;
pub fn APT_StartLibraryApplet(appID: NS_APPID, inhandle: Handle, pub fn APT_StartLibraryApplet(appID: NS_APPID,
parambuf: *mut u32, parambufsize: u32) param: *const ::libc::c_void,
-> Result; paramSize: ::libc::size_t, handle: Handle)
pub fn APT_LaunchLibraryApplet(appID: NS_APPID, inhandle: Handle,
parambuf: *mut u32, parambufsize: u32)
-> Result; -> Result;
pub fn APT_PrepareToStartSystemApplet(appID: NS_APPID) -> Result; pub fn APT_PrepareToStartSystemApplet(appID: NS_APPID) -> Result;
pub fn APT_StartSystemApplet(appID: NS_APPID, bufSize: u32, pub fn APT_StartSystemApplet(appID: NS_APPID,
applHandle: Handle, buf: *mut u8) -> Result; param: *const ::libc::c_void,
paramSize: ::libc::size_t, handle: Handle) -> Result;
pub fn APT_GetSharedFont(fontHandle: *mut Handle, mapAddr: *mut u32_)
-> Result;
} }
use ::types::*;

378
ctru-sys/src/services/cam.rs

@ -1,20 +1,21 @@
// TODO: Determine if anonymous enums are properly represented (they probably aren't) /* automatically generated by rust-bindgen */
use ::{Handle, Result}; #![allow(dead_code,
use libc::c_void; non_camel_case_types,
use ::types::*; non_upper_case_globals,
non_snake_case)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 { pub enum Enum_Unnamed1 {
PORT_NONE = 0, PORT_NONE = 0,
PORT_CAM1 = 1, PORT_CAM1 = 1,
PORT_CAM2 = 2, PORT_CAM2 = 2,
PORT_BOTH = 3, PORT_BOTH = 3,
} }
#[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed2 { pub enum Enum_Unnamed2 {
SELECT_NONE = 0, SELECT_NONE = 0,
SELECT_OUT1 = 1, SELECT_OUT1 = 1,
@ -25,30 +26,29 @@ pub enum Enum_Unnamed2 {
SELECT_IN1_OUT2 = 6, SELECT_IN1_OUT2 = 6,
SELECT_ALL = 7, SELECT_ALL = 7,
} }
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
pub enum Enum_Unnamed3 { #[derive(Debug)]
pub enum CAMU_Context {
CONTEXT_NONE = 0, CONTEXT_NONE = 0,
CONTEXT_A = 1, CONTEXT_A = 1,
CONTEXT_B = 2, CONTEXT_B = 2,
CONTEXT_BOTH = 3, CONTEXT_BOTH = 3,
} }
#[derive(Copy, Clone)]
pub type CAMU_Context = Enum_Unnamed3; #[repr(u32)]
#[derive(Clone, Copy)] #[derive(Debug)]
#[repr(C)] pub enum CAMU_Flip {
pub enum Enum_Unnamed4 {
FLIP_NONE = 0, FLIP_NONE = 0,
FLIP_HORIZONTAL = 1, FLIP_HORIZONTAL = 1,
FLIP_VERTICAL = 2, FLIP_VERTICAL = 2,
FLIP_REVERSE = 3, FLIP_REVERSE = 3,
} }
pub type CAMU_Flip = Enum_Unnamed4; pub const SIZE_CTR_BOTTOM_LCD: CAMU_Size = CAMU_Size::SIZE_QVGA;
#[derive(Copy, Clone)]
pub const SIZE_CTR_BOTTOM_LCD: Enum_Unnamed5 = Enum_Unnamed5::SIZE_QVGA; #[repr(u32)]
#[derive(Clone, Copy)] #[derive(Debug)]
#[repr(C)] pub enum CAMU_Size {
pub enum Enum_Unnamed5 {
SIZE_VGA = 0, SIZE_VGA = 0,
SIZE_QVGA = 1, SIZE_QVGA = 1,
SIZE_QQVGA = 2, SIZE_QQVGA = 2,
@ -58,10 +58,9 @@ pub enum Enum_Unnamed5 {
SIZE_DS_LCDx4 = 6, SIZE_DS_LCDx4 = 6,
SIZE_CTR_TOP_LCD = 7, SIZE_CTR_TOP_LCD = 7,
} }
pub type CAMU_Size = Enum_Unnamed5; #[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Clone, Copy)] #[derive(Debug)]
#[repr(C)]
pub enum CAMU_FrameRate { pub enum CAMU_FrameRate {
FRAME_RATE_15 = 0, FRAME_RATE_15 = 0,
FRAME_RATE_15_TO_5 = 1, FRAME_RATE_15_TO_5 = 1,
@ -77,24 +76,24 @@ pub enum CAMU_FrameRate {
FRAME_RATE_20_TO_10 = 11, FRAME_RATE_20_TO_10 = 11,
FRAME_RATE_30_TO_10 = 12, FRAME_RATE_30_TO_10 = 12,
} }
pub const WHITE_BALANCE_NORMAL: CAMU_WhiteBalance =
pub const WHITE_BALANCE_NORMAL: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_AUTO;
Enum_Unnamed7::WHITE_BALANCE_AUTO; pub const WHITE_BALANCE_TUNGSTEN: CAMU_WhiteBalance =
pub const WHITE_BALANCE_TUNGSTEN: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_3200K;
Enum_Unnamed7::WHITE_BALANCE_3200K; pub const WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT: CAMU_WhiteBalance =
pub const WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_4150K;
Enum_Unnamed7::WHITE_BALANCE_4150K; pub const WHITE_BALANCE_DAYLIGHT: CAMU_WhiteBalance =
pub const WHITE_BALANCE_DAYLIGHT: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_5200K;
Enum_Unnamed7::WHITE_BALANCE_5200K; pub const WHITE_BALANCE_CLOUDY: CAMU_WhiteBalance =
pub const WHITE_BALANCE_CLOUDY: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_6000K;
Enum_Unnamed7::WHITE_BALANCE_6000K; pub const WHITE_BALANCE_HORIZON: CAMU_WhiteBalance =
pub const WHITE_BALANCE_HORIZON: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_6000K;
Enum_Unnamed7::WHITE_BALANCE_6000K; pub const WHITE_BALANCE_SHADE: CAMU_WhiteBalance =
pub const WHITE_BALANCE_SHADE: Enum_Unnamed7 = CAMU_WhiteBalance::WHITE_BALANCE_7000K;
Enum_Unnamed7::WHITE_BALANCE_7000K; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed7 { pub enum CAMU_WhiteBalance {
WHITE_BALANCE_AUTO = 0, WHITE_BALANCE_AUTO = 0,
WHITE_BALANCE_3200K = 1, WHITE_BALANCE_3200K = 1,
WHITE_BALANCE_4150K = 2, WHITE_BALANCE_4150K = 2,
@ -102,20 +101,20 @@ pub enum Enum_Unnamed7 {
WHITE_BALANCE_6000K = 4, WHITE_BALANCE_6000K = 4,
WHITE_BALANCE_7000K = 5, WHITE_BALANCE_7000K = 5,
} }
pub type CAMU_WhiteBalance = Enum_Unnamed7; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed8 { pub enum CAMU_PhotoMode {
PHOTO_MODE_NORMAL = 0, PHOTO_MODE_NORMAL = 0,
PHOTO_MODE_PORTRAIT = 1, PHOTO_MODE_PORTRAIT = 1,
PHOTO_MODE_LANDSCAPE = 2, PHOTO_MODE_LANDSCAPE = 2,
PHOTO_MODE_NIGHTVIEW = 3, PHOTO_MODE_NIGHTVIEW = 3,
PHOTO_MODE_LETTER = 4, PHOTO_MODE_LETTER = 4,
} }
pub type CAMU_PhotoMode = Enum_Unnamed8; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed9 { pub enum CAMU_Effect {
EFFECT_NONE = 0, EFFECT_NONE = 0,
EFFECT_MONO = 1, EFFECT_MONO = 1,
EFFECT_SEPIA = 2, EFFECT_SEPIA = 2,
@ -123,14 +122,13 @@ pub enum Enum_Unnamed9 {
EFFECT_NEGAFILM = 4, EFFECT_NEGAFILM = 4,
EFFECT_SEPIA01 = 5, EFFECT_SEPIA01 = 5,
} }
pub type CAMU_Effect = Enum_Unnamed9; pub const CONTRAST_LOW: CAMU_Contrast = CAMU_Contrast::CONTRAST_PATTERN_05;
pub const CONTRAST_LOW: Enum_Unnamed10 = Enum_Unnamed10::CONTRAST_PATTERN_05; pub const CONTRAST_NORMAL: CAMU_Contrast = CAMU_Contrast::CONTRAST_PATTERN_06;
pub const CONTRAST_NORMAL: Enum_Unnamed10 = pub const CONTRAST_HIGH: CAMU_Contrast = CAMU_Contrast::CONTRAST_PATTERN_07;
Enum_Unnamed10::CONTRAST_PATTERN_06; #[derive(Copy, Clone)]
pub const CONTRAST_HIGH: Enum_Unnamed10 = Enum_Unnamed10::CONTRAST_PATTERN_07; #[repr(u32)]
#[derive(Clone, Copy)] #[derive(Debug)]
#[repr(C)] pub enum CAMU_Contrast {
pub enum Enum_Unnamed10 {
CONTRAST_PATTERN_01 = 0, CONTRAST_PATTERN_01 = 0,
CONTRAST_PATTERN_02 = 1, CONTRAST_PATTERN_02 = 1,
CONTRAST_PATTERN_03 = 2, CONTRAST_PATTERN_03 = 2,
@ -143,60 +141,57 @@ pub enum Enum_Unnamed10 {
CONTRAST_PATTERN_10 = 9, CONTRAST_PATTERN_10 = 9,
CONTRAST_PATTERN_11 = 10, CONTRAST_PATTERN_11 = 10,
} }
pub type CAMU_Contrast = Enum_Unnamed10; pub const LENS_CORRECTION_DARK: CAMU_LensCorrection =
pub const LENS_CORRECTION_DARK: Enum_Unnamed11 = CAMU_LensCorrection::LENS_CORRECTION_OFF;
Enum_Unnamed11::LENS_CORRECTION_OFF; pub const LENS_CORRECTION_NORMAL: CAMU_LensCorrection =
pub const LENS_CORRECTION_NORMAL: Enum_Unnamed11 = CAMU_LensCorrection::LENS_CORRECTION_ON_70;
Enum_Unnamed11::LENS_CORRECTION_ON_70; pub const LENS_CORRECTION_BRIGHT: CAMU_LensCorrection =
pub const LENS_CORRECTION_BRIGHT: Enum_Unnamed11 = CAMU_LensCorrection::LENS_CORRECTION_ON_90;
Enum_Unnamed11::LENS_CORRECTION_ON_90; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed11 { pub enum CAMU_LensCorrection {
LENS_CORRECTION_OFF = 0, LENS_CORRECTION_OFF = 0,
LENS_CORRECTION_ON_70 = 1, LENS_CORRECTION_ON_70 = 1,
LENS_CORRECTION_ON_90 = 2, LENS_CORRECTION_ON_90 = 2,
} }
pub type CAMU_LensCorrection = Enum_Unnamed11; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed12 { OUTPUT_YUV_422 = 0, OUTPUT_RGB_565 = 1, } pub enum CAMU_OutputFormat { OUTPUT_YUV_422 = 0, OUTPUT_RGB_565 = 1, }
pub type CAMU_OutputFormat = Enum_Unnamed12; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed13 { pub enum CAMU_ShutterSoundType {
SHUTTER_SOUND_TYPE_NORMAL = 0, SHUTTER_SOUND_TYPE_NORMAL = 0,
SHUTTER_SOUND_TYPE_MOVIE = 1, SHUTTER_SOUND_TYPE_MOVIE = 1,
SHUTTER_SOUND_TYPE_MOVIE_END = 2, SHUTTER_SOUND_TYPE_MOVIE_END = 2,
} }
pub type CAMU_ShutterSoundType = Enum_Unnamed13;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed14 { #[derive(Debug)]
pub struct CAMU_ImageQualityCalibrationData {
pub aeBaseTarget: s16, pub aeBaseTarget: s16,
pub kRL: s16, pub kRL: s16,
pub kGL: s16, pub kGL: s16,
pub kBL: s16, pub kBL: s16,
pub ccmPosition: s16, pub ccmPosition: s16,
pub awbCcmL9Right: u16, pub awbCcmL9Right: u16_,
pub awbCcmL9Left: u16, pub awbCcmL9Left: u16_,
pub awbCcmL10Right: u16, pub awbCcmL10Right: u16_,
pub awbCcmL10Left: u16, pub awbCcmL10Left: u16_,
pub awbX0Right: u16, pub awbX0Right: u16_,
pub awbX0Left: u16, pub awbX0Left: u16_,
}
impl ::core::clone::Clone for Struct_Unnamed14 {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for Struct_Unnamed14 { impl ::core::default::Default for CAMU_ImageQualityCalibrationData {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CAMU_ImageQualityCalibrationData = Struct_Unnamed14;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed15 { #[derive(Debug)]
pub isValidRotationXY: u8, pub struct CAMU_StereoCameraCalibrationData {
pub padding: [u8; 3usize], pub isValidRotationXY: u8_,
pub padding: [u8_; 3usize],
pub scale: f32, pub scale: f32,
pub rotationZ: f32, pub rotationZ: f32,
pub translationX: f32, pub translationX: f32,
@ -209,30 +204,27 @@ pub struct Struct_Unnamed15 {
pub distanceCameras: f32, pub distanceCameras: f32,
pub imageWidth: s16, pub imageWidth: s16,
pub imageHeight: s16, pub imageHeight: s16,
pub reserved: [u8; 16usize], pub reserved: [u8_; 16usize],
} }
impl ::core::clone::Clone for Struct_Unnamed15 { impl ::core::default::Default for CAMU_StereoCameraCalibrationData {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed15 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CAMU_StereoCameraCalibrationData = Struct_Unnamed15;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed16 { #[derive(Debug)]
pub camera: u8, pub struct CAMU_PackageParameterCameraSelect {
pub camera: u8_,
pub exposure: s8, pub exposure: s8,
pub whiteBalance: u8, pub whiteBalance: u8_,
pub sharpness: s8, pub sharpness: s8,
pub autoExposureOn: u8, pub autoExposureOn: u8_,
pub autoWhiteBalanceOn: u8, pub autoWhiteBalanceOn: u8_,
pub frameRate: u8, pub frameRate: u8_,
pub photoMode: u8, pub photoMode: u8_,
pub contrast: u8, pub contrast: u8_,
pub lensCorrection: u8, pub lensCorrection: u8_,
pub noiseFilterOn: u8, pub noiseFilterOn: u8_,
pub padding: u8, pub padding: u8_,
pub autoExposureWindowX: s16, pub autoExposureWindowX: s16,
pub autoExposureWindowY: s16, pub autoExposureWindowY: s16,
pub autoExposureWindowWidth: s16, pub autoExposureWindowWidth: s16,
@ -242,36 +234,30 @@ pub struct Struct_Unnamed16 {
pub autoWhiteBalanceWindowWidth: s16, pub autoWhiteBalanceWindowWidth: s16,
pub autoWhiteBalanceWindowHeight: s16, pub autoWhiteBalanceWindowHeight: s16,
} }
impl ::core::clone::Clone for Struct_Unnamed16 { impl ::core::default::Default for CAMU_PackageParameterCameraSelect {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed16 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CAMU_PackageParameterCameraSelect = Struct_Unnamed16;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed17 { #[derive(Debug)]
pub camera: u8, pub struct CAMU_PackageParameterContext {
pub context: u8, pub camera: u8_,
pub flip: u8, pub context: u8_,
pub effect: u8, pub flip: u8_,
pub size: u8, pub effect: u8_,
pub size: u8_,
} }
impl ::core::clone::Clone for Struct_Unnamed17 { impl ::core::default::Default for CAMU_PackageParameterContext {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed17 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CAMU_PackageParameterContext = Struct_Unnamed17;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed18 { #[derive(Debug)]
pub camera: u8, pub struct CAMU_PackageParameterContextDetail {
pub context: u8, pub camera: u8_,
pub flip: u8, pub context: u8_,
pub effect: u8, pub flip: u8_,
pub effect: u8_,
pub width: s16, pub width: s16,
pub height: s16, pub height: s16,
pub cropX0: s16, pub cropX0: s16,
@ -279,93 +265,87 @@ pub struct Struct_Unnamed18 {
pub cropX1: s16, pub cropX1: s16,
pub cropY1: s16, pub cropY1: s16,
} }
impl ::core::clone::Clone for Struct_Unnamed18 { impl ::core::default::Default for CAMU_PackageParameterContextDetail {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed18 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CAMU_PackageParameterContextDetail = Struct_Unnamed18;
use services::y2r::Y2RU_StandardCoefficient;
extern "C" { extern "C" {
pub fn camInit() -> Result; pub fn camInit() -> Result;
pub fn camExit(); pub fn camExit();
pub fn CAMU_StartCapture(port: u32) -> Result; pub fn CAMU_StartCapture(port: u32_) -> Result;
pub fn CAMU_StopCapture(port: u32) -> Result; pub fn CAMU_StopCapture(port: u32_) -> Result;
pub fn CAMU_IsBusy(busy: *mut u8, port: u32) -> Result; pub fn CAMU_IsBusy(busy: *mut u8, port: u32_) -> Result;
pub fn CAMU_ClearBuffer(port: u32) -> Result; pub fn CAMU_ClearBuffer(port: u32_) -> Result;
pub fn CAMU_GetVsyncInterruptEvent(event: *mut Handle, port: u32) pub fn CAMU_GetVsyncInterruptEvent(event: *mut Handle, port: u32_)
-> Result;
pub fn CAMU_GetBufferErrorInterruptEvent(event: *mut Handle, port: u32_)
-> Result; -> Result;
pub fn CAMU_GetBufferErrorInterruptEvent(event: *mut Handle, port: u32) pub fn CAMU_SetReceiving(event: *mut Handle, dst: *mut ::libc::c_void,
port: u32_, imageSize: u32_, transferUnit: s16)
-> Result; -> Result;
pub fn CAMU_SetReceiving(event: *mut Handle, pub fn CAMU_IsFinishedReceiving(finishedReceiving: *mut u8, port: u32_)
dst: *mut c_void, port: u32,
imageSize: u32, transferUnit: s16) -> Result;
pub fn CAMU_IsFinishedReceiving(finishedReceiving: *mut u8, port: u32)
-> Result; -> Result;
pub fn CAMU_SetTransferLines(port: u32, lines: s16, width: s16, pub fn CAMU_SetTransferLines(port: u32_, lines: s16, width: s16,
height: s16) -> Result; height: s16) -> Result;
pub fn CAMU_GetMaxLines(maxLines: *mut s16, width: s16, height: s16) pub fn CAMU_GetMaxLines(maxLines: *mut s16, width: s16, height: s16)
-> Result; -> Result;
pub fn CAMU_SetTransferBytes(port: u32, bytes: u32, width: s16, pub fn CAMU_SetTransferBytes(port: u32_, bytes: u32_, width: s16,
height: s16) -> Result; height: s16) -> Result;
pub fn CAMU_GetTransferBytes(transferBytes: *mut u32, port: u32) pub fn CAMU_GetTransferBytes(transferBytes: *mut u32_, port: u32_)
-> Result; -> Result;
pub fn CAMU_GetMaxBytes(maxBytes: *mut u32, width: s16, height: s16) pub fn CAMU_GetMaxBytes(maxBytes: *mut u32_, width: s16, height: s16)
-> Result; -> Result;
pub fn CAMU_SetTrimming(port: u32, trimming: u8) -> Result; pub fn CAMU_SetTrimming(port: u32_, trimming: u8) -> Result;
pub fn CAMU_IsTrimming(trimming: *mut u8, port: u32) -> Result; pub fn CAMU_IsTrimming(trimming: *mut u8, port: u32_) -> Result;
pub fn CAMU_SetTrimmingParams(port: u32, xStart: s16, yStart: s16, pub fn CAMU_SetTrimmingParams(port: u32_, xStart: s16, yStart: s16,
xEnd: s16, yEnd: s16) -> Result; xEnd: s16, yEnd: s16) -> Result;
pub fn CAMU_GetTrimmingParams(xStart: *mut s16, yStart: *mut s16, pub fn CAMU_GetTrimmingParams(xStart: *mut s16, yStart: *mut s16,
xEnd: *mut s16, yEnd: *mut s16, port: u32) xEnd: *mut s16, yEnd: *mut s16, port: u32_)
-> Result; -> Result;
pub fn CAMU_SetTrimmingParamsCenter(port: u32, trimWidth: s16, pub fn CAMU_SetTrimmingParamsCenter(port: u32_, trimWidth: s16,
trimHeight: s16, camWidth: s16, trimHeight: s16, camWidth: s16,
camHeight: s16) -> Result; camHeight: s16) -> Result;
pub fn CAMU_Activate(select: u32) -> Result; pub fn CAMU_Activate(select: u32_) -> Result;
pub fn CAMU_SwitchContext(select: u32, context: CAMU_Context) -> Result; pub fn CAMU_SwitchContext(select: u32_, context: CAMU_Context) -> Result;
pub fn CAMU_SetExposure(select: u32, exposure: s8) -> Result; pub fn CAMU_SetExposure(select: u32_, exposure: s8) -> Result;
pub fn CAMU_SetWhiteBalance(select: u32, whiteBalance: CAMU_WhiteBalance) pub fn CAMU_SetWhiteBalance(select: u32_, whiteBalance: CAMU_WhiteBalance)
-> Result; -> Result;
pub fn CAMU_SetWhiteBalanceWithoutBaseUp(select: u32, pub fn CAMU_SetWhiteBalanceWithoutBaseUp(select: u32_,
whiteBalance: CAMU_WhiteBalance) whiteBalance: CAMU_WhiteBalance)
-> Result; -> Result;
pub fn CAMU_SetSharpness(select: u32, sharpness: s8) -> Result; pub fn CAMU_SetSharpness(select: u32_, sharpness: s8) -> Result;
pub fn CAMU_SetAutoExposure(select: u32, autoExposure: u8) -> Result; pub fn CAMU_SetAutoExposure(select: u32_, autoExposure: u8) -> Result;
pub fn CAMU_IsAutoExposure(autoExposure: *mut u8, select: u32) -> Result; pub fn CAMU_IsAutoExposure(autoExposure: *mut u8, select: u32_) -> Result;
pub fn CAMU_SetAutoWhiteBalance(select: u32, autoWhiteBalance: u8) pub fn CAMU_SetAutoWhiteBalance(select: u32_, autoWhiteBalance: u8)
-> Result; -> Result;
pub fn CAMU_IsAutoWhiteBalance(autoWhiteBalance: *mut u8, select: u32) pub fn CAMU_IsAutoWhiteBalance(autoWhiteBalance: *mut u8, select: u32_)
-> Result; -> Result;
pub fn CAMU_FlipImage(select: u32, flip: CAMU_Flip, pub fn CAMU_FlipImage(select: u32_, flip: CAMU_Flip,
context: CAMU_Context) -> Result; context: CAMU_Context) -> Result;
pub fn CAMU_SetDetailSize(select: u32, width: s16, height: s16, pub fn CAMU_SetDetailSize(select: u32_, width: s16, height: s16,
cropX0: s16, cropY0: s16, cropX1: s16, cropX0: s16, cropY0: s16, cropX1: s16,
cropY1: s16, context: CAMU_Context) -> Result; cropY1: s16, context: CAMU_Context) -> Result;
pub fn CAMU_SetSize(select: u32, size: CAMU_Size, context: CAMU_Context) pub fn CAMU_SetSize(select: u32_, size: CAMU_Size, context: CAMU_Context)
-> Result; -> Result;
pub fn CAMU_SetFrameRate(select: u32, frameRate: CAMU_FrameRate) pub fn CAMU_SetFrameRate(select: u32_, frameRate: CAMU_FrameRate)
-> Result; -> Result;
pub fn CAMU_SetPhotoMode(select: u32, photoMode: CAMU_PhotoMode) pub fn CAMU_SetPhotoMode(select: u32_, photoMode: CAMU_PhotoMode)
-> Result; -> Result;
pub fn CAMU_SetEffect(select: u32, effect: CAMU_Effect, pub fn CAMU_SetEffect(select: u32_, effect: CAMU_Effect,
context: CAMU_Context) -> Result; context: CAMU_Context) -> Result;
pub fn CAMU_SetContrast(select: u32, contrast: CAMU_Contrast) -> Result; pub fn CAMU_SetContrast(select: u32_, contrast: CAMU_Contrast) -> Result;
pub fn CAMU_SetLensCorrection(select: u32, pub fn CAMU_SetLensCorrection(select: u32_,
lensCorrection: CAMU_LensCorrection) lensCorrection: CAMU_LensCorrection)
-> Result; -> Result;
pub fn CAMU_SetOutputFormat(select: u32, format: CAMU_OutputFormat, pub fn CAMU_SetOutputFormat(select: u32_, format: CAMU_OutputFormat,
context: CAMU_Context) -> Result; context: CAMU_Context) -> Result;
pub fn CAMU_SetAutoExposureWindow(select: u32, x: s16, y: s16, pub fn CAMU_SetAutoExposureWindow(select: u32_, x: s16, y: s16,
width: s16, height: s16) -> Result; width: s16, height: s16) -> Result;
pub fn CAMU_SetAutoWhiteBalanceWindow(select: u32, x: s16, y: s16, pub fn CAMU_SetAutoWhiteBalanceWindow(select: u32_, x: s16, y: s16,
width: s16, height: s16) -> Result; width: s16, height: s16) -> Result;
pub fn CAMU_SetNoiseFilter(select: u32, noiseFilter: u8) -> Result; pub fn CAMU_SetNoiseFilter(select: u32_, noiseFilter: u8) -> Result;
pub fn CAMU_SynchronizeVsyncTiming(select1: u32, select2: u32) pub fn CAMU_SynchronizeVsyncTiming(select1: u32_, select2: u32_)
-> Result; -> Result;
pub fn CAMU_GetLatestVsyncTiming(timing: *mut s64, port: u32, past: u32) pub fn CAMU_GetLatestVsyncTiming(timing: *mut s64, port: u32_, past: u32_)
-> Result; -> Result;
pub fn CAMU_GetStereoCameraCalibrationData(data: pub fn CAMU_GetStereoCameraCalibrationData(data:
*mut CAMU_StereoCameraCalibrationData) *mut CAMU_StereoCameraCalibrationData)
@ -373,14 +353,14 @@ extern "C" {
pub fn CAMU_SetStereoCameraCalibrationData(data: pub fn CAMU_SetStereoCameraCalibrationData(data:
CAMU_StereoCameraCalibrationData) CAMU_StereoCameraCalibrationData)
-> Result; -> Result;
pub fn CAMU_WriteRegisterI2c(select: u32, addr: u16, data: u16) pub fn CAMU_WriteRegisterI2c(select: u32_, addr: u16_, data: u16_)
-> Result; -> Result;
pub fn CAMU_WriteMcuVariableI2c(select: u32, addr: u16, data: u16) pub fn CAMU_WriteMcuVariableI2c(select: u32_, addr: u16_, data: u16_)
-> Result; -> Result;
pub fn CAMU_ReadRegisterI2cExclusive(data: *mut u16, select: u32, pub fn CAMU_ReadRegisterI2cExclusive(data: *mut u16_, select: u32_,
addr: u16) -> Result; addr: u16_) -> Result;
pub fn CAMU_ReadMcuVariableI2cExclusive(data: *mut u16, select: u32, pub fn CAMU_ReadMcuVariableI2cExclusive(data: *mut u16_, select: u32_,
addr: u16) -> Result; addr: u16_) -> Result;
pub fn CAMU_SetImageQualityCalibrationData(data: pub fn CAMU_SetImageQualityCalibrationData(data:
CAMU_ImageQualityCalibrationData) CAMU_ImageQualityCalibrationData)
-> Result; -> Result;
@ -402,9 +382,11 @@ extern "C" {
pub fn CAMU_PlayShutterSound(sound: CAMU_ShutterSoundType) -> Result; pub fn CAMU_PlayShutterSound(sound: CAMU_ShutterSoundType) -> Result;
pub fn CAMU_DriverInitialize() -> Result; pub fn CAMU_DriverInitialize() -> Result;
pub fn CAMU_DriverFinalize() -> Result; pub fn CAMU_DriverFinalize() -> Result;
pub fn CAMU_GetActivatedCamera(select: *mut u32) -> Result; pub fn CAMU_GetActivatedCamera(select: *mut u32_) -> Result;
pub fn CAMU_GetSleepCamera(select: *mut u32) -> Result; pub fn CAMU_GetSleepCamera(select: *mut u32_) -> Result;
pub fn CAMU_SetSleepCamera(select: u32) -> Result; pub fn CAMU_SetSleepCamera(select: u32_) -> Result;
pub fn CAMU_SetBrightnessSynchronization(brightnessSynchronization: u8) pub fn CAMU_SetBrightnessSynchronization(brightnessSynchronization: u8)
-> Result; -> Result;
} }
use ::types::*;
use super::y2r::*;

19
ctru-sys/src/services/cfgnor.rs

@ -1,14 +1,19 @@
use ::Result; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub fn cfgnorInit(value: u8) -> Result; pub fn cfgnorInit(value: u8_) -> Result;
pub fn cfgnorExit(); pub fn cfgnorExit();
pub fn cfgnorDumpFlash(buf: *mut u32, size: u32) -> Result; pub fn cfgnorDumpFlash(buf: *mut u32_, size: u32_) -> Result;
pub fn cfgnorWriteFlash(buf: *mut u32, size: u32) -> Result; pub fn cfgnorWriteFlash(buf: *mut u32_, size: u32_) -> Result;
pub fn CFGNOR_Initialize(value: u8) -> Result; pub fn CFGNOR_Initialize(value: u8_) -> Result;
pub fn CFGNOR_Shutdown() -> Result; pub fn CFGNOR_Shutdown() -> Result;
pub fn CFGNOR_ReadData(offset: u32, buf: *mut u32, size: u32) pub fn CFGNOR_ReadData(offset: u32_, buf: *mut u32_, size: u32_)
-> Result; -> Result;
pub fn CFGNOR_WriteData(offset: u32, buf: *mut u32, size: u32) pub fn CFGNOR_WriteData(offset: u32_, buf: *mut u32_, size: u32_)
-> Result; -> Result;
} }
use ::types::*;

46
ctru-sys/src/services/cfgu.rs

@ -1,7 +1,12 @@
use ::Result; /* automatically generated by rust-bindgen */
#[repr(C)] #![allow(dead_code,
#[derive(Clone, Copy)] non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum CFG_Region { pub enum CFG_Region {
CFG_REGION_JPN = 0, CFG_REGION_JPN = 0,
CFG_REGION_USA = 1, CFG_REGION_USA = 1,
@ -11,9 +16,9 @@ pub enum CFG_Region {
CFG_REGION_KOR = 5, CFG_REGION_KOR = 5,
CFG_REGION_TWN = 6, CFG_REGION_TWN = 6,
} }
#[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
#[derive(Clone, Copy)] #[derive(Debug)]
pub enum CFG_Language { pub enum CFG_Language {
CFG_LANGUAGE_JP = 0, CFG_LANGUAGE_JP = 0,
CFG_LANGUAGE_EN = 1, CFG_LANGUAGE_EN = 1,
@ -28,19 +33,28 @@ pub enum CFG_Language {
CFG_LANGUAGE_RU = 10, CFG_LANGUAGE_RU = 10,
CFG_LANGUAGE_TW = 11, CFG_LANGUAGE_TW = 11,
} }
extern "C" { extern "C" {
pub fn cfguInit() -> Result; pub fn cfguInit() -> Result;
pub fn cfguExit(); pub fn cfguExit();
pub fn CFGU_SecureInfoGetRegion(region: *mut u8) -> Result; pub fn CFGU_SecureInfoGetRegion(region: *mut u8_) -> Result;
pub fn CFGU_GenHashConsoleUnique(appIDSalt: u32, hash: *mut u64) pub fn CFGU_GenHashConsoleUnique(appIDSalt: u32_, hash: *mut u64_)
-> Result;
pub fn CFGU_GetRegionCanadaUSA(value: *mut u8_) -> Result;
pub fn CFGU_GetSystemModel(model: *mut u8_) -> Result;
pub fn CFGU_GetModelNintendo2DS(value: *mut u8_) -> Result;
pub fn CFGU_GetCountryCodeString(code: u16_, string: *mut u16_) -> Result;
pub fn CFGU_GetCountryCodeID(string: u16_, code: *mut u16_) -> Result;
pub fn CFGU_GetConfigInfoBlk2(size: u32_, blkID: u32_, outData: *mut u8_)
-> Result;
pub fn CFG_GetConfigInfoBlk4(size: u32_, blkID: u32_, outData: *mut u8_)
-> Result;
pub fn CFG_GetConfigInfoBlk8(size: u32_, blkID: u32_, outData: *mut u8_)
-> Result;
pub fn CFG_SetConfigInfoBlk4(size: u32_, blkID: u32_, inData: *mut u8_)
-> Result; -> Result;
pub fn CFGU_GetRegionCanadaUSA(value: *mut u8) -> Result; pub fn CFG_SetConfigInfoBlk8(size: u32_, blkID: u32_, inData: *mut u8_)
pub fn CFGU_GetSystemModel(model: *mut u8) -> Result;
pub fn CFGU_GetModelNintendo2DS(value: *mut u8) -> Result;
pub fn CFGU_GetCountryCodeString(code: u16, string: *mut u16) -> Result;
pub fn CFGU_GetCountryCodeID(string: u16, code: *mut u16) -> Result;
pub fn CFGU_GetConfigInfoBlk2(size: u32, blkID: u32, outData: *mut u8)
-> Result; -> Result;
pub fn CFGU_GetSystemLanguage(language: *mut u8) -> Result; pub fn CFG_UpdateConfigNANDSavegame() -> Result;
pub fn CFGU_GetSystemLanguage(language: *mut u8_) -> Result;
} }
use ::types::*;

73
ctru-sys/src/services/dsp.rs

@ -1,48 +1,45 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
use ::libc::c_void;
#[repr(C)]
#[derive(Clone, Copy)]
pub enum DSP_InterruptType {
DSP_INTERRUPT_PIPE = 2,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub enum DSP_PipeDirection {
DSP_PIPE_INPUT = 0,
DSP_PIPE_OUTPUT = 1,
}
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum DSP_InterruptType { DSP_INTERRUPT_PIPE = 2, }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum DSP_PipeDirection { DSP_PIPE_INPUT = 0, DSP_PIPE_OUTPUT = 1, }
extern "C" { extern "C" {
pub fn dspInit() -> Result; pub fn dspInit() -> Result;
pub fn dspExit(); pub fn dspExit();
pub fn DSP_GetHeadphoneStatus(is_inserted: *mut u8) -> Result; pub fn DSP_GetHeadphoneStatus(is_inserted: *mut u8) -> Result;
pub fn DSP_FlushDataCache(address: *const c_void, pub fn DSP_FlushDataCache(address: *const ::libc::c_void, size: u32_)
size: u32) -> Result; -> Result;
pub fn DSP_InvalidateDataCache(address: *const c_void, pub fn DSP_InvalidateDataCache(address: *const ::libc::c_void, size: u32_)
size: u32) -> Result; -> Result;
pub fn DSP_GetSemaphoreHandle(semaphore: *mut Handle) -> Result; pub fn DSP_GetSemaphoreHandle(semaphore: *mut Handle) -> Result;
pub fn DSP_SetSemaphore(value: u16) -> Result; pub fn DSP_SetSemaphore(value: u16_) -> Result;
pub fn DSP_SetSemaphoreMask(mask: u16) -> Result; pub fn DSP_SetSemaphoreMask(mask: u16_) -> Result;
pub fn DSP_LoadComponent(component: *const c_void, pub fn DSP_LoadComponent(component: *const ::libc::c_void, size: u32_,
size: u32, prog_mask: u16, data_mask: u16, prog_mask: u16_, data_mask: u16_,
is_loaded: *mut u8) -> Result; is_loaded: *mut u8) -> Result;
pub fn DSP_UnloadComponent() -> Result; pub fn DSP_UnloadComponent() -> Result;
pub fn DSP_RegisterInterruptEvents(handle: Handle, interrupt: u32, pub fn DSP_RegisterInterruptEvents(handle: Handle, interrupt: u32_,
channel: u32) -> Result; channel: u32_) -> Result;
pub fn DSP_ReadPipeIfPossible(channel: u32, peer: u32, pub fn DSP_ReadPipeIfPossible(channel: u32_, peer: u32_,
buffer: *mut c_void, buffer: *mut ::libc::c_void, length: u16_,
length: u16, length_read: *mut u16) length_read: *mut u16_) -> Result;
-> Result; pub fn DSP_WriteProcessPipe(channel: u32_, buffer: *const ::libc::c_void,
pub fn DSP_WriteProcessPipe(channel: u32, length: u32_) -> Result;
buffer: *const c_void, pub fn DSP_ConvertProcessAddressFromDspDram(dsp_address: u32_,
length: u32) -> Result; arm_address: *mut u32_)
pub fn DSP_ConvertProcessAddressFromDspDram(dsp_address: u32,
arm_address: *mut u32)
-> Result; -> Result;
pub fn DSP_RecvData(regNo: u16, value: *mut u16) -> Result; pub fn DSP_RecvData(regNo: u16_, value: *mut u16_) -> Result;
pub fn DSP_RecvDataIsReady(regNo: u16, is_ready: *mut u8) -> Result; pub fn DSP_RecvDataIsReady(regNo: u16_, is_ready: *mut u8) -> Result;
pub fn DSP_SendData(regNo: u16, value: u16) -> Result; pub fn DSP_SendData(regNo: u16_, value: u16_) -> Result;
pub fn DSP_SendDataIsEmpty(regNo: u16, is_empty: *mut u8) -> Result; pub fn DSP_SendDataIsEmpty(regNo: u16_, is_empty: *mut u8) -> Result;
} }
use ::types::*;

369
ctru-sys/src/services/fs.rs

@ -4,21 +4,27 @@
non_camel_case_types, non_camel_case_types,
non_upper_case_globals, non_upper_case_globals,
non_snake_case)] non_snake_case)]
#[derive(Copy, Clone)]
use ::{Handle, Result}; #[repr(u32)]
#[derive(Debug)]
pub const FS_OPEN_READ: u32 = 1; pub enum Enum_Unnamed1 {
pub const FS_OPEN_WRITE: u32 = 2; FS_OPEN_READ = 1,
pub const FS_OPEN_CREATE: u32 = 4; FS_OPEN_WRITE = 2,
FS_OPEN_CREATE = 4,
pub const FS_WRITE_FLUSH: u32 = 1; }
pub const FS_WRITE_UPDATE_TIME: u32 = 256; #[derive(Copy, Clone)]
#[repr(u32)]
pub const FS_ATTRIBUTE_DIRECTORY: u32 = 1; #[derive(Debug)]
pub const FS_ATTRIBUTE_HIDDEN: u32 = 256; pub enum Enum_Unnamed2 { FS_WRITE_FLUSH = 1, FS_WRITE_UPDATE_TIME = 256, }
pub const FS_ATTRIBUTE_ARCHIVE: u32 = 65536; #[derive(Copy, Clone)]
pub const FS_ATTRIBUTE_READ_ONLY: u32 = 16777216; #[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed3 {
FS_ATTRIBUTE_DIRECTORY = 1,
FS_ATTRIBUTE_HIDDEN = 256,
FS_ATTRIBUTE_ARCHIVE = 65536,
FS_ATTRIBUTE_READ_ONLY = 16777216,
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(u32)] #[repr(u32)]
#[derive(Debug)] #[derive(Debug)]
@ -135,13 +141,13 @@ pub enum FS_DirectoryAction { DIRECTORY_ACTION_UNKNOWN = 0, }
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy)]
pub struct FS_DirectoryEntry { pub struct FS_DirectoryEntry {
pub name: [u16; 262usize], pub name: [u16_; 262usize],
pub shortName: [u8; 10usize], pub shortName: [::libc::c_char; 10usize],
pub shortExt: [u8; 4usize], pub shortExt: [::libc::c_char; 4usize],
pub valid: u8, pub valid: u8_,
pub reserved: u8, pub reserved: u8_,
pub attributes: u32, pub attributes: u32_,
pub fileSize: u64, pub fileSize: u64_,
} }
impl ::core::clone::Clone for FS_DirectoryEntry { impl ::core::clone::Clone for FS_DirectoryEntry {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
@ -153,10 +159,10 @@ impl ::core::default::Default for FS_DirectoryEntry {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct FS_ArchiveResource { pub struct FS_ArchiveResource {
pub sectorSize: u32, pub sectorSize: u32_,
pub clusterSize: u32, pub clusterSize: u32_,
pub totalClusters: u32, pub totalClusters: u32_,
pub freeClusters: u32, pub freeClusters: u32_,
} }
impl ::core::default::Default for FS_ArchiveResource { impl ::core::default::Default for FS_ArchiveResource {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -165,9 +171,9 @@ impl ::core::default::Default for FS_ArchiveResource {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct FS_ProgramInfo { pub struct FS_ProgramInfo {
pub programId: u64, pub programId: u64_,
pub _bindgen_bitfield_1_: FS_MediaType, pub _bindgen_bitfield_1_: FS_MediaType,
pub padding: [u8; 7usize], pub padding: [u8_; 7usize],
} }
impl ::core::default::Default for FS_ProgramInfo { impl ::core::default::Default for FS_ProgramInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -176,9 +182,9 @@ impl ::core::default::Default for FS_ProgramInfo {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct FS_ProductInfo { pub struct FS_ProductInfo {
pub productCode: [u8; 16usize], pub productCode: [::libc::c_char; 16usize],
pub companyCode: [u8; 2usize], pub companyCode: [::libc::c_char; 2usize],
pub remasterVersion: u16, pub remasterVersion: u16_,
} }
impl ::core::default::Default for FS_ProductInfo { impl ::core::default::Default for FS_ProductInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -186,8 +192,8 @@ impl ::core::default::Default for FS_ProductInfo {
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy)]
pub struct FS_IntegrityVerificationSeed { pub struct FS_IntegrityVerificationSeed {
pub aesCbcMac: [u8; 16usize], pub aesCbcMac: [u8_; 16usize],
pub movableSed: [u8; 288usize], pub movableSed: [u8_; 288usize],
} }
impl ::core::clone::Clone for FS_IntegrityVerificationSeed { impl ::core::clone::Clone for FS_IntegrityVerificationSeed {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
@ -200,10 +206,10 @@ impl ::core::default::Default for FS_IntegrityVerificationSeed {
#[derive(Debug)] #[derive(Debug)]
pub struct FS_ExtSaveDataInfo { pub struct FS_ExtSaveDataInfo {
pub _bindgen_bitfield_1_: FS_MediaType, pub _bindgen_bitfield_1_: FS_MediaType,
pub unknown: u8, pub unknown: u8_,
pub reserved1: u16, pub reserved1: u16_,
pub saveId: u64, pub saveId: u64_,
pub reserved2: u32, pub reserved2: u32_,
} }
impl ::core::default::Default for FS_ExtSaveDataInfo { impl ::core::default::Default for FS_ExtSaveDataInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -213,9 +219,9 @@ impl ::core::default::Default for FS_ExtSaveDataInfo {
#[derive(Debug)] #[derive(Debug)]
pub struct FS_SystemSaveDataInfo { pub struct FS_SystemSaveDataInfo {
pub _bindgen_bitfield_1_: FS_MediaType, pub _bindgen_bitfield_1_: FS_MediaType,
pub unknown: u8, pub unknown: u8_,
pub reserved: u16, pub reserved: u16_,
pub saveId: u32, pub saveId: u32_,
} }
impl ::core::default::Default for FS_SystemSaveDataInfo { impl ::core::default::Default for FS_SystemSaveDataInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -224,8 +230,8 @@ impl ::core::default::Default for FS_SystemSaveDataInfo {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct FS_DeviceMoveContext { pub struct FS_DeviceMoveContext {
pub ivs: [u8; 16usize], pub ivs: [u8_; 16usize],
pub encryptParameter: [u8; 16usize], pub encryptParameter: [u8_; 16usize],
} }
impl ::core::default::Default for FS_DeviceMoveContext { impl ::core::default::Default for FS_DeviceMoveContext {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -235,27 +241,27 @@ impl ::core::default::Default for FS_DeviceMoveContext {
#[derive(Debug)] #[derive(Debug)]
pub struct FS_Path { pub struct FS_Path {
pub type_: FS_PathType, pub type_: FS_PathType,
pub size: u32, pub size: u32_,
pub data: *const ::libc::c_void, pub data: *const ::libc::c_void,
} }
impl ::core::default::Default for FS_Path { impl ::core::default::Default for FS_Path {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type FS_Archive = u64; pub type FS_Archive = u64_;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct romfs_header { pub struct romfs_header {
pub headerSize: u32, pub headerSize: u32_,
pub dirHashTableOff: u32, pub dirHashTableOff: u32_,
pub dirHashTableSize: u32, pub dirHashTableSize: u32_,
pub dirTableOff: u32, pub dirTableOff: u32_,
pub dirTableSize: u32, pub dirTableSize: u32_,
pub fileHashTableOff: u32, pub fileHashTableOff: u32_,
pub fileHashTableSize: u32, pub fileHashTableSize: u32_,
pub fileTableOff: u32, pub fileTableOff: u32_,
pub fileTableSize: u32, pub fileTableSize: u32_,
pub fileDataOff: u32, pub fileDataOff: u32_,
} }
impl ::core::default::Default for romfs_header { impl ::core::default::Default for romfs_header {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -264,13 +270,13 @@ impl ::core::default::Default for romfs_header {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct romfs_dir { pub struct romfs_dir {
pub parent: u32, pub parent: u32_,
pub sibling: u32, pub sibling: u32_,
pub childDir: u32, pub childDir: u32_,
pub childFile: u32, pub childFile: u32_,
pub nextHash: u32, pub nextHash: u32_,
pub nameLen: u32, pub nameLen: u32_,
pub name: [u16; 0usize], pub name: [u16_; 0usize],
} }
impl ::core::default::Default for romfs_dir { impl ::core::default::Default for romfs_dir {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -279,13 +285,13 @@ impl ::core::default::Default for romfs_dir {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[derive(Debug)] #[derive(Debug)]
pub struct romfs_file { pub struct romfs_file {
pub parent: u32, pub parent: u32_,
pub sibling: u32, pub sibling: u32_,
pub dataOff: u64, pub dataOff: u64_,
pub dataSize: u64, pub dataSize: u64_,
pub nextHash: u32, pub nextHash: u32_,
pub nameLen: u32, pub nameLen: u32_,
pub name: [u16; 0usize], pub name: [u16_; 0usize],
} }
impl ::core::default::Default for romfs_file { impl ::core::default::Default for romfs_file {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
@ -302,15 +308,15 @@ extern "C" {
-> FS_Path; -> FS_Path;
pub fn fsGetSessionHandle() -> *mut Handle; pub fn fsGetSessionHandle() -> *mut Handle;
pub fn FSUSER_Control(action: FS_Action, input: *mut ::libc::c_void, pub fn FSUSER_Control(action: FS_Action, input: *mut ::libc::c_void,
inputSize: u32, output: *mut ::libc::c_void, inputSize: u32_, output: *mut ::libc::c_void,
outputSize: u32) -> Result; outputSize: u32_) -> Result;
pub fn FSUSER_Initialize(session: Handle) -> Result; pub fn FSUSER_Initialize(session: Handle) -> Result;
pub fn FSUSER_OpenFile(out: *mut Handle, archive: FS_Archive, pub fn FSUSER_OpenFile(out: *mut Handle, archive: FS_Archive,
path: FS_Path, openFlags: u32, attributes: u32) path: FS_Path, openFlags: u32_, attributes: u32_)
-> Result; -> Result;
pub fn FSUSER_OpenFileDirectly(out: *mut Handle, archiveId: FS_ArchiveID, pub fn FSUSER_OpenFileDirectly(out: *mut Handle, archiveId: FS_ArchiveID,
archivePath: FS_Path, filePath: FS_Path, archivePath: FS_Path, filePath: FS_Path,
openFlags: u32, attributes: u32) openFlags: u32_, attributes: u32_)
-> Result; -> Result;
pub fn FSUSER_DeleteFile(archive: FS_Archive, path: FS_Path) -> Result; pub fn FSUSER_DeleteFile(archive: FS_Archive, path: FS_Path) -> Result;
pub fn FSUSER_RenameFile(srcArchive: FS_Archive, srcPath: FS_Path, pub fn FSUSER_RenameFile(srcArchive: FS_Archive, srcPath: FS_Path,
@ -321,9 +327,9 @@ extern "C" {
pub fn FSUSER_DeleteDirectoryRecursively(archive: FS_Archive, pub fn FSUSER_DeleteDirectoryRecursively(archive: FS_Archive,
path: FS_Path) -> Result; path: FS_Path) -> Result;
pub fn FSUSER_CreateFile(archive: FS_Archive, path: FS_Path, pub fn FSUSER_CreateFile(archive: FS_Archive, path: FS_Path,
attributes: u32, fileSize: u64) -> Result; attributes: u32_, fileSize: u64_) -> Result;
pub fn FSUSER_CreateDirectory(archive: FS_Archive, path: FS_Path, pub fn FSUSER_CreateDirectory(archive: FS_Archive, path: FS_Path,
attributes: u32) -> Result; attributes: u32_) -> Result;
pub fn FSUSER_RenameDirectory(srcArchive: FS_Archive, srcPath: FS_Path, pub fn FSUSER_RenameDirectory(srcArchive: FS_Archive, srcPath: FS_Path,
dstArchive: FS_Archive, dstPath: FS_Path) dstArchive: FS_Archive, dstPath: FS_Path)
-> Result; -> Result;
@ -333,11 +339,11 @@ extern "C" {
path: FS_Path) -> Result; path: FS_Path) -> Result;
pub fn FSUSER_ControlArchive(archive: FS_Archive, pub fn FSUSER_ControlArchive(archive: FS_Archive,
action: FS_ArchiveAction, action: FS_ArchiveAction,
input: *mut ::libc::c_void, inputSize: u32, input: *mut ::libc::c_void, inputSize: u32_,
output: *mut ::libc::c_void, output: *mut ::libc::c_void,
outputSize: u32) -> Result; outputSize: u32_) -> Result;
pub fn FSUSER_CloseArchive(archive: FS_Archive) -> Result; pub fn FSUSER_CloseArchive(archive: FS_Archive) -> Result;
pub fn FSUSER_GetFreeBytes(freeBytes: *mut u64, archive: FS_Archive) pub fn FSUSER_GetFreeBytes(freeBytes: *mut u64_, archive: FS_Archive)
-> Result; -> Result;
pub fn FSUSER_GetCardType(type_: *mut FS_CardType) -> Result; pub fn FSUSER_GetCardType(type_: *mut FS_CardType) -> Result;
pub fn FSUSER_GetSdmcArchiveResource(archiveResource: pub fn FSUSER_GetSdmcArchiveResource(archiveResource:
@ -346,82 +352,82 @@ extern "C" {
pub fn FSUSER_GetNandArchiveResource(archiveResource: pub fn FSUSER_GetNandArchiveResource(archiveResource:
*mut FS_ArchiveResource) *mut FS_ArchiveResource)
-> Result; -> Result;
pub fn FSUSER_GetSdmcFatfsError(error: *mut u32) -> Result; pub fn FSUSER_GetSdmcFatfsError(error: *mut u32_) -> Result;
pub fn FSUSER_IsSdmcDetected(detected: *mut u8) -> Result; pub fn FSUSER_IsSdmcDetected(detected: *mut u8) -> Result;
pub fn FSUSER_IsSdmcWritable(writable: *mut u8) -> Result; pub fn FSUSER_IsSdmcWritable(writable: *mut u8) -> Result;
pub fn FSUSER_GetSdmcCid(out: *mut u8, length: u32) -> Result; pub fn FSUSER_GetSdmcCid(out: *mut u8_, length: u32_) -> Result;
pub fn FSUSER_GetNandCid(out: *mut u8, length: u32) -> Result; pub fn FSUSER_GetNandCid(out: *mut u8_, length: u32_) -> Result;
pub fn FSUSER_GetSdmcSpeedInfo(speedInfo: *mut u32) -> Result; pub fn FSUSER_GetSdmcSpeedInfo(speedInfo: *mut u32_) -> Result;
pub fn FSUSER_GetNandSpeedInfo(speedInfo: *mut u32) -> Result; pub fn FSUSER_GetNandSpeedInfo(speedInfo: *mut u32_) -> Result;
pub fn FSUSER_GetSdmcLog(out: *mut u8, length: u32) -> Result; pub fn FSUSER_GetSdmcLog(out: *mut u8_, length: u32_) -> Result;
pub fn FSUSER_GetNandLog(out: *mut u8, length: u32) -> Result; pub fn FSUSER_GetNandLog(out: *mut u8_, length: u32_) -> Result;
pub fn FSUSER_ClearSdmcLog() -> Result; pub fn FSUSER_ClearSdmcLog() -> Result;
pub fn FSUSER_ClearNandLog() -> Result; pub fn FSUSER_ClearNandLog() -> Result;
pub fn FSUSER_CardSlotIsInserted(inserted: *mut u8) -> Result; pub fn FSUSER_CardSlotIsInserted(inserted: *mut u8) -> Result;
pub fn FSUSER_CardSlotPowerOn(status: *mut u8) -> Result; pub fn FSUSER_CardSlotPowerOn(status: *mut u8) -> Result;
pub fn FSUSER_CardSlotPowerOff(status: *mut u8) -> Result; pub fn FSUSER_CardSlotPowerOff(status: *mut u8) -> Result;
pub fn FSUSER_CardSlotGetCardIFPowerStatus(status: *mut u8) -> Result; pub fn FSUSER_CardSlotGetCardIFPowerStatus(status: *mut u8) -> Result;
pub fn FSUSER_CardNorDirectCommand(commandId: u8) -> Result; pub fn FSUSER_CardNorDirectCommand(commandId: u8_) -> Result;
pub fn FSUSER_CardNorDirectCommandWithAddress(commandId: u8, pub fn FSUSER_CardNorDirectCommandWithAddress(commandId: u8_,
address: u32) -> Result; address: u32_) -> Result;
pub fn FSUSER_CardNorDirectRead(commandId: u8, size: u32, pub fn FSUSER_CardNorDirectRead(commandId: u8_, size: u32_,
output: *mut u8) -> Result; output: *mut u8_) -> Result;
pub fn FSUSER_CardNorDirectReadWithAddress(commandId: u8, address: u32, pub fn FSUSER_CardNorDirectReadWithAddress(commandId: u8_, address: u32_,
size: u32, output: *mut u8) size: u32_, output: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_CardNorDirectWrite(commandId: u8, size: u32, pub fn FSUSER_CardNorDirectWrite(commandId: u8_, size: u32_,
input: *mut u8) -> Result; input: *mut u8_) -> Result;
pub fn FSUSER_CardNorDirectWriteWithAddress(commandId: u8, address: u32, pub fn FSUSER_CardNorDirectWriteWithAddress(commandId: u8_, address: u32_,
size: u32, input: *mut u8) size: u32_, input: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_CardNorDirectRead_4xIO(commandId: u8, address: u32, pub fn FSUSER_CardNorDirectRead_4xIO(commandId: u8_, address: u32_,
size: u32, output: *mut u8) size: u32_, output: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_CardNorDirectCpuWriteWithoutVerify(address: u32, pub fn FSUSER_CardNorDirectCpuWriteWithoutVerify(address: u32_,
size: u32, size: u32_,
input: *mut u8) input: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_CardNorDirectSectorEraseWithoutVerify(address: u32) pub fn FSUSER_CardNorDirectSectorEraseWithoutVerify(address: u32_)
-> Result; -> Result;
pub fn FSUSER_GetProductInfo(info: *mut FS_ProductInfo, processId: u32) pub fn FSUSER_GetProductInfo(info: *mut FS_ProductInfo, processId: u32_)
-> Result; -> Result;
pub fn FSUSER_GetProgramLaunchInfo(info: *mut FS_ProgramInfo, pub fn FSUSER_GetProgramLaunchInfo(info: *mut FS_ProgramInfo,
processId: u32) -> Result; processId: u32_) -> Result;
pub fn FSUSER_SetCardSpiBaudRate(baudRate: FS_CardSpiBaudRate) -> Result; pub fn FSUSER_SetCardSpiBaudRate(baudRate: FS_CardSpiBaudRate) -> Result;
pub fn FSUSER_SetCardSpiBusMode(busMode: FS_CardSpiBusMode) -> Result; pub fn FSUSER_SetCardSpiBusMode(busMode: FS_CardSpiBusMode) -> Result;
pub fn FSUSER_SendInitializeInfoTo9() -> Result; pub fn FSUSER_SendInitializeInfoTo9() -> Result;
pub fn FSUSER_GetSpecialContentIndex(index: *mut u16, pub fn FSUSER_GetSpecialContentIndex(index: *mut u16_,
mediaType: FS_MediaType, mediaType: FS_MediaType,
programId: u64, programId: u64_,
type_: FS_SpecialContentType) type_: FS_SpecialContentType)
-> Result; -> Result;
pub fn FSUSER_GetLegacyRomHeader(mediaType: FS_MediaType, programId: u64, pub fn FSUSER_GetLegacyRomHeader(mediaType: FS_MediaType, programId: u64_,
header: *mut u8) -> Result; header: *mut u8_) -> Result;
pub fn FSUSER_GetLegacyBannerData(mediaType: FS_MediaType, pub fn FSUSER_GetLegacyBannerData(mediaType: FS_MediaType,
programId: u64, banner: *mut u8) programId: u64_, banner: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_CheckAuthorityToAccessExtSaveData(access: *mut u8, pub fn FSUSER_CheckAuthorityToAccessExtSaveData(access: *mut u8,
mediaType: FS_MediaType, mediaType: FS_MediaType,
saveId: u64, saveId: u64_,
processId: u32) processId: u32_)
-> Result; -> Result;
pub fn FSUSER_QueryTotalQuotaSize(quotaSize: *mut u64, directories: u32, pub fn FSUSER_QueryTotalQuotaSize(quotaSize: *mut u64_, directories: u32_,
files: u32, fileSizeCount: u32, files: u32_, fileSizeCount: u32_,
fileSizes: *mut u64) -> Result; fileSizes: *mut u64_) -> Result;
pub fn FSUSER_AbnegateAccessRight(accessRight: u32) -> Result; pub fn FSUSER_AbnegateAccessRight(accessRight: u32_) -> Result;
pub fn FSUSER_DeleteSdmcRoot() -> Result; pub fn FSUSER_DeleteSdmcRoot() -> Result;
pub fn FSUSER_DeleteAllExtSaveDataOnNand() -> Result; pub fn FSUSER_DeleteAllExtSaveDataOnNand() -> Result;
pub fn FSUSER_InitializeCtrFileSystem() -> Result; pub fn FSUSER_InitializeCtrFileSystem() -> Result;
pub fn FSUSER_CreateSeed() -> Result; pub fn FSUSER_CreateSeed() -> Result;
pub fn FSUSER_GetFormatInfo(totalSize: *mut u32, directories: *mut u32, pub fn FSUSER_GetFormatInfo(totalSize: *mut u32_, directories: *mut u32_,
files: *mut u32, duplicateData: *mut u8, files: *mut u32_, duplicateData: *mut u8,
archiveId: FS_ArchiveID, path: FS_Path) archiveId: FS_ArchiveID, path: FS_Path)
-> Result; -> Result;
pub fn FSUSER_GetLegacyRomHeader2(headerSize: u32, pub fn FSUSER_GetLegacyRomHeader2(headerSize: u32_,
mediaType: FS_MediaType, mediaType: FS_MediaType,
programId: u64, header: *mut u8) programId: u64_, header: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_GetSdmcCtrRootPath(out: *mut u8, length: u32) -> Result; pub fn FSUSER_GetSdmcCtrRootPath(out: *mut u8_, length: u32_) -> Result;
pub fn FSUSER_GetArchiveResource(archiveResource: *mut FS_ArchiveResource, pub fn FSUSER_GetArchiveResource(archiveResource: *mut FS_ArchiveResource,
mediaType: FS_SystemMediaType) -> Result; mediaType: FS_SystemMediaType) -> Result;
pub fn FSUSER_ExportIntegrityVerificationSeed(seed: pub fn FSUSER_ExportIntegrityVerificationSeed(seed:
@ -431,106 +437,111 @@ extern "C" {
*mut FS_IntegrityVerificationSeed) *mut FS_IntegrityVerificationSeed)
-> Result; -> Result;
pub fn FSUSER_FormatSaveData(archiveId: FS_ArchiveID, path: FS_Path, pub fn FSUSER_FormatSaveData(archiveId: FS_ArchiveID, path: FS_Path,
blocks: u32, directories: u32, files: u32, blocks: u32_, directories: u32_, files: u32_,
directoryBuckets: u32, fileBuckets: u32, directoryBuckets: u32_, fileBuckets: u32_,
duplicateData: u8) -> Result; duplicateData: u8) -> Result;
pub fn FSUSER_GetLegacySubBannerData(bannerSize: u32, pub fn FSUSER_GetLegacySubBannerData(bannerSize: u32_,
mediaType: FS_MediaType, mediaType: FS_MediaType,
programId: u64, banner: *mut u8) programId: u64_, banner: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_ReadSpecialFile(bytesRead: *mut u32, fileOffset: u64, pub fn FSUSER_UpdateSha256Context(data: *const ::libc::c_void,
size: u32, data: *mut u8) -> Result; inputSize: u32_, hash: *mut u8_)
pub fn FSUSER_GetSpecialFileSize(fileSize: *mut u64) -> Result; -> Result;
pub fn FSUSER_ReadSpecialFile(bytesRead: *mut u32_, fileOffset: u64_,
size: u32_, data: *mut u8_) -> Result;
pub fn FSUSER_GetSpecialFileSize(fileSize: *mut u64_) -> Result;
pub fn FSUSER_CreateExtSaveData(info: FS_ExtSaveDataInfo, pub fn FSUSER_CreateExtSaveData(info: FS_ExtSaveDataInfo,
directories: u32, files: u32, directories: u32_, files: u32_,
sizeLimit: u64, smdhSize: u32, sizeLimit: u64_, smdhSize: u32_,
smdh: *mut u8) -> Result; smdh: *mut u8_) -> Result;
pub fn FSUSER_DeleteExtSaveData(info: FS_ExtSaveDataInfo) -> Result; pub fn FSUSER_DeleteExtSaveData(info: FS_ExtSaveDataInfo) -> Result;
pub fn FSUSER_ReadExtSaveDataIcon(bytesRead: *mut u32, pub fn FSUSER_ReadExtSaveDataIcon(bytesRead: *mut u32_,
info: FS_ExtSaveDataInfo, info: FS_ExtSaveDataInfo,
smdhSize: u32, smdh: *mut u8) smdhSize: u32_, smdh: *mut u8_)
-> Result; -> Result;
pub fn FSUSER_GetExtDataBlockSize(totalBlocks: *mut u64, pub fn FSUSER_GetExtDataBlockSize(totalBlocks: *mut u64_,
freeBlocks: *mut u64, freeBlocks: *mut u64_,
blockSize: *mut u32, blockSize: *mut u32_,
info: FS_ExtSaveDataInfo) -> Result; info: FS_ExtSaveDataInfo) -> Result;
pub fn FSUSER_EnumerateExtSaveData(idsWritten: *mut u32, idsSize: u32, pub fn FSUSER_EnumerateExtSaveData(idsWritten: *mut u32_, idsSize: u32_,
mediaType: FS_MediaType, idSize: u32, mediaType: FS_MediaType, idSize: u32_,
shared: u8, ids: *mut u8) -> Result; shared: u8, ids: *mut u8_) -> Result;
pub fn FSUSER_CreateSystemSaveData(info: FS_SystemSaveDataInfo, pub fn FSUSER_CreateSystemSaveData(info: FS_SystemSaveDataInfo,
totalSize: u32, blockSize: u32, totalSize: u32_, blockSize: u32_,
directories: u32, files: u32, directories: u32_, files: u32_,
directoryBuckets: u32, directoryBuckets: u32_,
fileBuckets: u32, duplicateData: u8) fileBuckets: u32_, duplicateData: u8)
-> Result; -> Result;
pub fn FSUSER_DeleteSystemSaveData(info: FS_SystemSaveDataInfo) -> Result; pub fn FSUSER_DeleteSystemSaveData(info: FS_SystemSaveDataInfo) -> Result;
pub fn FSUSER_StartDeviceMoveAsSource(context: *mut FS_DeviceMoveContext) pub fn FSUSER_StartDeviceMoveAsSource(context: *mut FS_DeviceMoveContext)
-> Result; -> Result;
pub fn FSUSER_StartDeviceMoveAsDestination(context: FS_DeviceMoveContext, pub fn FSUSER_StartDeviceMoveAsDestination(context: FS_DeviceMoveContext,
clear: u8) -> Result; clear: u8) -> Result;
pub fn FSUSER_SetArchivePriority(archive: FS_Archive, priority: u32) pub fn FSUSER_SetArchivePriority(archive: FS_Archive, priority: u32_)
-> Result; -> Result;
pub fn FSUSER_GetArchivePriority(priority: *mut u32, archive: FS_Archive) pub fn FSUSER_GetArchivePriority(priority: *mut u32_, archive: FS_Archive)
-> Result; -> Result;
pub fn FSUSER_SetCtrCardLatencyParameter(latency: u64, pub fn FSUSER_SetCtrCardLatencyParameter(latency: u64_,
emulateEndurance: u8) -> Result; emulateEndurance: u8) -> Result;
pub fn FSUSER_SwitchCleanupInvalidSaveData(enable: u8) -> Result; pub fn FSUSER_SwitchCleanupInvalidSaveData(enable: u8) -> Result;
pub fn FSUSER_EnumerateSystemSaveData(idsWritten: *mut u32, pub fn FSUSER_EnumerateSystemSaveData(idsWritten: *mut u32_,
idsSize: u32, ids: *mut u32) idsSize: u32_, ids: *mut u32_)
-> Result; -> Result;
pub fn FSUSER_InitializeWithSdkVersion(session: Handle, version: u32) pub fn FSUSER_InitializeWithSdkVersion(session: Handle, version: u32_)
-> Result; -> Result;
pub fn FSUSER_SetPriority(priority: u32) -> Result; pub fn FSUSER_SetPriority(priority: u32_) -> Result;
pub fn FSUSER_GetPriority(priority: *mut u32) -> Result; pub fn FSUSER_GetPriority(priority: *mut u32_) -> Result;
pub fn FSUSER_SetSaveDataSecureValue(value: u64, pub fn FSUSER_SetSaveDataSecureValue(value: u64_,
slot: FS_SecureValueSlot, slot: FS_SecureValueSlot,
titleUniqueId: u32, titleUniqueId: u32_,
titleVariation: u8) -> Result; titleVariation: u8_) -> Result;
pub fn FSUSER_GetSaveDataSecureValue(exists: *mut u8, value: *mut u64, pub fn FSUSER_GetSaveDataSecureValue(exists: *mut u8, value: *mut u64_,
slot: FS_SecureValueSlot, slot: FS_SecureValueSlot,
titleUniqueId: u32, titleUniqueId: u32_,
titleVariation: u8) -> Result; titleVariation: u8_) -> Result;
pub fn FSUSER_ControlSecureSave(action: FS_SecureSaveAction, pub fn FSUSER_ControlSecureSave(action: FS_SecureSaveAction,
input: *mut ::libc::c_void, input: *mut ::libc::c_void,
inputSize: u32, inputSize: u32_,
output: *mut ::libc::c_void, output: *mut ::libc::c_void,
outputSize: u32) -> Result; outputSize: u32_) -> Result;
pub fn FSUSER_GetMediaType(mediaType: *mut FS_MediaType) -> Result; pub fn FSUSER_GetMediaType(mediaType: *mut FS_MediaType) -> Result;
pub fn FSFILE_Control(handle: Handle, action: FS_FileAction, pub fn FSFILE_Control(handle: Handle, action: FS_FileAction,
input: *mut ::libc::c_void, inputSize: u32, input: *mut ::libc::c_void, inputSize: u32_,
output: *mut ::libc::c_void, outputSize: u32) output: *mut ::libc::c_void, outputSize: u32_)
-> Result; -> Result;
pub fn FSFILE_OpenSubFile(handle: Handle, subFile: *mut Handle, pub fn FSFILE_OpenSubFile(handle: Handle, subFile: *mut Handle,
offset: u64, size: u64) -> Result; offset: u64_, size: u64_) -> Result;
pub fn FSFILE_Read(handle: Handle, bytesRead: *mut u32, offset: u64, pub fn FSFILE_Read(handle: Handle, bytesRead: *mut u32_, offset: u64_,
buffer: *mut ::libc::c_void, size: u32) -> Result; buffer: *mut ::libc::c_void, size: u32_) -> Result;
pub fn FSFILE_Write(handle: Handle, bytesWritten: *mut u32, offset: u64, pub fn FSFILE_Write(handle: Handle, bytesWritten: *mut u32_, offset: u64_,
buffer: *const ::libc::c_void, size: u32, buffer: *const ::libc::c_void, size: u32_,
flags: u32) -> Result; flags: u32_) -> Result;
pub fn FSFILE_GetSize(handle: Handle, size: *mut u64) -> Result; pub fn FSFILE_GetSize(handle: Handle, size: *mut u64_) -> Result;
pub fn FSFILE_SetSize(handle: Handle, size: u64) -> Result; pub fn FSFILE_SetSize(handle: Handle, size: u64_) -> Result;
pub fn FSFILE_GetAttributes(handle: Handle, attributes: *mut u32) pub fn FSFILE_GetAttributes(handle: Handle, attributes: *mut u32_)
-> Result; -> Result;
pub fn FSFILE_SetAttributes(handle: Handle, attributes: u32) -> Result; pub fn FSFILE_SetAttributes(handle: Handle, attributes: u32_) -> Result;
pub fn FSFILE_Close(handle: Handle) -> Result; pub fn FSFILE_Close(handle: Handle) -> Result;
pub fn FSFILE_Flush(handle: Handle) -> Result; pub fn FSFILE_Flush(handle: Handle) -> Result;
pub fn FSFILE_SetPriority(handle: Handle, priority: u32) -> Result; pub fn FSFILE_SetPriority(handle: Handle, priority: u32_) -> Result;
pub fn FSFILE_GetPriority(handle: Handle, priority: *mut u32) -> Result; pub fn FSFILE_GetPriority(handle: Handle, priority: *mut u32_) -> Result;
pub fn FSFILE_OpenLinkFile(handle: Handle, linkFile: *mut Handle) pub fn FSFILE_OpenLinkFile(handle: Handle, linkFile: *mut Handle)
-> Result; -> Result;
pub fn FSDIR_Control(handle: Handle, action: FS_DirectoryAction, pub fn FSDIR_Control(handle: Handle, action: FS_DirectoryAction,
input: *mut ::libc::c_void, inputSize: u32, input: *mut ::libc::c_void, inputSize: u32_,
output: *mut ::libc::c_void, outputSize: u32) output: *mut ::libc::c_void, outputSize: u32_)
-> Result; -> Result;
pub fn FSDIR_Read(handle: Handle, entriesRead: *mut u32, pub fn FSDIR_Read(handle: Handle, entriesRead: *mut u32_,
entryCount: u32, entries: *mut FS_DirectoryEntry) entryCount: u32_, entries: *mut FS_DirectoryEntry)
-> Result; -> Result;
pub fn FSDIR_Close(handle: Handle) -> Result; pub fn FSDIR_Close(handle: Handle) -> Result;
pub fn FSDIR_SetPriority(handle: Handle, priority: u32) -> Result; pub fn FSDIR_SetPriority(handle: Handle, priority: u32_) -> Result;
pub fn FSDIR_GetPriority(handle: Handle, priority: *mut u32) -> Result; pub fn FSDIR_GetPriority(handle: Handle, priority: *mut u32_) -> Result;
pub fn romfsMount(mount: *mut *mut romfs_mount) -> Result; pub fn romfsMount(mount: *mut *mut romfs_mount) -> Result;
pub fn romfsMountFromFile(file: Handle, offset: u32, pub fn romfsMountFromFile(file: Handle, offset: u32_,
mount: *mut *mut romfs_mount) -> Result; mount: *mut *mut romfs_mount) -> Result;
pub fn romfsBind(mount: *mut romfs_mount) -> Result; pub fn romfsBind(mount: *mut romfs_mount) -> Result;
pub fn romfsUnmount(mount: *mut romfs_mount) -> Result; pub fn romfsUnmount(mount: *mut romfs_mount) -> Result;
} }
use ::types::*;

107
ctru-sys/src/services/gspgpu.rs

@ -1,32 +1,27 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
use ::libc::c_void;
use ::types::*;
#[inline]
pub fn GSPGPU_REBASE_REG(r: u32) {
((r)-0x1EB00000);
}
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct GSPGPU_FramebufferInfo { pub struct GSPGPU_FramebufferInfo {
pub active_framebuf: u32, pub active_framebuf: u32_,
pub framebuf0_vaddr: *mut u32, pub framebuf0_vaddr: *mut u32_,
pub framebuf1_vaddr: *mut u32, pub framebuf1_vaddr: *mut u32_,
pub framebuf_widthbytesize: u32, pub framebuf_widthbytesize: u32_,
pub format: u32, pub format: u32_,
pub framebuf_dispselect: u32, pub framebuf_dispselect: u32_,
pub unk: u32, pub unk: u32_,
}
impl ::core::clone::Clone for GSPGPU_FramebufferInfo {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for GSPGPU_FramebufferInfo { impl ::core::default::Default for GSPGPU_FramebufferInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum GSPGPU_FramebufferFormats { pub enum GSPGPU_FramebufferFormats {
GSP_RGBA8_OES = 0, GSP_RGBA8_OES = 0,
GSP_BGR8_OES = 1, GSP_BGR8_OES = 1,
@ -34,35 +29,30 @@ pub enum GSPGPU_FramebufferFormats {
GSP_RGB5_A1_OES = 3, GSP_RGB5_A1_OES = 3,
GSP_RGBA4_OES = 4, GSP_RGBA4_OES = 4,
} }
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct GSPGPU_CaptureInfoEntry { pub struct GSPGPU_CaptureInfoEntry {
pub framebuf0_vaddr: *mut u32, pub framebuf0_vaddr: *mut u32_,
pub framebuf1_vaddr: *mut u32, pub framebuf1_vaddr: *mut u32_,
pub format: u32, pub format: u32_,
pub framebuf_widthbytesize: u32, pub framebuf_widthbytesize: u32_,
}
impl ::core::clone::Clone for GSPGPU_CaptureInfoEntry {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for GSPGPU_CaptureInfoEntry { impl ::core::default::Default for GSPGPU_CaptureInfoEntry {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct GSPGPU_CaptureInfo { pub struct GSPGPU_CaptureInfo {
pub screencapture: [GSPGPU_CaptureInfoEntry; 2usize], pub screencapture: [GSPGPU_CaptureInfoEntry; 2usize],
} }
impl ::core::clone::Clone for GSPGPU_CaptureInfo {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for GSPGPU_CaptureInfo { impl ::core::default::Default for GSPGPU_CaptureInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[derive(Copy, Clone)]
#[repr(C)] #[repr(u32)]
#[derive(Debug)]
pub enum GSPGPU_Event { pub enum GSPGPU_Event {
GSPGPU_EVENT_PSC0 = 0, GSPGPU_EVENT_PSC0 = 0,
GSPGPU_EVENT_PSC1 = 1, GSPGPU_EVENT_PSC1 = 1,
@ -73,48 +63,45 @@ pub enum GSPGPU_Event {
GSPGPU_EVENT_DMA = 6, GSPGPU_EVENT_DMA = 6,
GSPGPU_EVENT_MAX = 7, GSPGPU_EVENT_MAX = 7,
} }
use ThreadFunc;
extern "C" { extern "C" {
pub fn gspInit() -> Result; pub fn gspInit() -> Result;
pub fn gspExit(); pub fn gspExit();
pub fn gspSetEventCallback(id: GSPGPU_Event, cb: ThreadFunc, pub fn gspSetEventCallback(id: GSPGPU_Event, cb: ThreadFunc,
data: *mut c_void, data: *mut ::libc::c_void, oneShot: u8);
oneShot: u8);
pub fn gspInitEventHandler(gspEvent: Handle, gspSharedMem: *mut vu8, pub fn gspInitEventHandler(gspEvent: Handle, gspSharedMem: *mut vu8,
gspThreadId: u8) -> Result; gspThreadId: u8_) -> Result;
pub fn gspExitEventHandler(); pub fn gspExitEventHandler();
pub fn gspWaitForEvent(id: GSPGPU_Event, nextEvent: u8); pub fn gspWaitForEvent(id: GSPGPU_Event, nextEvent: u8);
pub fn gspWaitForAnyEvent() -> GSPGPU_Event; pub fn gspWaitForAnyEvent() -> GSPGPU_Event;
pub fn gspSubmitGxCommand(sharedGspCmdBuf: *mut u32, pub fn gspSubmitGxCommand(sharedGspCmdBuf: *mut u32_,
gxCommand: *mut u32) -> Result; gxCommand: *mut u32_) -> Result;
pub fn GSPGPU_AcquireRight(flags: u8) -> Result; pub fn GSPGPU_AcquireRight(flags: u8_) -> Result;
pub fn GSPGPU_ReleaseRight() -> Result; pub fn GSPGPU_ReleaseRight() -> Result;
pub fn GSPGPU_ImportDisplayCaptureInfo(captureinfo: pub fn GSPGPU_ImportDisplayCaptureInfo(captureinfo:
*mut GSPGPU_CaptureInfo) *mut GSPGPU_CaptureInfo)
-> Result; -> Result;
pub fn GSPGPU_SaveVramSysArea() -> Result; pub fn GSPGPU_SaveVramSysArea() -> Result;
pub fn GSPGPU_RestoreVramSysArea() -> Result; pub fn GSPGPU_RestoreVramSysArea() -> Result;
pub fn GSPGPU_SetLcdForceBlack(flags: u8) -> Result; pub fn GSPGPU_SetLcdForceBlack(flags: u8_) -> Result;
pub fn GSPGPU_SetBufferSwap(screenid: u32, pub fn GSPGPU_SetBufferSwap(screenid: u32_,
framebufinfo: *mut GSPGPU_FramebufferInfo) framebufinfo: *mut GSPGPU_FramebufferInfo)
-> Result; -> Result;
pub fn GSPGPU_FlushDataCache(adr: *const c_void, pub fn GSPGPU_FlushDataCache(adr: *const ::libc::c_void, size: u32_)
size: u32) -> Result; -> Result;
pub fn GSPGPU_InvalidateDataCache(adr: *const c_void, pub fn GSPGPU_InvalidateDataCache(adr: *const ::libc::c_void, size: u32_)
size: u32) -> Result;
pub fn GSPGPU_WriteHWRegs(regAddr: u32, data: *mut u32, size: u8)
-> Result; -> Result;
pub fn GSPGPU_WriteHWRegsWithMask(regAddr: u32, data: *mut u32, pub fn GSPGPU_WriteHWRegs(regAddr: u32_, data: *mut u32_, size: u8_)
datasize: u8, maskdata: *mut u32, -> Result;
masksize: u8) -> Result; pub fn GSPGPU_WriteHWRegsWithMask(regAddr: u32_, data: *mut u32_,
pub fn GSPGPU_ReadHWRegs(regAddr: u32, data: *mut u32, size: u8) datasize: u8_, maskdata: *mut u32_,
masksize: u8_) -> Result;
pub fn GSPGPU_ReadHWRegs(regAddr: u32_, data: *mut u32_, size: u8_)
-> Result; -> Result;
pub fn GSPGPU_RegisterInterruptRelayQueue(eventHandle: Handle, pub fn GSPGPU_RegisterInterruptRelayQueue(eventHandle: Handle,
flags: u32, flags: u32_,
outMemHandle: *mut Handle, outMemHandle: *mut Handle,
threadID: *mut u8) -> Result; threadID: *mut u8_) -> Result;
pub fn GSPGPU_UnregisterInterruptRelayQueue() -> Result; pub fn GSPGPU_UnregisterInterruptRelayQueue() -> Result;
pub fn GSPGPU_TriggerCmdReqQueue() -> Result; pub fn GSPGPU_TriggerCmdReqQueue() -> Result;
} }
use ::types::*;

19
ctru-sys/src/services/gsplcd.rs

@ -1,9 +1,12 @@
//TODO: Verify if anonymous enum is properly represented /* automatically generated by rust-bindgen */
use ::Result; #![allow(dead_code,
non_camel_case_types,
#[derive(Clone, Copy)] non_upper_case_globals,
#[repr(C)] non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 { pub enum Enum_Unnamed1 {
GSPLCD_SCREEN_TOP = 1, GSPLCD_SCREEN_TOP = 1,
GSPLCD_SCREEN_BOTTOM = 2, GSPLCD_SCREEN_BOTTOM = 2,
@ -12,6 +15,8 @@ pub enum Enum_Unnamed1 {
extern "C" { extern "C" {
pub fn gspLcdInit() -> Result; pub fn gspLcdInit() -> Result;
pub fn gspLcdExit(); pub fn gspLcdExit();
pub fn GSPLCD_PowerOnBacklight(screen: u32) -> Result; pub fn GSPLCD_PowerOnBacklight(screen: u32_) -> Result;
pub fn GSPLCD_PowerOffBacklight(screen: u32) -> Result; pub fn GSPLCD_PowerOffBacklight(screen: u32_) -> Result;
pub fn GSPLCD_GetVendors(vendors: *mut u8_) -> Result;
} }
use ::types::*;

13
ctru-sys/src/services/hb.rs

@ -1,13 +0,0 @@
use ::Result;
use ::libc::c_void;
extern "C" {
pub fn hbInit() -> Result;
pub fn hbExit() -> ();
pub fn HB_FlushInvalidateCache() -> Result;
pub fn HB_GetBootloaderAddresses(load3dsx: *mut *mut c_void, setArgv: *mut *mut c_void)
-> Result;
pub fn HB_ReprotectMemory(addr: *mut u32, pages: u32, mode: u32, reprotectedPages: *mut u32)
-> Result;
}

97
ctru-sys/src/services/hid.rs

@ -1,9 +1,12 @@
use ::types::*; /* automatically generated by rust-bindgen */
use ::{Result, Handle};
pub const HID_SHAREDMEM_DEFAULT: u32 = 0x10000000;
#[repr(C)] #![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum PAD_KEY { pub enum PAD_KEY {
KEY_A = 1, KEY_A = 1,
KEY_B = 2, KEY_B = 2,
@ -27,50 +30,57 @@ pub enum PAD_KEY {
KEY_CPAD_RIGHT = 268435456, KEY_CPAD_RIGHT = 268435456,
KEY_CPAD_LEFT = 536870912, KEY_CPAD_LEFT = 536870912,
KEY_CPAD_UP = 1073741824, KEY_CPAD_UP = 1073741824,
KEY_CPAD_DOWN = -2147483648, KEY_CPAD_DOWN = 2147483648,
KEY_UP = 1073741888, KEY_UP = 1073741888,
KEY_DOWN = -2147483520, KEY_DOWN = 2147483776,
KEY_LEFT = 536870944, KEY_LEFT = 536870944,
KEY_RIGHT = 268435472, KEY_RIGHT = 268435472,
// Generic catch-all directions
/*KEY_UP = KEY_DUP | KEY_CPAD_UP,
KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN,
KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT,
KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT,*/
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct touchPosition { pub struct touchPosition {
px: u16, pub px: u16_,
py: u16, pub py: u16_,
}
impl ::core::default::Default for touchPosition {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct circlePosition { pub struct circlePosition {
dx: s16, pub dx: s16,
dy: s16, pub dy: s16,
}
impl ::core::default::Default for circlePosition {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct accelVector { pub struct accelVector {
x: s16, pub x: s16,
y: s16, pub y: s16,
z: s16 pub z: s16,
}
impl ::core::default::Default for accelVector {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct angularRate { pub struct angularRate {
x: s16, //roll pub x: s16,
z: s16, //yaw pub z: s16,
y: s16, //pitch pub y: s16,
} }
impl ::core::default::Default for angularRate {
#[repr(C)] fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum HID_Event { pub enum HID_Event {
HIDEVENT_PAD0 = 0, HIDEVENT_PAD0 = 0,
HIDEVENT_PAD1 = 1, HIDEVENT_PAD1 = 1,
@ -78,17 +88,18 @@ pub enum HID_Event {
HIDEVENT_Gyro = 3, HIDEVENT_Gyro = 3,
HIDEVENT_DebugPad = 4, HIDEVENT_DebugPad = 4,
HIDEVENT_MAX = 5, HIDEVENT_MAX = 5,
} }
extern "C" {
pub static mut hidMemHandle: Handle;
pub static mut hidSharedMem: *mut vu32;
}
extern "C" { extern "C" {
pub fn hidInit() -> Result; pub fn hidInit() -> Result;
pub fn hidExit(); pub fn hidExit();
pub fn hidScanInput(); pub fn hidScanInput();
pub fn hidKeysHeld() -> u32; pub fn hidKeysHeld() -> u32_;
pub fn hidKeysDown() -> u32; pub fn hidKeysDown() -> u32_;
pub fn hidKeysUp() -> u32; pub fn hidKeysUp() -> u32_;
pub fn hidTouchRead(pos: *mut touchPosition); pub fn hidTouchRead(pos: *mut touchPosition);
pub fn hidCircleRead(pos: *mut circlePosition); pub fn hidCircleRead(pos: *mut circlePosition);
pub fn hidAccelRead(vector: *mut accelVector); pub fn hidAccelRead(vector: *mut accelVector);
@ -102,9 +113,7 @@ extern "C" {
pub fn HIDUSER_DisableAccelerometer() -> Result; pub fn HIDUSER_DisableAccelerometer() -> Result;
pub fn HIDUSER_EnableGyroscope() -> Result; pub fn HIDUSER_EnableGyroscope() -> Result;
pub fn HIDUSER_DisableGyroscope() -> Result; pub fn HIDUSER_DisableGyroscope() -> Result;
pub fn HIDUSER_GetGyroscopeRawToDpsCoefficient(coeff: pub fn HIDUSER_GetGyroscopeRawToDpsCoefficient(coeff: *mut f32) -> Result;
*mut f32) pub fn HIDUSER_GetSoundVolume(volume: *mut u8_) -> Result;
-> Result;
pub fn HIDUSER_GetSoundVolume(volume: *mut u8) -> Result;
} }
use ::types::*;

149
ctru-sys/src/services/httpc.rs

@ -1,79 +1,126 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
#[derive(Debug)]
pub struct httpcContext { pub struct httpcContext {
pub servhandle: Handle, pub servhandle: Handle,
pub httphandle: u32, pub httphandle: u32_,
}
impl ::core::clone::Clone for httpcContext {
fn clone(&self) -> Self { *self }
} }
impl ::core::default::Default for httpcContext { impl ::core::default::Default for httpcContext {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
#[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum HTTPC_RequestMethod {
HTTPC_METHOD_GET = 1,
HTTPC_METHOD_POST = 2,
HTTPC_METHOD_HEAD = 3,
HTTPC_METHOD_PUT = 4,
HTTPC_METHOD_DELETE = 5,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum HTTPC_RequestStatus { pub enum HTTPC_RequestStatus {
HTTPC_STATUS_REQUEST_IN_PROGRESS = 5, HTTPC_STATUS_REQUEST_IN_PROGRESS = 5,
HTTPC_STATUS_DOWNLOAD_READY = 7, HTTPC_STATUS_DOWNLOAD_READY = 7,
} }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum HTTPC_KeepAlive {
HTTPC_KEEPALIVE_DISABLED = 0,
HTTPC_KEEPALIVE_ENABLED = 1,
}
extern "C" { extern "C" {
pub fn httpcInit() -> Result; pub fn httpcInit(sharedmem_size: u32_) -> Result;
pub fn httpcExit(); pub fn httpcExit();
pub fn httpcOpenContext(context: *mut httpcContext, pub fn httpcOpenContext(context: *mut httpcContext,
url: *mut u8, method: HTTPC_RequestMethod,
use_defaultproxy: u32) -> Result; url: *const ::libc::c_char,
use_defaultproxy: u32_) -> Result;
pub fn httpcCloseContext(context: *mut httpcContext) -> Result; pub fn httpcCloseContext(context: *mut httpcContext) -> Result;
pub fn httpcCancelConnection(context: *mut httpcContext) -> Result;
pub fn httpcAddRequestHeaderField(context: *mut httpcContext, pub fn httpcAddRequestHeaderField(context: *mut httpcContext,
name: *mut u8, name: *const ::libc::c_char,
value: *mut u8) value: *const ::libc::c_char) -> Result;
-> Result; pub fn httpcAddPostDataAscii(context: *mut httpcContext,
name: *const ::libc::c_char,
value: *const ::libc::c_char) -> Result;
pub fn httpcAddPostDataRaw(context: *mut httpcContext, data: *const u32_,
len: u32_) -> Result;
pub fn httpcBeginRequest(context: *mut httpcContext) -> Result; pub fn httpcBeginRequest(context: *mut httpcContext) -> Result;
pub fn httpcReceiveData(context: *mut httpcContext, buffer: *mut u8, pub fn httpcReceiveData(context: *mut httpcContext, buffer: *mut u8_,
size: u32) -> Result; size: u32_) -> Result;
pub fn httpcReceiveDataTimeout(context: *mut httpcContext,
buffer: *mut u8_, size: u32_,
timeout: u64_) -> Result;
pub fn httpcGetRequestState(context: *mut httpcContext, pub fn httpcGetRequestState(context: *mut httpcContext,
out: *mut HTTPC_RequestStatus) -> Result; out: *mut HTTPC_RequestStatus) -> Result;
pub fn httpcGetDownloadSizeState(context: *mut httpcContext, pub fn httpcGetDownloadSizeState(context: *mut httpcContext,
downloadedsize: *mut u32, downloadedsize: *mut u32_,
contentsize: *mut u32) -> Result; contentsize: *mut u32_) -> Result;
pub fn httpcGetResponseStatusCode(context: *mut httpcContext, pub fn httpcGetResponseStatusCode(context: *mut httpcContext,
out: *mut u32, delay: u64) -> Result; out: *mut u32_) -> Result;
pub fn httpcGetResponseStatusCodeTimeout(context: *mut httpcContext,
out: *mut u32_, timeout: u64_)
-> Result;
pub fn httpcGetResponseHeader(context: *mut httpcContext, pub fn httpcGetResponseHeader(context: *mut httpcContext,
name: *mut u8, name: *const ::libc::c_char,
value: *mut u8, value: *mut ::libc::c_char,
valuebuf_maxsize: u32) -> Result; valuebuf_maxsize: u32_) -> Result;
pub fn httpcDownloadData(context: *mut httpcContext, buffer: *mut u8, pub fn httpcAddTrustedRootCA(context: *mut httpcContext, cert: *const u8_,
size: u32, downloadedsize: *mut u32) -> Result; certsize: u32_) -> Result;
pub fn HTTPC_Initialize(handle: Handle) -> Result; pub fn httpcAddDefaultCert(context: *mut httpcContext,
pub fn HTTPC_InitializeConnectionSession(handle: Handle, certID: SSLC_DefaultRootCert) -> Result;
contextHandle: Handle) -> Result; pub fn httpcSelectRootCertChain(context: *mut httpcContext,
pub fn HTTPC_CreateContext(handle: Handle, RootCertChain_contexthandle: u32_)
url: *mut u8, -> Result;
contextHandle: *mut Handle) -> Result; pub fn httpcSetClientCert(context: *mut httpcContext, cert: *const u8_,
pub fn HTTPC_CloseContext(handle: Handle, contextHandle: Handle) certsize: u32_, privk: *const u8_,
privk_size: u32_) -> Result;
pub fn httpcSetClientCertDefault(context: *mut httpcContext,
certID: SSLC_DefaultClientCert)
-> Result;
pub fn httpcSetClientCertContext(context: *mut httpcContext,
ClientCert_contexthandle: u32_)
-> Result;
pub fn httpcSetSSLOpt(context: *mut httpcContext, options: u32_)
-> Result;
pub fn httpcSetSSLClearOpt(context: *mut httpcContext, options: u32_)
-> Result;
pub fn httpcCreateRootCertChain(RootCertChain_contexthandle: *mut u32_)
-> Result;
pub fn httpcDestroyRootCertChain(RootCertChain_contexthandle: u32_)
-> Result; -> Result;
pub fn HTTPC_SetProxyDefault(handle: Handle, contextHandle: Handle) pub fn httpcRootCertChainAddCert(RootCertChain_contexthandle: u32_,
cert: *const u8_, certsize: u32_,
cert_contexthandle: *mut u32_) -> Result;
pub fn httpcRootCertChainAddDefaultCert(RootCertChain_contexthandle: u32_,
certID: SSLC_DefaultRootCert,
cert_contexthandle: *mut u32_)
-> Result; -> Result;
pub fn HTTPC_AddRequestHeaderField(handle: Handle, contextHandle: Handle, pub fn httpcRootCertChainRemoveCert(RootCertChain_contexthandle: u32_,
name: *mut u8, cert_contexthandle: u32_) -> Result;
value: *mut u8) pub fn httpcOpenClientCertContext(cert: *const u8_, certsize: u32_,
privk: *const u8_, privk_size: u32_,
ClientCert_contexthandle: *mut u32_)
-> Result; -> Result;
pub fn HTTPC_BeginRequest(handle: Handle, contextHandle: Handle) pub fn httpcOpenDefaultClientCertContext(certID: SSLC_DefaultClientCert,
ClientCert_contexthandle:
*mut u32_) -> Result;
pub fn httpcCloseClientCertContext(ClientCert_contexthandle: u32_)
-> Result; -> Result;
pub fn HTTPC_ReceiveData(handle: Handle, contextHandle: Handle, pub fn httpcDownloadData(context: *mut httpcContext, buffer: *mut u8_,
buffer: *mut u8, size: u32) -> Result; size: u32_, downloadedsize: *mut u32_) -> Result;
pub fn HTTPC_GetRequestState(handle: Handle, contextHandle: Handle, pub fn httpcSetKeepAlive(context: *mut httpcContext,
out: *mut HTTPC_RequestStatus) -> Result; option: HTTPC_KeepAlive) -> Result;
pub fn HTTPC_GetDownloadSizeState(handle: Handle, contextHandle: Handle,
downloadedsize: *mut u32,
contentsize: *mut u32) -> Result;
pub fn HTTPC_GetResponseHeader(handle: Handle, contextHandle: Handle,
name: *mut u8,
value: *mut u8,
valuebuf_maxsize: u32) -> Result;
pub fn HTTPC_GetResponseStatusCode(handle: Handle, contextHandle: Handle,
out: *mut u32) -> Result;
} }
use ::types::*;
use super::sslc::*;

30
ctru-sys/src/services/ir.rs

@ -1,21 +1,25 @@
use ::{Result, Handle}; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub fn iruInit(sharedmem_addr: *mut u32, sharedmem_size: u32) -> Result; pub fn iruInit(sharedmem_addr: *mut u32_, sharedmem_size: u32_) -> Result;
pub fn iruExit(); pub fn iruExit();
pub fn iruGetServHandle() -> Handle; pub fn iruGetServHandle() -> Handle;
pub fn iruSendData(buf: *mut u8, size: u32, wait: u8) -> Result; pub fn iruSendData(buf: *mut u8_, size: u32_, wait: u8) -> Result;
pub fn iruRecvData(buf: *mut u8, size: u32, flag: u8, pub fn iruRecvData(buf: *mut u8_, size: u32_, flag: u8_,
transfercount: *mut u32, wait: u8) -> Result; transfercount: *mut u32_, wait: u8) -> Result;
pub fn IRU_Initialize() -> Result; pub fn IRU_Initialize() -> Result;
pub fn IRU_Shutdown() -> Result; pub fn IRU_Shutdown() -> Result;
pub fn IRU_StartSendTransfer(buf: *mut u8, size: u32) -> Result; pub fn IRU_StartSendTransfer(buf: *mut u8_, size: u32_) -> Result;
pub fn IRU_WaitSendTransfer() -> Result; pub fn IRU_WaitSendTransfer() -> Result;
pub fn IRU_StartRecvTransfer(size: u32, flag: u8) -> Result; pub fn IRU_StartRecvTransfer(size: u32_, flag: u8_) -> Result;
pub fn IRU_WaitRecvTransfer(transfercount: *mut u32) -> Result; pub fn IRU_WaitRecvTransfer(transfercount: *mut u32_) -> Result;
pub fn IRU_SetBitRate(value: u8) -> Result; pub fn IRU_SetBitRate(value: u8_) -> Result;
pub fn IRU_GetBitRate(out: *mut u8) -> Result; pub fn IRU_GetBitRate(out: *mut u8_) -> Result;
pub fn IRU_SetIRLEDState(value: u32) -> Result; pub fn IRU_SetIRLEDState(value: u32_) -> Result;
pub fn IRU_GetIRLEDRecvState(out: *mut u32) -> Result; pub fn IRU_GetIRLEDRecvState(out: *mut u32_) -> Result;
} }
use ::types::*;

19
ctru-sys/src/services/irrst.rs

@ -1,21 +1,24 @@
use ::{Result, Handle}; /* automatically generated by rust-bindgen */
use ::types::*;
use super::hid::circlePosition;
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub static mut irrstMemHandle: Handle; pub static mut irrstMemHandle: Handle;
pub static mut irrstSharedMem: *mut vu32; pub static mut irrstSharedMem: *mut vu32;
}
extern "C" {
pub fn irrstInit() -> Result; pub fn irrstInit() -> Result;
pub fn irrstExit(); pub fn irrstExit();
pub fn irrstScanInput(); pub fn irrstScanInput();
pub fn irrstKeysHeld() -> u32; pub fn irrstKeysHeld() -> u32_;
pub fn irrstCstickRead(pos: *mut circlePosition); pub fn irrstCstickRead(pos: *mut circlePosition);
pub fn irrstWaitForEvent(nextEvent: u8); pub fn irrstWaitForEvent(nextEvent: u8);
pub fn IRRST_GetHandles(outMemHandle: *mut Handle, pub fn IRRST_GetHandles(outMemHandle: *mut Handle,
outEventHandle: *mut Handle) -> Result; outEventHandle: *mut Handle) -> Result;
pub fn IRRST_Initialize(unk1: u32, unk2: u8) -> Result; pub fn IRRST_Initialize(unk1: u32_, unk2: u8_) -> Result;
pub fn IRRST_Shutdown() -> Result; pub fn IRRST_Shutdown() -> Result;
} }
use ::types::*;
use super::hid::*;

35
ctru-sys/src/services/mic.rs

@ -1,42 +1,47 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
#[derive(Clone, Copy)] #![allow(dead_code,
#[repr(C)] non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum MICU_Encoding { pub enum MICU_Encoding {
MICU_ENCODING_PCM8 = 0, MICU_ENCODING_PCM8 = 0,
MICU_ENCODING_PCM16 = 1, MICU_ENCODING_PCM16 = 1,
MICU_ENCODING_PCM8_SIGNED = 2, MICU_ENCODING_PCM8_SIGNED = 2,
MICU_ENCODING_PCM16_SIGNED = 3, MICU_ENCODING_PCM16_SIGNED = 3,
} }
#[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum MICU_SampleRate { pub enum MICU_SampleRate {
MICU_SAMPLE_RATE_32730 = 0, MICU_SAMPLE_RATE_32730 = 0,
MICU_SAMPLE_RATE_16360 = 1, MICU_SAMPLE_RATE_16360 = 1,
MICU_SAMPLE_RATE_10910 = 2, MICU_SAMPLE_RATE_10910 = 2,
MICU_SAMPLE_RATE_8180 = 3, MICU_SAMPLE_RATE_8180 = 3,
} }
extern "C" { extern "C" {
pub fn micInit(buffer: *mut u8, bufferSize: u32) -> Result; pub fn micInit(buffer: *mut u8_, bufferSize: u32_) -> Result;
pub fn micExit(); pub fn micExit();
pub fn micGetSampleDataSize() -> u32; pub fn micGetSampleDataSize() -> u32_;
pub fn micGetLastSampleOffset() -> u32; pub fn micGetLastSampleOffset() -> u32_;
pub fn MICU_MapSharedMem(size: u32, handle: Handle) -> Result; pub fn MICU_MapSharedMem(size: u32_, handle: Handle) -> Result;
pub fn MICU_UnmapSharedMem() -> Result; pub fn MICU_UnmapSharedMem() -> Result;
pub fn MICU_StartSampling(encoding: MICU_Encoding, pub fn MICU_StartSampling(encoding: MICU_Encoding,
sampleRate: MICU_SampleRate, offset: u32, sampleRate: MICU_SampleRate, offset: u32_,
size: u32, _loop: u8) -> Result; size: u32_, loop_: u8) -> Result;
pub fn MICU_AdjustSampling(sampleRate: MICU_SampleRate) -> Result; pub fn MICU_AdjustSampling(sampleRate: MICU_SampleRate) -> Result;
pub fn MICU_StopSampling() -> Result; pub fn MICU_StopSampling() -> Result;
pub fn MICU_IsSampling(sampling: *mut u8) -> Result; pub fn MICU_IsSampling(sampling: *mut u8) -> Result;
pub fn MICU_GetEventHandle(handle: *mut Handle) -> Result; pub fn MICU_GetEventHandle(handle: *mut Handle) -> Result;
pub fn MICU_SetGain(gain: u8) -> Result; pub fn MICU_SetGain(gain: u8_) -> Result;
pub fn MICU_GetGain(gain: *mut u8) -> Result; pub fn MICU_GetGain(gain: *mut u8_) -> Result;
pub fn MICU_SetPower(power: u8) -> Result; pub fn MICU_SetPower(power: u8) -> Result;
pub fn MICU_GetPower(power: *mut u8) -> Result; pub fn MICU_GetPower(power: *mut u8) -> Result;
pub fn MICU_SetClamp(clamp: u8) -> Result; pub fn MICU_SetClamp(clamp: u8) -> Result;
pub fn MICU_GetClamp(clamp: *mut u8) -> Result; pub fn MICU_GetClamp(clamp: *mut u8) -> Result;
pub fn MICU_SetAllowShellClosed(allowShellClosed: u8) -> Result; pub fn MICU_SetAllowShellClosed(allowShellClosed: u8) -> Result;
} }
use ::types::*;

8
ctru-sys/src/services/mod.rs

@ -1,5 +1,6 @@
pub mod ac; pub mod ac;
pub mod am; pub mod am;
pub mod ampxi;
pub mod apt; pub mod apt;
pub mod cam; pub mod cam;
pub mod cfgnor; pub mod cfgnor;
@ -8,20 +9,23 @@ pub mod dsp;
pub mod fs; pub mod fs;
pub mod gspgpu; pub mod gspgpu;
pub mod gsplcd; pub mod gsplcd;
pub mod hb;
pub mod hid; pub mod hid;
pub mod httpc; pub mod httpc;
pub mod ir; pub mod ir;
pub mod irrst; pub mod irrst;
pub mod mic; pub mod mic;
pub mod mvd; pub mod mvd;
pub mod ndm;
pub mod news; pub mod news;
pub mod nfc;
pub mod ns; pub mod ns;
pub mod pm; pub mod pm;
pub mod ps; pub mod ps;
pub mod ptmsysm; pub mod ptmsysm;
pub mod ptmu; pub mod ptmu;
pub mod pxidev;
pub mod qtm; pub mod qtm;
pub mod soc;
pub mod srvpm; pub mod srvpm;
pub mod sslc;
pub mod uds;
pub mod y2r; pub mod y2r;

67
ctru-sys/src/services/mvd.rs

@ -1,67 +0,0 @@
use ::Result;
#[derive(Clone, Copy)]
#[repr(C)]
pub enum MVDSTD_Mode {
MVDMODE_COLORFORMATCONV = 0,
MVDMODE_VIDEOPROCESSING = 1,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub enum MVDSTD_InputFormat {
MVD_INPUT_YUYV422 = 65537,
MVD_INPUT_H264 = 131073,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub enum MVDSTD_OutputFormat { MVD_OUTPUT_RGB565 = 262146, }
#[repr(C)]
#[derive(Copy)]
pub struct MVDSTD_Config {
pub input_type: MVDSTD_InputFormat,
pub unk_x04: u32,
pub unk_x08: u32,
pub inwidth: u32,
pub inheight: u32,
pub physaddr_colorconv_indata: u32,
pub unk_x18: [u32; 10usize],
pub flag_x40: u32,
pub unk_x44: u32,
pub unk_x48: u32,
pub outheight0: u32,
pub outwidth0: u32,
pub unk_x54: u32,
pub output_type: MVDSTD_OutputFormat,
pub outwidth1: u32,
pub outheight1: u32,
pub physaddr_outdata0: u32,
pub physaddr_outdata1_colorconv: u32,
pub unk_x6c: [u32; 44usize],
}
impl ::core::clone::Clone for MVDSTD_Config {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for MVDSTD_Config {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" {
pub fn mvdstdInit(mode: MVDSTD_Mode, input_type: MVDSTD_InputFormat,
output_type: MVDSTD_OutputFormat, size: u32) -> Result;
pub fn mvdstdExit();
pub fn mvdstdGenerateDefaultConfig(config: *mut MVDSTD_Config,
input_width: u32, input_height: u32,
output_width: u32,
output_height: u32,
vaddr_colorconv_indata: *mut u32,
vaddr_outdata0: *mut u32,
vaddr_outdata1_colorconv: *mut u32);
pub fn mvdstdProcessFrame(config: *mut MVDSTD_Config,
h264_vaddr_inframe: *mut u32,
h264_inframesize: u32, h264_frameid: u32)
-> Result;
pub fn MVDSTD_SetConfig(config: *mut MVDSTD_Config) -> Result;
}

23
ctru-sys/src/services/ndm.rs

@ -0,0 +1,23 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum NDM_ExclusiveState {
EXCLUSIVE_STATE_NONE = 0,
EXCLUSIVE_STATE_INFRASTRUCTURE = 1,
EXCLUSIVE_STATE_LOCAL_COMMUNICATIONS = 2,
EXCLUSIVE_STATE_STREETPASS = 3,
EXCLUSIVE_STATE_STREETPASS_DATA = 4,
}
extern "C" {
pub fn ndmuInit() -> Result;
pub fn ndmuExit();
pub fn ndmuEnterExclusiveState(state: NDM_ExclusiveState) -> Result;
pub fn ndmuLeaveExclusiveState() -> Result;
}
use ::types::*;

53
ctru-sys/src/services/news.rs

@ -1,11 +1,52 @@
use ::Result; /* automatically generated by rust-bindgen */
use ::libc::c_void;
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct NotificationHeader {
pub dataSet: u8,
pub unread: u8,
pub enableJPEG: u8,
pub isSpotPass: u8,
pub isOptedOut: u8,
pub unkData: [u8_; 3usize],
pub processID: u64_,
pub unkData2: [u8_; 8usize],
pub jumpParam: u64_,
pub unkData3: [u8_; 8usize],
pub time: u64_,
pub title: [u16_; 32usize],
}
impl ::core::default::Default for NotificationHeader {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" { extern "C" {
pub fn newsInit() -> Result; pub fn newsInit() -> Result;
pub fn newsExit(); pub fn newsExit();
pub fn NEWS_AddNotification(title: *const u16, titleLength: u32, pub fn NEWS_AddNotification(title: *const u16_, titleLength: u32_,
message: *const u16, messageLength: u32, message: *const u16_, messageLength: u32_,
imageData: *const c_void, imageData: *const ::libc::c_void,
imageSize: u32, jpeg: u8) -> Result; imageSize: u32_, jpeg: u8) -> Result;
pub fn NEWS_GetTotalNotifications(num: *mut u32_) -> Result;
pub fn NEWS_SetNotificationHeader(news_id: u32_,
header: *const NotificationHeader)
-> Result;
pub fn NEWS_GetNotificationHeader(news_id: u32_,
header: *mut NotificationHeader)
-> Result;
pub fn NEWS_SetNotificationMessage(news_id: u32_, message: *const u16_,
size: u32_) -> Result;
pub fn NEWS_GetNotificationMessage(news_id: u32_, message: *mut u16_,
size: *mut u32_) -> Result;
pub fn NEWS_SetNotificationImage(news_id: u32_,
buffer: *const ::libc::c_void,
size: u32_) -> Result;
pub fn NEWS_GetNotificationImage(news_id: u32_,
buffer: *mut ::libc::c_void,
size: *mut u32_) -> Result;
} }
use ::types::*;

127
ctru-sys/src/services/nfc.rs

@ -0,0 +1,127 @@
/* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum NFC_OpType { NFC_OpType_1 = 1, NFC_OpType_NFCTag = 2, }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum NFC_TagState {
NFC_TagState_Uninitialized = 0,
NFC_TagState_ScanningStopped = 1,
NFC_TagState_Scanning = 2,
NFC_TagState_InRange = 3,
NFC_TagState_OutOfRange = 4,
NFC_TagState_DataReady = 5,
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum Enum_Unnamed1 {
NFC_amiiboFlag_Setup = 16,
NFC_amiiboFlag_AppDataSetup = 32,
}
#[repr(C)]
#[derive(Copy)]
pub struct NFC_TagInfo {
pub id_offset_size: u16_,
pub unk_x2: u8_,
pub unk_x3: u8_,
pub id: [u8_; 40usize],
}
impl ::core::clone::Clone for NFC_TagInfo {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for NFC_TagInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy)]
pub struct NFC_AmiiboSettings {
pub mii: [u8_; 96usize],
pub nickname: [u16_; 11usize],
pub flags: u8_,
pub countrycodeid: u8_,
pub setupdate_year: u16_,
pub setupdate_month: u8_,
pub setupdate_day: u8_,
pub unk_x7c: [u8_; 44usize],
}
impl ::core::clone::Clone for NFC_AmiiboSettings {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for NFC_AmiiboSettings {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy)]
pub struct NFC_AmiiboConfig {
pub lastwritedate_year: u16_,
pub lastwritedate_month: u8_,
pub lastwritedate_day: u8_,
pub write_counter: u16_,
pub val_x6: u16_,
pub val_x8: u8_,
pub val_x9: u8_,
pub val_xa: u16_,
pub val_xc: u8_,
pub pagex4_byte3: u8_,
pub appdata_size: u8_,
pub zeros: [u8_; 49usize],
}
impl ::core::clone::Clone for NFC_AmiiboConfig {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for NFC_AmiiboConfig {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy)]
pub struct NFC_AppDataInitStruct {
pub data_x0: [u8_; 12usize],
pub data_xc: [u8_; 48usize],
}
impl ::core::clone::Clone for NFC_AppDataInitStruct {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for NFC_AppDataInitStruct {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct NFC_AppDataWriteStruct {
pub id: [u8_; 10usize],
pub id_size: u8_,
pub unused_xb: [u8_; 21usize],
}
impl ::core::default::Default for NFC_AppDataWriteStruct {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" {
pub fn nfcInit(type_: NFC_OpType) -> Result;
pub fn nfcExit();
pub fn nfcGetSessionHandle() -> Handle;
pub fn nfcStartScanning(inval: u16_) -> Result;
pub fn nfcStopScanning();
pub fn nfcLoadAmiiboData() -> Result;
pub fn nfcResetTagScanState() -> Result;
pub fn nfcUpdateStoredAmiiboData() -> Result;
pub fn nfcGetTagState(state: *mut NFC_TagState) -> Result;
pub fn nfcGetTagInfo(out: *mut NFC_TagInfo) -> Result;
pub fn nfcOpenAppData(amiibo_appid: u32_) -> Result;
pub fn nfcInitializeWriteAppData(amiibo_appid: u32_,
buf: *const ::libc::c_void, size: ::libc::size_t)
-> Result;
pub fn nfcReadAppData(buf: *mut ::libc::c_void, size: ::libc::size_t) -> Result;
pub fn nfcWriteAppData(buf: *const ::libc::c_void, size: ::libc::size_t,
taginfo: *mut NFC_TagInfo) -> Result;
pub fn nfcGetAmiiboSettings(out: *mut NFC_AmiiboSettings) -> Result;
pub fn nfcGetAmiiboConfig(out: *mut NFC_AmiiboConfig) -> Result;
}
use ::types::*;

16
ctru-sys/src/services/ns.rs

@ -1,9 +1,17 @@
use ::Result; /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub fn nsInit() -> Result; pub fn nsInit() -> Result;
pub fn nsExit(); pub fn nsExit();
pub fn NS_LaunchTitle(titleid: u64, launch_flags: u32, procid: *mut u32) -> Result; pub fn NS_LaunchFIRM(titleid: u64_) -> Result;
pub fn NS_RebootToTitle(mediatype: u8, titleid: u64) -> Result; pub fn NS_LaunchTitle(titleid: u64_, launch_flags: u32_,
procid: *mut u32_) -> Result;
pub fn NS_LaunchApplicationFIRM(titleid: u64_, flags: u32_) -> Result;
pub fn NS_RebootToTitle(mediatype: u8_, titleid: u64_) -> Result;
pub fn NS_TerminateProcessTID(titleid: u64_) -> Result;
} }
use ::types::*;

31
ctru-sys/src/services/pm.rs

@ -1,24 +1,19 @@
use ::{Handle, Result}; /* automatically generated by rust-bindgen */
use ::libc::c_void;
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
extern "C" { extern "C" {
pub fn pmInit() -> Result; pub fn pmInit() -> Result;
pub fn pmExit(); pub fn pmExit();
pub fn PM_LaunchTitle(mediatype: u8, titleid: u64, launch_flags: u32) pub fn PM_LaunchTitle(mediatype: u8_, titleid: u64_, launch_flags: u32_)
-> Result; -> Result;
pub fn PM_GetTitleExheaderFlags(mediatype: u8, titleid: u64, pub fn PM_GetTitleExheaderFlags(mediatype: u8_, titleid: u64_,
out: *mut u8) -> Result; out: *mut u8_) -> Result;
pub fn PM_SetFIRMLaunchParams(size: u32, _in: *mut u8) -> Result; pub fn PM_SetFIRMLaunchParams(size: u32_, in_: *mut u8_) -> Result;
pub fn PM_GetFIRMLaunchParams(size: u32, out: *mut u8) -> Result; pub fn PM_GetFIRMLaunchParams(size: u32_, out: *mut u8_) -> Result;
pub fn PM_LaunchFIRMSetParams(firm_titleid_low: u32, size: u32, pub fn PM_LaunchFIRMSetParams(firm_titleid_low: u32_, size: u32_,
_in: *mut u8) -> Result; in_: *mut u8_) -> Result;
pub fn srvPmInit() -> Result;
pub fn srvPmExit();
pub fn SRVPM_PublishToProcess(notificationId: u32, process: Handle)
-> Result;
pub fn SRVPM_PublishToAll(notificationId: u32) -> Result;
pub fn SRVPM_RegisterProcess(procid: u32, count: u32,
serviceaccesscontrol: c_void) -> Result;
pub fn SRVPM_UnregisterProcess(procid: u32) -> Result;
} }
use ::types::*;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save