<commit_before>extern crate bgfx;
extern crate common;
extern crate time;

use time::PreciseTime;

#[repr(packed)]
struct PosColorVertex {
    _x: f32,
    _y: f32,
    _z: f32,
    _abgr: u32,
}

impl PosColorVertex {
    fn build_decl() -> bgfx::VertexDecl {
        let decl = bgfx::VertexDecl::new(None)
                       .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float, None, None)
                       .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::UInt8, Some(true), None)
                       .end();

        decl
    }
}

//#[rustfmt_skip]
static CUBE_VERTICES: [PosColorVertex; 8] = [
    PosColorVertex { _x: -1.0, _y:  1.0, _z:  1.0, _abgr: 0xff000000 },
    PosColorVertex { _x:  1.0, _y:  1.0, _z:  1.0, _abgr: 0xff0000ff },
    PosColorVertex { _x: -1.0, _y: -1.0, _z:  1.0, _abgr: 0xff00ff00 },
    PosColorVertex { _x:  1.0, _y: -1.0, _z:  1.0, _abgr: 0xff00ffff },
    PosColorVertex { _x: -1.0, _y:  1.0, _z: -1.0, _abgr: 0xffff0000 },
    PosColorVertex { _x:  1.0, _y:  1.0, _z: -1.0, _abgr: 0xffff00ff },
    PosColorVertex { _x: -1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffff00 },
    PosColorVertex { _x:  1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffffff },
];

//#[rustfmt_skip]
static CUBE_INDICES: [u32; 36] = [
    0, 1, 2, // 0
    1, 3, 2,
    4, 6, 5, // 2
    5, 6, 7,
    0, 2, 4, // 4
    4, 2, 6,
    1, 5, 3, // 6
    5, 7, 3,
    0, 4, 1, // 8
    4, 5, 1,
    2, 3, 6, // 10
    6, 3, 7,
];

struct Cubes<'a> {
    bgfx: &'a bgfx::MainContext,
    example: &'a common::Example,
    width: u16,
    height: u16,
    debug: bgfx::DebugFlags,
    reset: bgfx::ResetFlags,
    vbh: bgfx::VertexBuffer<'a>,
    ibh: bgfx::IndexBuffer<'a>,
    program: bgfx::Program<'a>,
    time: time::PreciseTime,
    last: time::PreciseTime,
}

impl<'a> Cubes<'a> {
    pub fn init(bgfx: &'a mut bgfx::MainContext, example: &'a common::Example) -> Cubes<'a> {
        let width: u16 = 1280;
        let height: u16 = 720;
        let debug = bgfx::DEBUG_TEXT;
        let reset = bgfx::RESET_VSYNC;

        bgfx.init(common::get_renderer_type(), None, None);
        bgfx.reset(width, height, reset);

        // Enable debug text.
        bgfx.set_debug(debug);

        // Set view 0 clear state.
        let clear_flags = bgfx::CLEAR_COLOR | bgfx::CLEAR_DEPTH;
        bgfx.set_view_clear(0, clear_flags, 0x303030ff, 1.0_f32, 0);

        // Create vertex stream declaration
        let decl = PosColorVertex::build_decl();

        // Create static vertex buffer.
        let vbh = bgfx::VertexBuffer::new(bgfx,
                                          bgfx::Memory::reference(&CUBE_VERTICES),
                                          &decl,
                                          bgfx::BUFFER_NONE);

        // Create static index buffer.
        let ibh = bgfx::IndexBuffer::new(bgfx,
                                         bgfx::Memory::reference(&CUBE_INDICES),
                                         bgfx::BUFFER_NONE);

        // Create program from shaders.
        let program = common::load_program(bgfx, "vs_cubes", "fs_cubes");

        let now = PreciseTime::now();

        Cubes {
            bgfx: bgfx,
            example: example,
            width: 1280,
            height: 720,
            debug: bgfx::DEBUG_TEXT,
            reset: bgfx::RESET_VSYNC,
            vbh: vbh,
            ibh: ibh,
            program: program,
            time: now,
            last: now,
        }
    }

    pub fn shutdown(&mut self) {
        // We don't really need to do anything here, the objects will clean themselves up once they
        // go out of scope. This function is really only here to keep the examples similar in
        // structure to the C++ examples.
    }

    pub fn update(&mut self) -> bool {
        if !self.example.handle_events() {
            let now = PreciseTime::now();
            let frame_time = self.last.to(now);
            self.last = now;

            let time = (self.time.to(now).num_microseconds().unwrap() as f64) / 1_000_000.0_f64;

            // Use debug font to print information about this example.
            let frame_info = format!("Frame: {:7.3}[ms]", frame_time.num_milliseconds());
            self.bgfx.dbg_text_clear(None, None);
            self.bgfx.dbg_text_print(0, 1, 0x4f, "bgfx/examples/01-cubes");
            self.bgfx.dbg_text_print(0, 2, 0x6f, "Description: Rendering simple static mesh.");
            self.bgfx.dbg_text_print(0, 3, 0x0f, &frame_info);

            let at: [f32; 3] = [0.0, 0.0, 0.0];
            let eye: [f32; 3] = [0.0, 0.0, -35.0];

            // TODO: Support for HMD rendering

            // Set view and projection matrix for view 0.
            let aspect = (self.width as f32) / (self.height as f32);
            let view = bgfx::mtx_look_at(&eye, &at);
            let proj = bgfx::mtx_proj(60.0, aspect, 0.1, 100.0);
            self.bgfx.set_view_transform(0, &view, &proj);

            // Set view 0 default viewport.
            self.bgfx.set_view_rect(0, 0, 0, self.width, self.height);

            // This dummy draw call is here to make sure that view 0 is cleared if no other draw
            // calls are submitted to view 0.
            self.bgfx.touch(0);

            // Submit 11x11 cubes
            for yy in 0..11 {
                for xx in 0..11 {
                    let mut mtx = bgfx::mtx_rotate_xy((time / 0.21) as f32, (time / 0.37) as f32);
                    mtx[12] = -15.0 + (xx as f32) * 3.0;
                    mtx[13] = -15.0 + (yy as f32) * 3.0;
                    mtx[14] = 0.0;

                    // Set model matrix for rendering.
                    self.bgfx.set_transform(&mtx);

                    // Set vertex and index buffer.
                    self.bgfx.set_vertex_buffer(&self.vbh);
                    self.bgfx.set_index_buffer(&self.ibh);

                    // Set render states.
                    self.bgfx.set_state(bgfx::State::new(), None);

                    // Submit primitive for rendering to view 0.
                    self.bgfx.submit(0, &self.program);
                }
            }

            // Advance to next frame. Rendering thread will be kicked to process submitted
            // rendering primitives.
            self.bgfx.frame();

            true
        } else {
            false
        }
    }
}

fn example(bgfx: &mut bgfx::MainContext, example: &common::Example) {
    let mut cubes = Cubes::init(bgfx, example);
    while cubes.update() {}
    cubes.shutdown();
}

fn main() {
    common::run_example(1024, 768, example);
}
<commit_msg>Found the problem with the index buffer in cubes..<commit_after>extern crate bgfx;
extern crate common;
extern crate time;

use time::PreciseTime;

#[repr(packed)]
struct PosColorVertex {
    _x: f32,
    _y: f32,
    _z: f32,
    _abgr: u32,
}

impl PosColorVertex {
    fn build_decl() -> bgfx::VertexDecl {
        let decl = bgfx::VertexDecl::new(None)
                       .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float, None, None)
                       .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::UInt8, Some(true), None)
                       .end();

        decl
    }
}

//#[rustfmt_skip]
static CUBE_VERTICES: [PosColorVertex; 8] = [
    PosColorVertex { _x: -1.0, _y:  1.0, _z:  1.0, _abgr: 0xff000000 },
    PosColorVertex { _x:  1.0, _y:  1.0, _z:  1.0, _abgr: 0xff0000ff },
    PosColorVertex { _x: -1.0, _y: -1.0, _z:  1.0, _abgr: 0xff00ff00 },
    PosColorVertex { _x:  1.0, _y: -1.0, _z:  1.0, _abgr: 0xff00ffff },
    PosColorVertex { _x: -1.0, _y:  1.0, _z: -1.0, _abgr: 0xffff0000 },
    PosColorVertex { _x:  1.0, _y:  1.0, _z: -1.0, _abgr: 0xffff00ff },
    PosColorVertex { _x: -1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffff00 },
    PosColorVertex { _x:  1.0, _y: -1.0, _z: -1.0, _abgr: 0xffffffff },
];

//#[rustfmt_skip]
static CUBE_INDICES: [u16; 36] = [
    0, 1, 2, // 0
    1, 3, 2,
    4, 6, 5, // 2
    5, 6, 7,
    0, 2, 4, // 4
    4, 2, 6,
    1, 5, 3, // 6
    5, 7, 3,
    0, 4, 1, // 8
    4, 5, 1,
    2, 3, 6, // 10
    6, 3, 7,
];

struct Cubes<'a> {
    bgfx: &'a bgfx::MainContext,
    example: &'a common::Example,
    width: u16,
    height: u16,
    debug: bgfx::DebugFlags,
    reset: bgfx::ResetFlags,
    vbh: bgfx::VertexBuffer<'a>,
    ibh: bgfx::IndexBuffer<'a>,
    program: bgfx::Program<'a>,
    time: time::PreciseTime,
    last: time::PreciseTime,
}

impl<'a> Cubes<'a> {
    pub fn init(bgfx: &'a mut bgfx::MainContext, example: &'a common::Example) -> Cubes<'a> {
        let width: u16 = 1280;
        let height: u16 = 720;
        let debug = bgfx::DEBUG_TEXT;
        let reset = bgfx::RESET_VSYNC;

        bgfx.init(common::get_renderer_type(), None, None);
        bgfx.reset(width, height, reset);

        // Enable debug text.
        bgfx.set_debug(debug);

        // Set view 0 clear state.
        let clear_flags = bgfx::CLEAR_COLOR | bgfx::CLEAR_DEPTH;
        bgfx.set_view_clear(0, clear_flags, 0x303030ff, 1.0_f32, 0);

        // Create vertex stream declaration
        let decl = PosColorVertex::build_decl();

        // Create static vertex buffer.
        let vbh = bgfx::VertexBuffer::new(bgfx,
                                          bgfx::Memory::reference(&CUBE_VERTICES),
                                          &decl,
                                          bgfx::BUFFER_NONE);

        // Create static index buffer.
        let ibh = bgfx::IndexBuffer::new(bgfx,
                                         bgfx::Memory::reference(&CUBE_INDICES),
                                         bgfx::BUFFER_NONE);

        // Create program from shaders.
        let program = common::load_program(bgfx, "vs_cubes", "fs_cubes");

        let now = PreciseTime::now();

        Cubes {
            bgfx: bgfx,
            example: example,
            width: 1280,
            height: 720,
            debug: bgfx::DEBUG_TEXT,
            reset: bgfx::RESET_VSYNC,
            vbh: vbh,
            ibh: ibh,
            program: program,
            time: now,
            last: now,
        }
    }

    pub fn shutdown(&mut self) {
        // We don't really need to do anything here, the objects will clean themselves up once they
        // go out of scope. This function is really only here to keep the examples similar in
        // structure to the C++ examples.
    }

    pub fn update(&mut self) -> bool {
        if !self.example.handle_events() {
            let now = PreciseTime::now();
            let frame_time = self.last.to(now);
            self.last = now;

            let time = (self.time.to(now).num_microseconds().unwrap() as f64) / 1_000_000.0_f64;

            // Use debug font to print information about this example.
            let frame_info = format!("Frame: {:7.3}[ms]", frame_time.num_milliseconds());
            self.bgfx.dbg_text_clear(None, None);
            self.bgfx.dbg_text_print(0, 1, 0x4f, "bgfx/examples/01-cubes");
            self.bgfx.dbg_text_print(0, 2, 0x6f, "Description: Rendering simple static mesh.");
            self.bgfx.dbg_text_print(0, 3, 0x0f, &frame_info);

            let at: [f32; 3] = [0.0, 0.0, 0.0];
            let eye: [f32; 3] = [0.0, 0.0, -35.0];

            // TODO: Support for HMD rendering

            // Set view and projection matrix for view 0.
            let aspect = (self.width as f32) / (self.height as f32);
            let view = bgfx::mtx_look_at(&eye, &at);
            let proj = bgfx::mtx_proj(60.0, aspect, 0.1, 100.0);
            self.bgfx.set_view_transform(0, &view, &proj);

            // Set view 0 default viewport.
            self.bgfx.set_view_rect(0, 0, 0, self.width, self.height);

            // This dummy draw call is here to make sure that view 0 is cleared if no other draw
            // calls are submitted to view 0.
            self.bgfx.touch(0);

            // Submit 11x11 cubes
            for yy in 0..11 {
                for xx in 0..11 {
                    let mut mtx = bgfx::mtx_rotate_xy((time / 0.21) as f32, (time / 0.37) as f32);
                    mtx[12] = -15.0 + (xx as f32) * 3.0;
                    mtx[13] = -15.0 + (yy as f32) * 3.0;
                    mtx[14] = 0.0;

                    // Set model matrix for rendering.
                    self.bgfx.set_transform(&mtx);

                    // Set vertex and index buffer.
                    self.bgfx.set_vertex_buffer(&self.vbh);
                    self.bgfx.set_index_buffer(&self.ibh);

                    // Set render states.
                    self.bgfx.set_state(bgfx::State::new(), None);

                    // Submit primitive for rendering to view 0.
                    self.bgfx.submit(0, &self.program);
                }
            }

            // Advance to next frame. Rendering thread will be kicked to process submitted
            // rendering primitives.
            self.bgfx.frame();

            true
        } else {
            false
        }
    }
}

fn example(bgfx: &mut bgfx::MainContext, example: &common::Example) {
    let mut cubes = Cubes::init(bgfx, example);
    while cubes.update() {}
    cubes.shutdown();
}

fn main() {
    common::run_example(1024, 768, example);
}
<|endoftext|>


<commit_before>use bytecode::{Chunk, ChunkID, Inst, StrID};
use libc;
use std::mem;
use value::{GC, Ref};

pub struct StateDiff<'gc> {
  pub jump: Jump,
  pub return_: bool,
  pub call: Option<(Ref<'gc>, Ref<'gc>)>,
}

pub enum Jump {
  Absolute(usize),
  Relative(isize),
}

pub unsafe fn interpret<'str, 'gc, 'chunk, GetChunk, GetStr>(
  gc: &'gc GC,
  get_str: &GetStr,
  get_chunk: &GetChunk,
  stack: &mut Vec<Ref<'gc>>,
  locals: &mut [Ref<'gc>],
  inst: &Inst,
) -> StateDiff<'gc>
  where
    GetStr: Fn(StrID) -> &'str str,
    GetChunk: Fn(ChunkID) -> &'chunk Chunk {
  let mut state_diff = StateDiff{
    jump: Jump::Relative(1),
    return_: false,
    call: None,
  };
  match *inst {
    Inst::NoOp => (),

    Inst::Call => {
      let argument = stack.pop().unwrap();
      let callee = stack.pop().unwrap();
      state_diff.call = Some((callee, argument));
    },
    Inst::Return => state_diff.return_ = true,

    Inst::Pop => {
      stack.pop();
    },

    Inst::GetLocal(offset) => {
      let value = locals[offset].clone();
      stack.push(value);
    },

    Inst::New(ptr_count, aux_count) => {
      let new = gc.alloc(ptr_count, aux_count);
      for offset in (0 .. ptr_count).rev() {
        let ptr = stack.pop().unwrap();
        new.set_ptr(offset, &ptr);
      }
      stack.push(new);
    },
    Inst::NewI32(value) => {
      let new = gc.alloc(0, 4);
      *new.aux_i32() = value;
      stack.push(new);
    },
    Inst::NewStr(str_id) => {
      let value = get_str(str_id);
      let new = gc.alloc(0, value.len());
      new.aux().copy_from_slice(value.as_bytes());
      stack.push(new);
    },
    Inst::NewFunc(chunk_id) => {
      let chunk = get_chunk(chunk_id);
      let aux_count = mem::size_of::<usize>();
      let new = gc.alloc(chunk.captures, aux_count);
      for offset in (0 .. chunk.captures).rev() {
        let ptr = stack.pop().unwrap();
        new.set_ptr(offset, &ptr);
      }
      *new.aux_usize() = chunk_id.0;
      stack.push(new);
    },

    Inst::Write => {
      let handle = stack.pop().unwrap();
      let bytes = stack.pop().unwrap();

      let status =
        libc::write(
          *handle.aux_i32(),
          mem::transmute(bytes.aux().as_ptr()),
          bytes.aux().len(),
        ) as i32;

      let result = gc.alloc(0, 4);
      *result.aux_i32() = status;
      stack.push(result);
    },
  }
  state_diff
}
<commit_msg>Clean up stuff<commit_after>use bytecode::{Chunk, ChunkID, Inst, StrID};
use libc;
use std::mem;
use value::{GC, Ref};

pub struct StateDiff<'gc> {
  pub jump: Jump,
  pub return_: bool,
  pub call: Option<(Ref<'gc>, Ref<'gc>)>,
}

pub enum Jump {
  Absolute(usize),
  Relative(isize),
}

pub unsafe fn interpret<'str, 'gc, 'chunk, GetChunk, GetStr>(
  gc: &'gc GC,
  get_str: &GetStr,
  get_chunk: &GetChunk,
  stack: &mut Vec<Ref<'gc>>,
  locals: &mut [Ref<'gc>],
  inst: &Inst,
) -> StateDiff<'gc>
  where
    GetStr: Fn(StrID) -> &'str str,
    GetChunk: Fn(ChunkID) -> &'chunk Chunk {
  let mut state_diff = StateDiff{
    jump: Jump::Relative(1),
    return_: false,
    call: None,
  };
  match *inst {
    Inst::NoOp => (),

    Inst::Call => {
      let argument = stack.pop().unwrap();
      let callee = stack.pop().unwrap();
      state_diff.call = Some((callee, argument));
    },
    Inst::Return =>
      state_diff.return_ = true,

    Inst::Pop =>
      drop(stack.pop()),

    Inst::GetLocal(offset) =>
      stack.push(locals[offset].clone()),

    Inst::New(ptr_count, aux_count) => {
      let new = gc.alloc(ptr_count, aux_count);
      for offset in (0 .. ptr_count).rev() {
        let ptr = stack.pop().unwrap();
        new.set_ptr(offset, &ptr);
      }
      stack.push(new);
    },
    Inst::NewI32(value) => {
      let new = gc.alloc(0, 4);
      *new.aux_i32() = value;
      stack.push(new);
    },
    Inst::NewStr(str_id) => {
      let value = get_str(str_id);
      let new = gc.alloc(0, value.len());
      new.aux().copy_from_slice(value.as_bytes());
      stack.push(new);
    },
    Inst::NewFunc(chunk_id) => {
      let chunk = get_chunk(chunk_id);
      let new = gc.alloc(chunk.captures, mem::size_of::<usize>());
      for offset in (0 .. chunk.captures).rev() {
        let ptr = stack.pop().unwrap();
        new.set_ptr(offset, &ptr);
      }
      *new.aux_usize() = chunk_id.0;
      stack.push(new);
    },

    Inst::Write => {
      let handle = stack.pop().unwrap();
      let bytes = stack.pop().unwrap();

      let status =
        libc::write(
          *handle.aux_i32(),
          mem::transmute(bytes.aux().as_ptr()),
          bytes.aux().len(),
        ) as i32;

      let result = gc.alloc(0, 4);
      *result.aux_i32() = status;
      stack.push(result);
    },
  }
  state_diff
}
<|endoftext|>


<commit_before>use hash_map::HashMap;
use std::borrow::Borrow;
use std::hash::{BuildHasher, Hash};

use FailedAllocationError;

#[cfg(target_pointer_width = "32")]
const CANARY: usize = 0x42cafe99;
#[cfg(target_pointer_width = "64")]
const CANARY: usize = 0x42cafe9942cafe99;

#[derive(Clone, Debug)]
enum JournalEntry {
    Insert(usize),
    GOIW(usize),
    Remove(usize),
    DidClear(usize),
}

#[derive(Clone, Debug)]
pub struct DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    map: HashMap<K, (usize, V), S>,
    journal: Vec<JournalEntry>,
    readonly: bool,
}

impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    #[inline(always)]
    pub fn inner(&self) -> &HashMap<K, (usize, V), S> {
        &self.map
    }

    #[inline(never)]
    pub fn begin_mutation(&mut self) {
        self.map.verify();
        assert!(self.readonly);
        self.readonly = false;
        self.verify();
    }

    #[inline(never)]
    pub fn end_mutation(&mut self) {
        self.map.verify();
        assert!(!self.readonly);
        self.readonly = true;
        self.verify();
    }

    fn verify(&self) {
        let mut position = 0;
        let mut bad_canary: Option<(usize, *const usize)> = None;
        for (_,v) in self.map.iter() {
            let canary_ref = &v.0;
            if *canary_ref == CANARY {
                position += 1;
                continue;
            }
            bad_canary = Some((*canary_ref, canary_ref));
        }
        if let Some(c) = bad_canary {
            self.report_corruption(c.0, c.1, position);
        }
    }

    #[inline(always)]
    pub fn with_hasher(hash_builder: S) -> Self {
        Self {
            map: HashMap::<K, (usize, V), S>::with_hasher(hash_builder),
            journal: Vec::new(),
            readonly: true,
        }
    }

    #[inline(always)]
    pub fn len(&self) -> usize {
        self.map.len()
    }

    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }

    #[inline(always)]
    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        self.map.contains_key(k)
    }

    #[inline(always)]
    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        self.map.get(k).map(|v| &v.1)
    }

    #[inline(always)]
    pub fn try_get_or_insert_with<F: FnOnce() -> V>(
        &mut self,
        key: K,
        default: F
    ) -> Result<&mut V, FailedAllocationError> {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::GOIW(self.map.make_hash(&key).inspect()));
        let entry = self.map.try_entry(key)?;
        Ok(&mut entry.or_insert_with(|| (CANARY, default())).1)
    }

    #[inline(always)]
    pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::Insert(self.map.make_hash(&k).inspect()));
        let old = self.map.try_insert(k, (CANARY, v))?;
        Ok(old.map(|x| x.1))
    }

    #[inline(always)]
    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::Remove(self.map.make_hash(k).inspect()));
        self.map.remove(k).map(|x| x.1)
    }

    #[inline(always)]
    pub fn clear(&mut self) where K: 'static, V: 'static  {
        // We handle scoped mutations for the caller here, since callsites that
        // invoke clear() don't benefit from the coalescing we do around insertion.
        self.begin_mutation();
        self.journal.clear();
        self.journal.push(JournalEntry::DidClear(self.map.raw_capacity()));
        self.map.clear();
        self.end_mutation();
    }

    #[inline(never)]
    fn report_corruption(
        &self,
        canary: usize,
        canary_addr: *const usize,
        position: usize
    ) {
        use ::std::ffi::CString;
        let key = b"HashMapJournal\0";
        let value = CString::new(format!("{:?}", self.journal)).unwrap();
        unsafe {
            Gecko_AnnotateCrashReport(
                key.as_ptr() as *const ::std::os::raw::c_char,
                value.as_ptr(),
            );
        }
        panic!(
            "HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})",
            self.map.len(),
            self.map.raw_capacity(),
            ::std::mem::size_of::<(K, (usize, V))>(),
            canary,
            position,
            self.map.raw_buffer(),
            canary_addr,
            self.journal.len(),
        );
    }
}

impl<K, V, S> PartialEq for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          V: PartialEq,
          S: BuildHasher
{
    fn eq(&self, other: &Self) -> bool {
        self.map.eq(&other.map)
    }
}

impl<K, V, S> Eq for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          V: Eq,
          S: BuildHasher
{
}

impl<K, V, S> Default for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher + Default
{
    fn default() -> Self {
        Self {
            map: HashMap::default(),
            journal: Vec::new(),
            readonly: true,
        }
    }
}

impl<K: Hash + Eq, V, S: BuildHasher> Drop for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    fn drop(&mut self) {
        self.map.verify();
        debug_assert!(self.readonly, "Dropped while mutating");
        self.verify();
    }
}

extern "C" {
    pub fn Gecko_AnnotateCrashReport(key_str: *const ::std::os::raw::c_char,
                                     value_str: *const ::std::os::raw::c_char);
}
<commit_msg>Revert "Verify in DiagnosticHashMap::drop."<commit_after>use hash_map::HashMap;
use std::borrow::Borrow;
use std::hash::{BuildHasher, Hash};

use FailedAllocationError;

#[cfg(target_pointer_width = "32")]
const CANARY: usize = 0x42cafe99;
#[cfg(target_pointer_width = "64")]
const CANARY: usize = 0x42cafe9942cafe99;

#[derive(Clone, Debug)]
enum JournalEntry {
    Insert(usize),
    GOIW(usize),
    Remove(usize),
    DidClear(usize),
}

#[derive(Clone, Debug)]
pub struct DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    map: HashMap<K, (usize, V), S>,
    journal: Vec<JournalEntry>,
    readonly: bool,
}

impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    #[inline(always)]
    pub fn inner(&self) -> &HashMap<K, (usize, V), S> {
        &self.map
    }

    #[inline(never)]
    pub fn begin_mutation(&mut self) {
        self.map.verify();
        assert!(self.readonly);
        self.readonly = false;
        self.verify();
    }

    #[inline(never)]
    pub fn end_mutation(&mut self) {
        self.map.verify();
        assert!(!self.readonly);
        self.readonly = true;
        self.verify();
    }

    fn verify(&self) {
        let mut position = 0;
        let mut bad_canary: Option<(usize, *const usize)> = None;
        for (_,v) in self.map.iter() {
            let canary_ref = &v.0;
            if *canary_ref == CANARY {
                position += 1;
                continue;
            }
            bad_canary = Some((*canary_ref, canary_ref));
        }
        if let Some(c) = bad_canary {
            self.report_corruption(c.0, c.1, position);
        }
    }

    #[inline(always)]
    pub fn with_hasher(hash_builder: S) -> Self {
        Self {
            map: HashMap::<K, (usize, V), S>::with_hasher(hash_builder),
            journal: Vec::new(),
            readonly: true,
        }
    }

    #[inline(always)]
    pub fn len(&self) -> usize {
        self.map.len()
    }

    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }

    #[inline(always)]
    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        self.map.contains_key(k)
    }

    #[inline(always)]
    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        self.map.get(k).map(|v| &v.1)
    }

    #[inline(always)]
    pub fn try_get_or_insert_with<F: FnOnce() -> V>(
        &mut self,
        key: K,
        default: F
    ) -> Result<&mut V, FailedAllocationError> {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::GOIW(self.map.make_hash(&key).inspect()));
        let entry = self.map.try_entry(key)?;
        Ok(&mut entry.or_insert_with(|| (CANARY, default())).1)
    }

    #[inline(always)]
    pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::Insert(self.map.make_hash(&k).inspect()));
        let old = self.map.try_insert(k, (CANARY, v))?;
        Ok(old.map(|x| x.1))
    }

    #[inline(always)]
    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Hash + Eq
    {
        assert!(!self.readonly);
        self.journal.push(JournalEntry::Remove(self.map.make_hash(k).inspect()));
        self.map.remove(k).map(|x| x.1)
    }

    #[inline(always)]
    pub fn clear(&mut self) where K: 'static, V: 'static  {
        // We handle scoped mutations for the caller here, since callsites that
        // invoke clear() don't benefit from the coalescing we do around insertion.
        self.begin_mutation();
        self.journal.clear();
        self.journal.push(JournalEntry::DidClear(self.map.raw_capacity()));
        self.map.clear();
        self.end_mutation();
    }

    #[inline(never)]
    fn report_corruption(
        &self,
        canary: usize,
        canary_addr: *const usize,
        position: usize
    ) {
        use ::std::ffi::CString;
        let key = b"HashMapJournal\0";
        let value = CString::new(format!("{:?}", self.journal)).unwrap();
        unsafe {
            Gecko_AnnotateCrashReport(
                key.as_ptr() as *const ::std::os::raw::c_char,
                value.as_ptr(),
            );
        }
        panic!(
            "HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})",
            self.map.len(),
            self.map.raw_capacity(),
            ::std::mem::size_of::<(K, (usize, V))>(),
            canary,
            position,
            self.map.raw_buffer(),
            canary_addr,
            self.journal.len(),
        );
    }
}

impl<K, V, S> PartialEq for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          V: PartialEq,
          S: BuildHasher
{
    fn eq(&self, other: &Self) -> bool {
        self.map.eq(&other.map)
    }
}

impl<K, V, S> Eq for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          V: Eq,
          S: BuildHasher
{
}

impl<K, V, S> Default for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher + Default
{
    fn default() -> Self {
        Self {
            map: HashMap::default(),
            journal: Vec::new(),
            readonly: true,
        }
    }
}

impl<K: Hash + Eq, V, S: BuildHasher> Drop for DiagnosticHashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher
{
    fn drop(&mut self) {
        debug_assert!(self.readonly, "Dropped while mutating");
    }
}

extern "C" {
    pub fn Gecko_AnnotateCrashReport(key_str: *const ::std::os::raw::c_char,
                                     value_str: *const ::std::os::raw::c_char);
}
<|endoftext|>


<commit_before>#![feature(question_mark)]
#[macro_use]
extern crate rustfbp;
extern crate capnp;

component! {
    shells_lain_flow, contracts(list_command, file_desc)
    inputs(input: list_command),
    inputs_array(),
    outputs(output: file_desc),
    outputs_array(),
    option(),
    acc(),
    fn run(&mut self) -> Result<()> {
        let mut ip_input = self.ports.recv("input")?;
        let input_reader: list_command::Reader = ip_input.get_root()?;
        let mut cmds = input_reader.borrow().get_commands()?;
        let mut flow = String::from("");
        let mut args: Vec<String> = Vec::new();
        let mut cmd_count :usize = 0;
        let cmd_len :usize = cmds.iter().len();
        for cmd in cmds.iter() {
            let mut formatted_args = String::from("");
            let mut formatted_singles = String::from("singles=[");
            let singles_csv = cmd.get_singles()?
                .iter()
                .map(|O| {
                    match O {
                        Ok(x) => {let out = format!("\"{}\"", x); out},
                        Err(e) => String::from(""),
                    }
                }).collect::<Vec<_>>().join(",");
            formatted_singles.push_str(format!("{}]", singles_csv.as_str()).as_str());
            formatted_args.push_str(
                format!("'command:({0})' -> option {1}_{2}()"
                    , formatted_singles
                    , cmd.get_name()?
                    , cmd_count).as_str());
            args.push(formatted_args);
            if cmd_len == 1 { // only one command in the list
                flow.push_str(format!("{0}_{1}({0})", cmd.get_name()?, cmd_count).as_str());
                args.push(format!("'generic_text:(text=\"/2/1/\")' -> stdin {0}_{1}()", cmd.get_name()?, cmd_count));
            } else { // more than one command
                if cmd_len > 1 && cmd_count == 0 { // the first command of many in a list
                    flow.push_str(format!("{0}_{1}({0}) stdout -> ", cmd.get_name()?, cmd_count).as_str());
                    args.push(format!("'generic_text:(text=\"start\")' -> stdin {0}_{1}()", cmd.get_name()?, cmd_count));
                } else { // check if the last command or not
                    if (cmd_len - 1) == cmd_count { // last command
                        flow.push_str(format!("stdin {0}_{1}({0})", cmd.get_name()?, cmd_count).as_str());
                    } else { // not the first command, and not the last command
                        flow.push_str(format!("stdin {0}_{1}({0}) stdout -> ", cmd.get_name()?, cmd_count).as_str());
                    }
                }
            }
            cmd_count += 1;
        }
        println!("{:?}", flow);

        // Send start
        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_start("flowscript");
        }
        self.ports.send("output", new_ip)?;

        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_text(&flow.as_str());
        }
        self.ports.send("output", new_ip)?;

        for arg in args {
            println!("{:?}", arg);
            let mut new_ip = IP::new();
            {
                let mut ip = new_ip.init_root::<file_desc::Builder>();
                ip.set_text(&arg.as_str());
            }
            self.ports.send("output", new_ip)?;
        }

        // Send stop
        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_end("flowscript");
        }
        self.ports.send("output", new_ip)?;
        Ok(())
    }
}
<commit_msg>Problem: kvs not present in lain option code generation<commit_after>#![feature(question_mark)]
#[macro_use]
extern crate rustfbp;
extern crate capnp;

component! {
    shells_lain_flow, contracts(list_command, file_desc)
    inputs(input: list_command),
    inputs_array(),
    outputs(output: file_desc),
    outputs_array(),
    option(),
    acc(),
    fn run(&mut self) -> Result<()> {
        let mut ip_input = self.ports.recv("input")?;
        let input_reader: list_command::Reader = ip_input.get_root()?;
        let mut cmds = input_reader.borrow().get_commands()?;
        let mut flow = String::from("");
        let mut switches: Vec<String> = Vec::new();
        let mut cmd_count :usize = 0;
        let cmd_len :usize = cmds.iter().len();
        for cmd in cmds.iter() {
            let mut formatted_args = String::from("");
            let mut command_contents: Vec<String> = Vec::new();
            let mut formatted_name = String::from(format!("name=\"{}\"",cmd.get_name()?));
            command_contents.push(formatted_name);
            let mut formatted_singles = String::from("singles=[");
            let singles_csv = cmd.get_singles()?
                .iter()
                .map(|O| {
                    match O {
                        Ok(x) => {let out = format!("\"{}\"", x); out},
                        Err(e) => String::new(),
                    }
                }).collect::<Vec<_>>().join(", ");
            formatted_singles.push_str(format!("{}]", singles_csv.as_str()).as_str());
            command_contents.push(formatted_singles);
            let mut formatted_kvs = String::from("kvs=[");
            let kvs_csv = cmd.get_kvs()?
            .iter()
            .map(|O| {
                let first = match O.get_first() {
                    Ok(x) => x,
                    Err(e) => "",
                };
                let second = match O.get_second() {
                    Ok(x) => x,
                    Err(e) => "",
                };
                let out = format!("(first=\"{}\", second=\"{}\")", first, second);
                out
            }).collect::<Vec<String>>().join(", ");
            formatted_kvs.push_str(format!("{}]", kvs_csv.as_str()).as_str());
            command_contents.push(formatted_kvs);
            formatted_args.push_str(
                format!("'command:({0})' -> option {1}_{2}()"
                    , command_contents.join(", ")
                    , cmd.get_name()?
                    , cmd_count).as_str());
            switches.push(formatted_args);
            if cmd_len == 1 { // only one command in the list
                flow.push_str(format!("{0}_{1}({0})", cmd.get_name()?, cmd_count).as_str());
                switches.push(format!("'generic_text:(text=\"/2/1/\")' -> stdin {0}_{1}()", cmd.get_name()?, cmd_count));
            } else { // more than one command
                if cmd_len > 1 && cmd_count == 0 { // the first command of many in a list
                    flow.push_str(format!("{0}_{1}({0}) stdout -> ", cmd.get_name()?, cmd_count).as_str());
                    switches.push(format!("'generic_text:(text=\"/2/1/\")' -> stdin {0}_{1}()", cmd.get_name()?, cmd_count));
                } else { // check if the last command or not
                    if (cmd_len - 1) == cmd_count { // last command
                        flow.push_str(format!("stdin {0}_{1}({0})", cmd.get_name()?, cmd_count).as_str());
                    } else { // not the first command, and not the last command
                        flow.push_str(format!("stdin {0}_{1}({0}) stdout -> ", cmd.get_name()?, cmd_count).as_str());
                    }
                }
            }
            cmd_count += 1;
        }
        println!("{:?}", flow);

        // Send start
        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_start("flowscript");
        }
        self.ports.send("output", new_ip)?;

        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_text(&flow.as_str());
        }
        self.ports.send("output", new_ip)?;

        for switch in switches {
            println!("{:?}", switch);
            let mut new_ip = IP::new();
            {
                let mut ip = new_ip.init_root::<file_desc::Builder>();
                ip.set_text(&switch.as_str());
            }
            self.ports.send("output", new_ip)?;
        }

        // Send stop
        let mut new_ip = IP::new();
        {
            let mut ip = new_ip.init_root::<file_desc::Builder>();
            ip.set_end("flowscript");
        }
        self.ports.send("output", new_ip)?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::hash;
