Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  load.rs   Sprache: unbekannt

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use futures_channel::oneshot;
use nserror::{nsresult, NS_OK, NS_SUCCESS_ADOPTED_DATA};
use nsstring::{nsACString, nsCStringLike};
use std::{
    cell::Cell,
    ffi::c_void,
    io::{self, Error, ErrorKind},
    ptr,
};
use xpcom::{
    interfaces::{nsIStreamLoader, nsIStreamLoaderObserver, nsISupports},
    xpcom,
};

unsafe fn boxed_slice_from_raw(ptr: *mut u8, len: usize) -> Box<[u8]> {
    if ptr.is_null() {
        // It is undefined behaviour to create a `Box<[u8]>` with a null pointer,
        // so avoid that case.
        assert_eq!(len, 0);
        Box::new([])
    } else {
        Box::from_raw(ptr::slice_from_raw_parts_mut(ptr, len))
    }
}

#[xpcom(implement(nsIStreamLoaderObserver), nonatomic)]
struct StreamLoaderObserver {
    sender: Cell<Option<oneshot::Sender<Result<Box<[u8]>, nsresult>>>>,
}

impl StreamLoaderObserver {
    #[allow(non_snake_case)]
    unsafe fn OnStreamComplete(
        &self,
        _loader: *const nsIStreamLoader,
        _ctxt: *const nsISupports,
        status: nsresult,
        result_length: u32,
        result: *const u8,
    ) -> nsresult {
        let sender = match self.sender.take() {
            Some(sender) => sender,
            None => return NS_OK,
        };

        if status.failed() {
            sender.send(Err(status)).expect("Failed to send data");
            return NS_OK;
        }

        // safety: take ownership of the data passed in. This is OK because we
        // have configured Rust and C++ to use the same allocator, and our
        // caller won't free the `result` pointer if we return
        // NS_SUCCESS_ADOPTED_DATA.
        sender
            .send(Ok(boxed_slice_from_raw(
                result as *mut u8,
                result_length as usize,
            )))
            .expect("Failed to send data");
        NS_SUCCESS_ADOPTED_DATA
    }
}

extern "C" {
    fn L10nRegistryLoad(
        path: *const nsACString,
        observer: *const nsIStreamLoaderObserver,
    ) -> nsresult;

    fn L10nRegistryLoadSync(
        aPath: *const nsACString,
        aData: *mut *mut c_void,
        aSize: *mut u64,
    ) -> nsresult;
}

pub async fn load_async(path: impl nsCStringLike) -> io::Result<Box<[u8]>> {
    let (sender, receiver) = oneshot::channel::<Result<Box<[u8]>, nsresult>>();
    let observer = StreamLoaderObserver::allocate(InitStreamLoaderObserver {
        sender: Cell::new(Some(sender)),
    });
    unsafe {
        L10nRegistryLoad(&*path.adapt(), observer.coerce())
            .to_result()
            .map_err(|err| Error::new(ErrorKind::Other, err))?;
    }
    receiver
        .await
        .expect("Failed to receive from observer.")
        .map_err(|err| Error::new(ErrorKind::Other, err))
}

pub fn load_sync(path: impl nsCStringLike) -> io::Result<Box<[u8]>> {
    let mut data_ptr: *mut c_void = ptr::null_mut();
    let mut data_length: u64 = 0;
    unsafe {
        L10nRegistryLoadSync(&*path.adapt(), &mut data_ptr, &mut data_length)
            .to_result()
            .map_err(|err| Error::new(ErrorKind::Other, err))?;

        // The call succeeded, meaning `data_ptr` and `size` have been filled in with owning pointers to actual data payloads (or null).
        // If we get a null, return a successful read of the empty file.
        Ok(boxed_slice_from_raw(
            data_ptr as *mut u8,
            data_length as usize,
        ))
    }
}

[ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge