From 4c1a89544ee61e82cd74a9a18fdc93789f633712 Mon Sep 17 00:00:00 2001 From: thiagopnts Date: Mon, 10 Nov 2014 22:55:41 -0200 Subject: [PATCH] Move code related to json packet reading to JsonPacketSender trait fixup! Move code related to json packet reading to JsonPacketSender trait --- components/devtools/actors/console.rs | 2 +- components/devtools/actors/inspector.rs | 2 +- components/devtools/actors/root.rs | 2 +- components/devtools/actors/tab.rs | 2 +- components/devtools/lib.rs | 41 ++++++------------------- components/devtools/protocol.rs | 31 +++++++++++++++++-- 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/components/devtools/actors/console.rs b/components/devtools/actors/console.rs index a4be9967527c..a52bea0d3ba2 100644 --- a/components/devtools/actors/console.rs +++ b/components/devtools/actors/console.rs @@ -7,7 +7,7 @@ /// inspection, JS evaluation, autocompletion) in Servo. use actor::{Actor, ActorRegistry}; -use protocol::JsonPacketSender; +use protocol::JsonPacketStream; use devtools_traits::{EvaluateJS, NullValue, VoidValue, NumberValue, StringValue, BooleanValue}; use devtools_traits::{ActorValue, DevtoolScriptControlMsg}; diff --git a/components/devtools/actors/inspector.rs b/components/devtools/actors/inspector.rs index 89ef092a137d..9dffef6452d9 100644 --- a/components/devtools/actors/inspector.rs +++ b/components/devtools/actors/inspector.rs @@ -8,7 +8,7 @@ use devtools_traits::{GetRootNode, GetDocumentElement, GetChildren, DevtoolScrip use devtools_traits::{GetLayout, NodeInfo}; use actor::{Actor, ActorRegistry}; -use protocol::JsonPacketSender; +use protocol::JsonPacketStream; use collections::TreeMap; use servo_msg::constellation_msg::PipelineId; diff --git a/components/devtools/actors/root.rs b/components/devtools/actors/root.rs index 8968749f2c51..ac5c355da71d 100644 --- a/components/devtools/actors/root.rs +++ b/components/devtools/actors/root.rs @@ -8,7 +8,7 @@ use actor::{Actor, ActorRegistry}; use actors::tab::{TabActor, TabActorMsg}; -use protocol::JsonPacketSender; +use protocol::JsonPacketStream; use serialize::json; use std::io::TcpStream; diff --git a/components/devtools/actors/tab.rs b/components/devtools/actors/tab.rs index 2e5cb6d10b0b..bbd8ce9c3230 100644 --- a/components/devtools/actors/tab.rs +++ b/components/devtools/actors/tab.rs @@ -7,7 +7,7 @@ /// Supports dynamic attaching and detaching which control notifications of navigation, etc. use actor::{Actor, ActorRegistry}; -use protocol::JsonPacketSender; +use protocol::JsonPacketStream; use serialize::json; use std::io::TcpStream; diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 6c756237c30f..0afb4f6f9a48 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -34,7 +34,7 @@ use actors::console::ConsoleActor; use actors::inspector::InspectorActor; use actors::root::RootActor; use actors::tab::TabActor; -use protocol::JsonPacketSender; +use protocol::JsonPacketStream; use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg}; use servo_msg::constellation_msg::PipelineId; @@ -44,9 +44,7 @@ use std::cell::RefCell; use std::comm; use std::comm::{Disconnected, Empty}; use std::io::{TcpListener, TcpStream}; -use std::io::{Acceptor, Listener, EndOfFile, TimedOut}; -use std::num; -use serialize::json; +use std::io::{Acceptor, Listener, TimedOut}; use sync::{Arc, Mutex}; mod actor; @@ -91,41 +89,20 @@ fn run_server(receiver: Receiver, port: u16) { /// Process the input from a single devtools client until EOF. fn handle_client(actors: Arc>, mut stream: TcpStream) { println!("connection established to {:?}", stream.peer_name().unwrap()); - { let mut actors = actors.lock(); let msg = actors.find::("root").encodable(); stream.write_json_packet(&msg); } - // https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport - // In short, each JSON packet is [ascii length]:[JSON data of given length] - // TODO: this really belongs in the protocol module. 'outer: loop { - let mut buffer = vec!(); - loop { - let colon = ':' as u8; - match stream.read_byte() { - Ok(c) if c != colon => buffer.push(c as u8), - Ok(_) => { - let packet_len_str = String::from_utf8(buffer).unwrap(); - let packet_len = num::from_str_radix(packet_len_str.as_slice(), 10).unwrap(); - let packet_buf = stream.read_exact(packet_len).unwrap(); - let packet = String::from_utf8(packet_buf).unwrap(); - println!("{:s}", packet); - let json_packet = json::from_str(packet.as_slice()).unwrap(); - actors.lock().handle_message(json_packet.as_object().unwrap(), - &mut stream); - break; - } - Err(ref e) if e.kind == EndOfFile => { - println!("\nEOF"); - break 'outer; - }, - _ => { - println!("\nconnection error"); - break 'outer; - } + match stream.read_json_packet() { + Ok(json_packet) => + actors.lock().handle_message(json_packet.as_object().unwrap(), + &mut stream), + Err(e) => { + println!("error: {}", e.desc); + break 'outer } } } diff --git a/components/devtools/protocol.rs b/components/devtools/protocol.rs index 728e593040e0..52cfdaa35369 100644 --- a/components/devtools/protocol.rs +++ b/components/devtools/protocol.rs @@ -5,13 +5,15 @@ /// Low-level wire protocol implementation. Currently only supports [JSON packets](https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport#JSON_Packets). use serialize::{json, Encodable}; -use std::io::{IoError, TcpStream}; +use std::io::{IoError, OtherIoError, EndOfFile, TcpStream, IoResult}; +use std::num; -pub trait JsonPacketSender { +pub trait JsonPacketStream { fn write_json_packet<'a, T: Encodable,IoError>>(&mut self, obj: &T); + fn read_json_packet(&mut self) -> IoResult; } -impl JsonPacketSender for TcpStream { +impl JsonPacketStream for TcpStream { fn write_json_packet<'a, T: Encodable,IoError>>(&mut self, obj: &T) { let s = json::encode(obj).replace("__type__", "type"); println!("<- {:s}", s); @@ -19,4 +21,27 @@ impl JsonPacketSender for TcpStream { self.write_u8(':' as u8).unwrap(); self.write_str(s.as_slice()).unwrap(); } + + fn read_json_packet<'a>(&mut self) -> IoResult { + // https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport + // In short, each JSON packet is [ascii length]:[JSON data of given length] + let mut buffer = vec!(); + loop { + let colon = ':' as u8; + match self.read_byte() { + Ok(c) if c != colon => buffer.push(c as u8), + Ok(_) => { + let packet_len_str = String::from_utf8(buffer).unwrap(); + let packet_len = num::from_str_radix(packet_len_str.as_slice(), 10).unwrap(); + let packet_buf = self.read_exact(packet_len).unwrap(); + let packet = String::from_utf8(packet_buf).unwrap(); + println!("{:s}", packet); + return Ok(json::from_str(packet.as_slice()).unwrap()) + }, + Err(ref e) if e.kind == EndOfFile => + return Err(IoError { kind: EndOfFile, desc: "EOF", detail: None }), + _ => return Err(IoError { kind: OtherIoError, desc: "connection error", detail: None }) + } + } + } }