use std::iter::FromIterator;
use std::collections::HashMap;
use num::{BigUint, FromPrimitive, Zero, One};
use nock::{self, Noun, FromNoun};

pub struct Jet {
    pub name: String,
    pub jet: Option<fn(&Noun) -> Noun>,
    pub battery: Noun,
    // TODO: What do we do with these?
    pub axis: u32,
    pub hooks: HashMap<String, Noun>,
    pub calls: u64,
}

impl Jet {
    pub fn new(name: String, battery: Noun, axis: u32, hooks: Vec<(String, Noun)>) -> Jet {
        let jet = match &name[..] {
            "dec" => Some(dec as fn(&Noun) -> Noun),
            "bex" => Some(bex as fn(&Noun) -> Noun),
            "add" => Some(add as fn(&Noun) -> Noun),
            "mul" => Some(mul as fn(&Noun) -> Noun),
            "sub" => Some(sub as fn(&Noun) -> Noun),
            "div" => Some(div as fn(&Noun) -> Noun),
            "lth" => Some(lth as fn(&Noun) -> Noun),
            "rsh" => Some(rsh as fn(&Noun) -> Noun),
            "lsh" => Some(lsh as fn(&Noun) -> Noun),
            "mod" => Some(mod_ as fn(&Noun) -> Noun),
            "end" => Some(end as fn(&Noun) -> Noun),
            "mix" => Some(mix as fn(&Noun) -> Noun),
            "met" => Some(met as fn(&Noun) -> Noun),
            "cut" => Some(cut as fn(&Noun) -> Noun),
            "mug" => Some(mug as fn(&Noun) -> Noun),
            _ => None,
        };

        Jet {
            name: name,
            jet: jet,
            battery: battery,
            axis: axis,
            hooks: HashMap::from_iter(hooks.into_iter()),
            calls: 0,
        }
    }
}

impl hash::Hash for Jet {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.battery.hash(state);
    }
}

// FIXME: Needing to do the get_axis on subject.
// TODO: Error handling that isn't panicing.

pub fn dec(subject: &Noun) -> Noun {
    // XXX: How do we know the axis here?
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let n = BigUint::from_noun(&arg).unwrap();
    Noun::from(n - BigUint::one())
}

pub fn bex(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    // XXX: Will fail if arg is above machine word size.
    let n: usize = FromNoun::from_noun(&arg).unwrap();
    Noun::from(BigUint::one() << n)
}

pub fn add(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x + y)
}

pub fn mul(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x * y)
}

pub fn sub(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x - y)
}

pub fn div(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x / y)
}

pub fn lth(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x < y)
}

pub fn rsh(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(c >> ((1 << a) * b))
}

pub fn lsh(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(c << ((1 << a) * b))
}

pub fn mod_(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x % y)
}

pub fn end(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();

    Noun::from(c % BigUint::from_usize(1 << ((1 << a) * b)).unwrap())
}

pub fn mix(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();

    Noun::from(a ^ b)
}

pub fn met(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (bloq, mut atom): (usize, BigUint) = FromNoun::from_noun(&arg).unwrap();
    let mut ret: usize = 0;
    while atom != Zero::zero() {
        atom = atom >> (1 << bloq);
        ret += 1;
    }
    Noun::from(ret)
}

pub fn cut(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, (mut b, mut c), mut d): (usize, (usize, usize), BigUint) = FromNoun::from_noun(&arg).unwrap();
    b = b << a;
    c = c << (1 << a);
    d = d >> b;
    d = d % BigUint::from_usize(c).unwrap();

    Noun::from(d)
}

pub fn mug(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();
    Noun::from(arg.mug())
}
<commit_msg>Less dumb met jet<commit_after>use std::hash;
use std::iter::FromIterator;
use std::collections::HashMap;
use num::{BigUint, FromPrimitive, One};
use nock::{self, Shape, Noun, FromNoun};

pub struct Jet {
    pub name: String,
    pub jet: Option<fn(&Noun) -> Noun>,
    pub battery: Noun,
    // TODO: What do we do with these?
    pub axis: u32,
    pub hooks: HashMap<String, Noun>,
    pub calls: u64,
}

impl Jet {
    pub fn new(name: String, battery: Noun, axis: u32, hooks: Vec<(String, Noun)>) -> Jet {
        let jet = match &name[..] {
            "dec" => Some(dec as fn(&Noun) -> Noun),
            "bex" => Some(bex as fn(&Noun) -> Noun),
            "add" => Some(add as fn(&Noun) -> Noun),
            "mul" => Some(mul as fn(&Noun) -> Noun),
            "sub" => Some(sub as fn(&Noun) -> Noun),
            "div" => Some(div as fn(&Noun) -> Noun),
            "lth" => Some(lth as fn(&Noun) -> Noun),
            "rsh" => Some(rsh as fn(&Noun) -> Noun),
            "lsh" => Some(lsh as fn(&Noun) -> Noun),
            "mod" => Some(mod_ as fn(&Noun) -> Noun),
            "end" => Some(end as fn(&Noun) -> Noun),
            "mix" => Some(mix as fn(&Noun) -> Noun),
            "met" => Some(met as fn(&Noun) -> Noun),
            "cut" => Some(cut as fn(&Noun) -> Noun),
            "mug" => Some(mug as fn(&Noun) -> Noun),
            _ => None,
        };

        Jet {
            name: name,
            jet: jet,
            battery: battery,
            axis: axis,
            hooks: HashMap::from_iter(hooks.into_iter()),
            calls: 0,
        }
    }
}

impl hash::Hash for Jet {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.battery.hash(state);
    }
}

// FIXME: Needing to do the get_axis on subject.
// TODO: Error handling that isn't panicing.

pub fn dec(subject: &Noun) -> Noun {
    // XXX: How do we know the axis here?
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let n = BigUint::from_noun(&arg).unwrap();
    Noun::from(n - BigUint::one())
}

pub fn bex(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    // XXX: Will fail if arg is above machine word size.
    let n: usize = FromNoun::from_noun(&arg).unwrap();
    Noun::from(BigUint::one() << n)
}

pub fn add(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x + y)
}

pub fn mul(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x * y)
}

pub fn sub(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x - y)
}

pub fn div(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x / y)
}

pub fn lth(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x < y)
}

pub fn rsh(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(c >> ((1 << a) * b))
}

pub fn lsh(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(c << ((1 << a) * b))
}

pub fn mod_(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (x, y): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();
    Noun::from(x % y)
}

pub fn end(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b, c): (usize, usize, BigUint) = FromNoun::from_noun(&arg).unwrap();

    Noun::from(c % BigUint::from_usize(1 << ((1 << a) * b)).unwrap())
}

pub fn mix(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, b): (BigUint, BigUint) = FromNoun::from_noun(&arg).unwrap();

    Noun::from(a ^ b)
}

pub fn met(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    if let Shape::Cell(ref bloq, ref b) = arg.get() {
        let bloq: usize = FromNoun::from_noun(bloq).unwrap();

        let mut bits;
        if let Shape::Atom(ref atom) = b.get() {
            bits = atom.len() * 8;
            if bits > 0 {
                let last = atom[atom.len() - 1];
                for i in (1..8).rev() {
                    if last & (1 << i) == 0 {
                        bits -= 1;
                    } else {
                        break;
                    }
                }
            }
        } else {
            panic!("Bad atom");
        }

        bits += (1 << bloq) - 1;

        Noun::from(bits / (1 << bloq))
    } else {
        panic!("Bad argument");
    }
}

pub fn cut(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();

    let (a, (mut b, mut c), mut d): (usize, (usize, usize), BigUint) = FromNoun::from_noun(&arg).unwrap();
    b = b << a;
    c = c << (1 << a);
    d = d >> b;
    d = d % BigUint::from_usize(c).unwrap();

    Noun::from(d)
}

pub fn mug(subject: &Noun) -> Noun {
    let arg = nock::get_axis(&Noun::from(6u32), subject).unwrap();
    Noun::from(arg.mug())
}
<|endoftext|>


<commit_before><commit_msg>no size<commit_after><|endoftext|>


<commit_before>//! Access to open sqlite3 database by filename.
//!
//! The `core` module requires explicit authority to access files and such,
//! following the principle of least authority.
//!
//! This module provides the privileged functions to create such authorities.
//!
//! *TODO: move `mod access` to its own crate so that linking to `sqlite3` doesn't
//! bring in this ambient authority.*
#![unstable]

use libc::c_int;
use std::ptr;

use super::SqliteResult;
use core::{Access, DatabaseConnection, str_charstar};
use ffi;

use access::flags::OpenFlags;

// submodule KLUDGE around missing_docs for bitflags!()
#[allow(missing_docs)]
pub mod flags;

/// Open a database by filename.
///
/// *TODO: test for "Note that sqlite3_open() can be used to either
/// open existing database files or to create and open new database
/// files."*
///
///
/// Refer to [Opening A New Database][open] regarding URI filenames.
///
/// [open]: http://www.sqlite.org/c3ref/open.html
#[stable]
pub fn open(filename: &str, flags: Option<OpenFlags>) -> SqliteResult<DatabaseConnection> {
    DatabaseConnection::new(
        ByFilename {
            filename: filename,
            flags: flags.unwrap_or_default()
        })
}

/// Access to a database by filename
pub struct ByFilename<'a> {
    /// Filename or sqlite3 style URI.
    pub filename: &'a str,
    /// Flags for additional control over the new database connection.
    pub flags: OpenFlags
}

impl<'a> Access for ByFilename<'a> {
    fn open(self, db: *mut *mut ffi::sqlite3) -> c_int {
        let c_filename = str_charstar(self.filename).as_ptr();
        let flags = self.flags.bits();
        unsafe { ffi::sqlite3_open_v2(c_filename, db, flags, ptr::null()) }
    }
}

#[cfg(test)]
mod tests {
    use std::default::Default;
    use super::ByFilename;
    use core::DatabaseConnection;
    use std::os::tmpdir;
    use std::path::BytesContainer;

    #[test]
    fn open_file_db() {
        let mut temp_directory = tmpdir();
        temp_directory.push("db1");
        let path = temp_directory.container_as_str().unwrap();
        DatabaseConnection::new(
            ByFilename {
                filename: path, flags: Default::default()
            })
            .unwrap();
    }
}

// Local Variables:
// flycheck-rust-crate-root: "lib.rs"
// End:
<commit_msg>"path" -> "old_path"<commit_after>//! Access to open sqlite3 database by filename.
//!
//! The `core` module requires explicit authority to access files and such,
//! following the principle of least authority.
//!
//! This module provides the privileged functions to create such authorities.
//!
//! *TODO: move `mod access` to its own crate so that linking to `sqlite3` doesn't
//! bring in this ambient authority.*
#![unstable]

use libc::c_int;
use std::ptr;

use super::SqliteResult;
use core::{Access, DatabaseConnection, str_charstar};
use ffi;

use access::flags::OpenFlags;

// submodule KLUDGE around missing_docs for bitflags!()
#[allow(missing_docs)]
pub mod flags;

/// Open a database by filename.
///
/// *TODO: test for "Note that sqlite3_open() can be used to either
/// open existing database files or to create and open new database
/// files."*
///
///
/// Refer to [Opening A New Database][open] regarding URI filenames.
///
/// [open]: http://www.sqlite.org/c3ref/open.html
#[stable]
pub fn open(filename: &str, flags: Option<OpenFlags>) -> SqliteResult<DatabaseConnection> {
    DatabaseConnection::new(
        ByFilename {
            filename: filename,
            flags: flags.unwrap_or_default()
        })
}

/// Access to a database by filename
pub struct ByFilename<'a> {
    /// Filename or sqlite3 style URI.
    pub filename: &'a str,
    /// Flags for additional control over the new database connection.
    pub flags: OpenFlags
}

impl<'a> Access for ByFilename<'a> {
    fn open(self, db: *mut *mut ffi::sqlite3) -> c_int {
        let c_filename = str_charstar(self.filename).as_ptr();
        let flags = self.flags.bits();
        unsafe { ffi::sqlite3_open_v2(c_filename, db, flags, ptr::null()) }
    }
}

#[cfg(test)]
mod tests {
    use std::default::Default;
    use super::ByFilename;
    use core::DatabaseConnection;
    use std::os::tmpdir;
    use std::old_path::BytesContainer;

    #[test]
    fn open_file_db() {
        let mut temp_directory = tmpdir();
        temp_directory.push("db1");
        let path = temp_directory.container_as_str().unwrap();
        DatabaseConnection::new(
            ByFilename {
                filename: path, flags: Default::default()
            })
            .unwrap();
    }
}

// Local Variables:
// flycheck-rust-crate-root: "lib.rs"
// End:
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! Handlers and types for agent's actions.
//!
//! The basic functionality that a GRR agent exposes is called an _action_.
//! Actions are invoked by the server (when running a _flow_), should gather
//! requested information and report back to the server.
//!
//! In RRG each action consists of three components: a request type, a response
//! type and an action handler. Request and response types wrap lower-level
//! Protocol Buffer messages sent by and to the GRR server. Handlers accept one
//! instance of the corresponding request type and send some (zero or more)
//! instances of the corresponding response type.

#[cfg(feature = "action-filesystems")]
#[cfg(target_os = "linux")]
pub mod filesystems;

#[cfg(feature = "action-interfaces")]
#[cfg(target_family = "unix")]
pub mod interfaces;

#[cfg(feature = "action-metadata")]
pub mod metadata;

#[cfg(feature = "action-listdir")]
pub mod listdir;

#[cfg(feature = "action-timeline")]
pub mod timeline;

#[cfg(feature = "action-network")]
pub mod network;

#[cfg(feature = "action-stat")]
pub mod stat;

#[cfg(feature = "action-insttime")]
pub mod insttime;

#[cfg(feature = "action-memsize")]
pub mod memsize;

#[cfg(feature = "action-finder")]
pub mod finder;

use crate::session::{self, Session, Task};

/// Abstraction for action-specific requests.
///
/// Protocol Buffer messages received from the GRR server are not necessarily
/// easy to work with and are hardly idiomatic to Rust. For this reason, actions
/// should define more structured data types to represent their input and should
/// be able to parse raw messages into them.
pub trait Request: Sized {

    /// A type of the corresponding raw proto message.
    type Proto: protobuf::Message + Default;

    /// A method for converting raw proto messages into structured requests.
    fn from_proto(proto: Self::Proto) -> Result<Self, session::ParseError>;
}

/// Abstraction for action-specific responses.
///
/// Like with the [`Request`] type, Protocol Buffer messages sent to the GRR
/// server are very idiomatic to Rust. For this reason, actions should define
/// more structured data types to represent responses and provide a way to
/// convert them into the wire format.
///
/// Note that because of the design flaws in the protocol, actions also need to
/// specify a name of the wrapper RDF class from the Python implementation.
/// Hopefully, one day this issue would be fixed and class names will not leak
/// into the specification.
///
/// [`Request`]: trait.Request.html
pub trait Response: Sized {

    /// A name of the corresponding RDF class.
    const RDF_NAME: Option<&'static str>;

    /// A type of the corresponding raw proto message.
    type Proto: protobuf::Message + Default;

    /// A method for converting structured responses into raw proto messages.
    fn into_proto(self) -> Self::Proto;
}

impl Request for () {

    type Proto = protobuf::well_known_types::Empty;

    fn from_proto(_: protobuf::well_known_types::Empty) -> Result<(), session::ParseError> {
        Ok(())
    }
}

impl Response for () {

    const RDF_NAME: Option<&'static str> = None;

    type Proto = protobuf::well_known_types::Empty;

    fn into_proto(self) -> protobuf::well_known_types::Empty {
        protobuf::well_known_types::Empty::new()
    }
}

/// Dispatches `task` to a handler appropriate for the given `action`.
///
/// This method is a mapping between action names (as specified in the protocol)
/// and action handlers (implemented on the agent).
///
/// If the given action is unknown (or not yet implemented), this function will
/// return an error.
pub fn dispatch<'s, S>(action: &str, task: Task<'s, S>) -> session::Result<()>
where
    S: Session,
{
    match action {
        #[cfg(feature = "action-metadata")]
        "GetClientInfo" => task.execute(self::metadata::handle),

        #[cfg(feature = "action-listdir")]
        "ListDirectory" => task.execute(self::listdir::handle),

        #[cfg(feature = "action-timeline")]
        "Timeline" => task.execute(self::timeline::handle),

        #[cfg(feature = "action-network")]
        "ListNetworkConnections" => task.execute(self::network::handle),

        #[cfg(feature = "action-stat")]
        "GetFileStat" => task.execute(self::stat::handle),

        #[cfg(feature = "action-insttime")]
        "GetInstallDate" => task.execute(self::insttime::handle),

        #[cfg(feature = "action-interfaces")]
        #[cfg(target_family = "unix")]
        "EnumerateInterfaces" => task.execute(self::interfaces::handle),

        #[cfg(feature = "action-filesystems")]
        #[cfg(target_os = "linux")]
        "EnumerateFilesystems" => task.execute(self::filesystems::handle),

        #[cfg(feature = "action-memsize")]
        "GetMemorySize" => task.execute(self::memsize::handle),

        action => return Err(session::Error::Dispatch(String::from(action))),
    }
}

// TODO(panhania@): Remove all usages of the `Request` trait and replace it with
// `Args`.
pub trait Args: Sized {
    /// Low-level Protocol Buffers type representing the action arguments.
    type Proto: protobuf::Message + Default;

    /// Converts a low-level type to a structured request arguments.
    fn from_proto(proto: Self::Proto) -> Result<Self, ParseArgsError>;
}

pub trait Item: Sized {
    /// Low-level Protocol Buffers type representing the action results.
    type Proto: protobuf::Message + Default;

    /// A name of the corresponding RDF class in GRR.
    const RDF_NAME: &'static str;

    /// Converts an action result ot its low-level representation.
    fn into_proto(self) -> Self::Proto;
}

/// The error type for cases when action argument parsing fails.
#[derive(Debug)]
pub struct ParseArgsError {
    /// A corresponding [`ParseArgsErrorKind`] of this error.
    kind: ParseArgsErrorKind,
    /// A detailed payload associated with the error.
    error: Box<dyn std::error::Error + Send + Sync>,
}

/// Kinds of errors that can happen when parsing action arguments.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ParseArgsErrorKind {
    /// The serialized message with arguments was impossible to deserialize.
    InvalidProto,
}

impl ParseArgsErrorKind {

    fn as_str(&self) -> &'static str {
        use ParseArgsErrorKind::*;

        match *self {
            InvalidProto => "invalid serialized protobuf message",
        }
    }
}

impl std::fmt::Display for ParseArgsError {

    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(fmt, "{}: {}", self.kind.as_str(), self.error)
    }
}

impl std::error::Error for ParseArgsError {

    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        self.error.source()
    }
}

impl From<protobuf::ProtobufError> for ParseArgsError {

    fn from(error: protobuf::ProtobufError) -> Self {
        ParseArgsError {
            kind: ParseArgsErrorKind::InvalidProto,
            error: Box::new(error),
        }
    }
}
<commit_msg>Add an invalid field variant to argument errors.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

//! Handlers and types for agent's actions.
//!
//! The basic functionality that a GRR agent exposes is called an _action_.
//! Actions are invoked by the server (when running a _flow_), should gather
//! requested information and report back to the server.
//!
//! In RRG each action consists of three components: a request type, a response
//! type and an action handler. Request and response types wrap lower-level
//! Protocol Buffer messages sent by and to the GRR server. Handlers accept one
//! instance of the corresponding request type and send some (zero or more)
//! instances of the corresponding response type.

#[cfg(feature = "action-filesystems")]
#[cfg(target_os = "linux")]
pub mod filesystems;

#[cfg(feature = "action-interfaces")]
#[cfg(target_family = "unix")]
pub mod interfaces;

#[cfg(feature = "action-metadata")]
pub mod metadata;

#[cfg(feature = "action-listdir")]
pub mod listdir;

#[cfg(feature = "action-timeline")]
pub mod timeline;

#[cfg(feature = "action-network")]
pub mod network;

#[cfg(feature = "action-stat")]
pub mod stat;

#[cfg(feature = "action-insttime")]
pub mod insttime;

#[cfg(feature = "action-memsize")]
pub mod memsize;

#[cfg(feature = "action-finder")]
pub mod finder;

use crate::session::{self, Session, Task};

/// Abstraction for action-specific requests.
///
/// Protocol Buffer messages received from the GRR server are not necessarily
/// easy to work with and are hardly idiomatic to Rust. For this reason, actions
/// should define more structured data types to represent their input and should
/// be able to parse raw messages into them.
pub trait Request: Sized {

    /// A type of the corresponding raw proto message.
    type Proto: protobuf::Message + Default;

    /// A method for converting raw proto messages into structured requests.
    fn from_proto(proto: Self::Proto) -> Result<Self, session::ParseError>;
}

/// Abstraction for action-specific responses.
///
/// Like with the [`Request`] type, Protocol Buffer messages sent to the GRR
/// server are very idiomatic to Rust. For this reason, actions should define
/// more structured data types to represent responses and provide a way to
/// convert them into the wire format.
///
/// Note that because of the design flaws in the protocol, actions also need to
/// specify a name of the wrapper RDF class from the Python implementation.
/// Hopefully, one day this issue would be fixed and class names will not leak
/// into the specification.
///
/// [`Request`]: trait.Request.html
pub trait Response: Sized {

    /// A name of the corresponding RDF class.
    const RDF_NAME: Option<&'static str>;

    /// A type of the corresponding raw proto message.
    type Proto: protobuf::Message + Default;

    /// A method for converting structured responses into raw proto messages.
    fn into_proto(self) -> Self::Proto;
}

impl Request for () {

    type Proto = protobuf::well_known_types::Empty;

    fn from_proto(_: protobuf::well_known_types::Empty) -> Result<(), session::ParseError> {
        Ok(())
    }
}

impl Response for () {

    const RDF_NAME: Option<&'static str> = None;

    type Proto = protobuf::well_known_types::Empty;

    fn into_proto(self) -> protobuf::well_known_types::Empty {
        protobuf::well_known_types::Empty::new()
    }
}

/// Dispatches `task` to a handler appropriate for the given `action`.
///
/// This method is a mapping between action names (as specified in the protocol)
/// and action handlers (implemented on the agent).
///
/// If the given action is unknown (or not yet implemented), this function will
/// return an error.
pub fn dispatch<'s, S>(action: &str, task: Task<'s, S>) -> session::Result<()>
where
    S: Session,
{
    match action {
        #[cfg(feature = "action-metadata")]
        "GetClientInfo" => task.execute(self::metadata::handle),

        #[cfg(feature = "action-listdir")]
        "ListDirectory" => task.execute(self::listdir::handle),

        #[cfg(feature = "action-timeline")]
        "Timeline" => task.execute(self::timeline::handle),

        #[cfg(feature = "action-network")]
        "ListNetworkConnections" => task.execute(self::network::handle),

        #[cfg(feature = "action-stat")]
        "GetFileStat" => task.execute(self::stat::handle),

        #[cfg(feature = "action-insttime")]
        "GetInstallDate" => task.execute(self::insttime::handle),

        #[cfg(feature = "action-interfaces")]
        #[cfg(target_family = "unix")]
        "EnumerateInterfaces" => task.execute(self::interfaces::handle),

        #[cfg(feature = "action-filesystems")]
        #[cfg(target_os = "linux")]
        "EnumerateFilesystems" => task.execute(self::filesystems::handle),

        #[cfg(feature = "action-memsize")]
        "GetMemorySize" => task.execute(self::memsize::handle),

        action => return Err(session::Error::Dispatch(String::from(action))),
    }
}

// TODO(panhania@): Remove all usages of the `Request` trait and replace it with
// `Args`.
pub trait Args: Sized {
    /// Low-level Protocol Buffers type representing the action arguments.
    type Proto: protobuf::Message + Default;

    /// Converts a low-level type to a structured request arguments.
    fn from_proto(proto: Self::Proto) -> Result<Self, ParseArgsError>;
}

pub trait Item: Sized {
    /// Low-level Protocol Buffers type representing the action results.
    type Proto: protobuf::Message + Default;

    /// A name of the corresponding RDF class in GRR.
    const RDF_NAME: &'static str;

    /// Converts an action result ot its low-level representation.
    fn into_proto(self) -> Self::Proto;
}

/// The error type for cases when action argument parsing fails.
#[derive(Debug)]
pub struct ParseArgsError {
    /// A corresponding [`ParseArgsErrorKind`] of this error.
    kind: ParseArgsErrorKind,
    /// A detailed payload associated with the error.
    error: Box<dyn std::error::Error + Send + Sync>,
}

impl ParseArgsError {

    /// Creates a new error instance caused by some invalid field error.
    fn invalid_field<E>(error: E) -> ParseArgsError
    where
        E: std::error::Error + Send + Sync + 'static,
    {
        ParseArgsError {
            kind: ParseArgsErrorKind::InvalidField,
            error: Box::new(error),
        }
    }
}

/// Kinds of errors that can happen when parsing action arguments.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ParseArgsErrorKind {
    /// The serialized message with arguments was impossible to deserialize.
    InvalidProto,
    // TODO(panhania@): Augment with field name.
    /// One of the fields of the arguments struct is invalid.
    InvalidField,
}

impl ParseArgsErrorKind {

    fn as_str(&self) -> &'static str {
        use ParseArgsErrorKind::*;

        match *self {
            InvalidProto => "invalid serialized protobuf message",
            InvalidField => "invalid argument field",
        }
    }
}

impl std::fmt::Display for ParseArgsError {

    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(fmt, "{}: {}", self.kind.as_str(), self.error)
    }
}

impl std::error::Error for ParseArgsError {

    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        self.error.source()
    }
}

impl From<protobuf::ProtobufError> for ParseArgsError {

    fn from(error: protobuf::ProtobufError) -> Self {
        ParseArgsError {
            kind: ParseArgsErrorKind::InvalidProto,
            error: Box::new(error),
        }
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use self::libc::{c_char, c_uchar};

/// Signs and sends transaction message to validator pool.
///
/// Adds submitter information to passed transaction json, signs it with submitter
/// sign key (see wallet_sign_by_my_did), and sends signed transaction message
/// to validator pool (see ledger_write_txn).
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// submitter_did: Id of Identity stored in secured Wallet.
/// txn_json: Transaction data json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_sign_and_send_txn(client_handle: i32, command_handle: i32,
                                       submitter_did: *const c_char, txn_json: *const c_char,
                                       cb: extern fn(xcommand_handle: i32, err: i32,
                                                     txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Sends transaction message to validator pool (no signing, unlike ledger_sign_and_write_txn).
///
/// The transaction is sent to the validator pool as is. It's assumed that it's already prepared.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// txn_json: Transaction data json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_send_txn(client_handle: i32, command_handle: i32,
                              txn_json: *const c_char,
                              cb: extern fn(xcommand_handle: i32, err: i32,
                                            txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs a txn to get a DDO.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_get_ddo_txn(client_handle: i32, command_handle: i32, sign: i32,
                                 submitter_did: *const c_char, target_did: *const c_char,
                                 cb: extern fn(xcommand_handle: i32, err: i32,
                                               txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs NYM transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// verkey:
/// xref:
/// data:
/// role:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_nym_txn(client_handle: i32, command_handle: i32, sign: i32,
                             submitter_did: *const c_char,
                             target_did: *const c_char,
                             verkey: *const c_char, xref: *const c_char,
                             data: *const c_char, role: *const c_char,
                             cb: extern fn(xcommand_handle: i32, err: i32,
                                           txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs ATTRIB transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// hash:
/// raw:
/// enc:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_attrib_txn(client_handle: i32, command_handle: i32, sign: i32,
                                submitter_did: *const c_char, target_did: *const c_char,
                                hash: *const c_char, raw: *const c_char, enc: *const c_char,
                                cb: extern fn(xcommand_handle: i32, err: i32,
                                              txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_ATTRIB transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// data:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
pub extern fn create_get_attrib_txn(client_handle: i32, command_handle: i32, sign: i32,
                                    submitter_did: *const c_char, target_did: *const c_char,
                                    data: *const c_char,
                                    cb: extern fn(xcommand_handle: i32, err: i32,
                                                  txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_NYM transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_get_nym_txn(client_handle: i32, command_handle: i32, sign: i32,
                                 submitter_did: *const c_char, target_did: *const c_char,
                                 cb: extern fn(xcommand_handle: i32, err: i32,
                                               txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs SCHEMA transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// data:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_schema_txn(client_handle: i32, command_handle: i32, sign: i32,
                                submitter_did: *const c_char, data: *const c_char,
                                cb: extern fn(xcommand_handle: i32, err: i32,
                                              txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_SCHEMA transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// data:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_get_schema_txn(client_handle: i32, command_handle: i32, sign: i32,
                                    submitter_did: *const c_char, data: *const c_char,
                                    cb: extern fn(xcommand_handle: i32, err: i32,
                                                  txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs ISSUER_KEY transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// xref:
/// data:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_issuer_key_txn(client_handle: i32, command_handle: i32, sign: i32,
                                    submitter_did: *const c_char, xref: *const c_char,
                                    data: *const c_char,
                                    cb: extern fn(xcommand_handle: i32, err: i32,
                                                  txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_ISSUER_KEY transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// xref:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
pub extern fn crate_get_issuer_key_txn(client_handle: i32, command_handle: i32, sign: i32,
                                       submitter_did: *const c_char, xref: *const c_char,
                                       cb: extern fn(xcommand_handle: i32, err: i32,
                                                     txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs NODE transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign:
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// data:
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn create_node_txn(client_handle: i32, command_handle: i32, sign: i32,
                              submitter_did: *const c_char, target_did: *const c_char,
                              data: *const c_char,
                              cb: extern fn(xcommand_handle: i32, err: i32,
                                            txn_json: *const c_char)) -> i32 {
    unimplemented!();
}<commit_msg>small changes<commit_after>extern crate libc;

use self::libc::{c_char, c_uchar};

/// Signs and sends transaction message to validator pool.
///
/// Adds submitter information to passed transaction json, signs it with submitter
/// sign key (see wallet_sign_by_my_did), and sends signed transaction message
/// to validator pool (see ledger_write_txn).
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// submitter_did: Id of Identity stored in secured Wallet.
/// txn_json: Transaction data json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_sign_and_send_txn(client_handle: i32, command_handle: i32,
                                       submitter_did: *const c_char, txn_json: *const c_char,
                                       cb: extern fn(xcommand_handle: i32, err: i32,
                                                     txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Sends transaction message to validator pool (no signing, unlike ledger_sign_and_write_txn).
///
/// The transaction is sent to the validator pool as is. It's assumed that it's already prepared.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// txn_json: Transaction data json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_send_txn(client_handle: i32, command_handle: i32,
                              txn_json: *const c_char,
                              cb: extern fn(xcommand_handle: i32, err: i32,
                                            txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs a txn to get a DDO.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_get_ddo_txn(client_handle: i32, command_handle: i32, sign: bool,
                                        submitter_did: *const c_char, target_did: *const c_char,
                                        cb: extern fn(xcommand_handle: i32, err: i32,
                                                      txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs NYM transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// verkey: verification key
/// xref: id of a NYM record
/// data: alias
/// role: Role of a user NYM record
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_nym_txn(client_handle: i32, command_handle: i32, sign: bool,
                                    submitter_did: *const c_char,
                                    target_did: *const c_char,
                                    verkey: *const c_char, xref: *const c_char,
                                    data: *const c_char, role: *const c_char,
                                    cb: extern fn(xcommand_handle: i32, err: i32,
                                                  txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs ATTRIB transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// hash: Hash of attribute data
/// raw: represented as json, where key is attribute name and value is it's value
/// enc: Encrypted attribute data
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_attrib_txn(client_handle: i32, command_handle: i32, sign: bool,
                                       submitter_did: *const c_char, target_did: *const c_char,
                                       hash: *const c_char, raw: *const c_char, enc: *const c_char,
                                       cb: extern fn(xcommand_handle: i32, err: i32,
                                                     txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_ATTRIB transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// data: name (attribute name)
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
pub extern fn ledger_create_get_attrib_txn(client_handle: i32, command_handle: i32, sign: bool,
                                           submitter_did: *const c_char, target_did: *const c_char,
                                           data: *const c_char,
                                           cb: extern fn(xcommand_handle: i32, err: i32,
                                                         txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_NYM transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_get_nym_txn(client_handle: i32, command_handle: i32, sign: bool,
                                        submitter_did: *const c_char, target_did: *const c_char,
                                        cb: extern fn(xcommand_handle: i32, err: i32,
                                                      txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs SCHEMA transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// data: name, version, type, attr_names (ip, port, keys)
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_schema_txn(client_handle: i32, command_handle: i32, sign: bool,
                                       submitter_did: *const c_char, data: *const c_char,
                                       cb: extern fn(xcommand_handle: i32, err: i32,
                                                     txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_SCHEMA transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// data: name, version
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_get_schema_txn(client_handle: i32, command_handle: i32, sign: bool,
                                           submitter_did: *const c_char, data: *const c_char,
                                           cb: extern fn(xcommand_handle: i32, err: i32,
                                                         txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs ISSUER_KEY transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// xref: Seq. number of schema
/// data: components of a key in json: N, R, S, Z
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_issuer_key_txn(client_handle: i32, command_handle: i32, sign: bool,
                                           submitter_did: *const c_char, xref: *const c_char,
                                           data: *const c_char,
                                           cb: extern fn(xcommand_handle: i32, err: i32,
                                                         txn_result_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs GET_ISSUER_KEY transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// xref: Seq. number of schema
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
pub extern fn ledger_create_get_issuer_key_txn(client_handle: i32, command_handle: i32, sign: bool,
                                               submitter_did: *const c_char, xref: *const c_char,
                                               cb: extern fn(xcommand_handle: i32, err: i32,
                                                             txn_json: *const c_char)) -> i32 {
    unimplemented!();
}

/// Creates and optionally signs NODE transaction.
///
/// #Params
/// client_handle: id of Ledger client instance.
/// command_handle: command id to map of callback to user context.
/// sign: boolean (true if tnx must be signed).
/// submitter_did: Id of Identity stored in secured Wallet.
/// target_did: Id of Identity stored in secured Wallet.
/// data: id of a target NYM record
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Transaction result as json.
///
/// #Errors
/// No method specific errors.
/// See `LedgerError` docs for common errors description.
#[no_mangle]
pub extern fn ledger_create_node_txn(client_handle: i32, command_handle: i32, sign: bool,
                                     submitter_did: *const c_char, target_did: *const c_char,
                                     data: *const c_char,
                                     cb: extern fn(xcommand_handle: i32, err: i32,
                                                   txn_json: *const c_char)) -> i32 {
    unimplemented!();
}<|endoftext|>