diff --git a/libcore/src/terrapipe.rs b/libcore/src/terrapipe.rs
index d537e3d3..7a7b8cd7 100644
--- a/libcore/src/terrapipe.rs
+++ b/libcore/src/terrapipe.rs
@@ -8,14 +8,184 @@
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
*/
+const METAFRAME_PROTOCOL_TAG: &'static str = "TP";
+const METAFRAME_QUERY_TAG: &'static str = "Q";
+const METAFRAME_QUERY_SET_TAG: &'static str = "SET";
+const METAFRAME_QUERY_GET_TAG: &'static str = "GET";
+const METAFRAME_QUERY_UPDATE_TAG: &'static str = "UPDATE";
+const METAFRAME_QUERY_DEL_TAG: &'static str = "DEL";
+
+pub struct Version(u8, u8, u8);
+
+impl Version {
+ pub fn new_from_str<'a>(val: &'a str) -> Option {
+ let vals: Vec<&str> = val.split(".").collect();
+ if vals.len() != 3 {
+ return None;
+ }
+ let semver = (
+ vals[0].parse::(),
+ vals[1].parse::(),
+ vals[2].parse::(),
+ );
+ if let (Ok(major), Ok(minor), Ok(patch)) = semver {
+ return Some(Version(major, minor, patch));
+ } else {
+ return None;
+ }
+ }
+ pub fn is_compatible_with(&self, other: &Version) -> bool {
+ if self.0 == other.0 {
+ true
+ } else {
+ false
+ }
+ }
+}
+
+type Key = String;
+
+pub enum TPQueryType {
+ GET(Key),
+ SET(Key, Key),
+ UPDATE(Key, Key),
+ DEL(Key, Key),
+}
+
+pub fn parse_query_packet(own_version: Version, packet: &String) {
+ let rlines: Vec<&str> = packet.lines().collect();
+ // This should give us two or more lines
+ if rlines.len() < 2 {
+ eprintln!("error: 5 CorruptDataframe");
+ return;
+ }
+ // This is the meta frame
+ let meta_frame: Vec<&str> = rlines[0].split("/").collect();
+ if meta_frame.len() != 3 {
+ eprintln!("error: 4 InvalidMetaframe");
+ return;
+ }
+ // This is the data frame
+ let data_frame: Vec<&str> = rlines[1].split_whitespace().collect();
+ // Check if version is valid
+ let version_header: Vec<&str> = meta_frame[0].split(" ").collect();
+ if let Some(version_tag) = version_header.get(0) {
+ if version_tag == &METAFRAME_PROTOCOL_TAG {
+ if let Some(version) = version_header.get(1) {
+ if let Some(v) = Version::new_from_str(&version) {
+ if !v.is_compatible_with(&own_version) {
+ eprintln!("error: 6 ProtocolVersionMismatch");
+ } else {
+ ()
+ }
+ } else {
+ eprintln!("error: 4 InvalidMetaframe");
+ }
+ } else {
+ eprintln!("error: 4 InvalidMetaframe");
+ }
+ } else {
+ eprintln!("error: 4 InvalidMetaframe");
+ }
+ } else {
+ eprintln!("error: 4 InvalidMetaframe");
+ }
+
+ // Now get request type
+ let request_partition: Vec<&str> = meta_frame[1].split(" ").collect();
+ if let Some(request_tag) = request_partition.get(0) {
+ if request_tag == &METAFRAME_QUERY_TAG {
+ if let Some(qtype) = request_partition.get(1) {
+ match qtype {
+ &METAFRAME_QUERY_SET_TAG => {
+ // This is a set request
+ if let Some(key) = data_frame.get(0) {
+ if let Some(value) = data_frame.get(1) {
+ if data_frame.get(2).is_none() {
+ println!("SET {} {}", key, value);
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ }
+ &METAFRAME_QUERY_UPDATE_TAG => {
+ // This is an update request
+ if let Some(key) = data_frame.get(0) {
+ if let Some(value) = data_frame.get(1) {
+ if data_frame.get(2).is_none() {
+ println!("UPDATE {} {}", key, value);
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ }
+ &METAFRAME_QUERY_GET_TAG => {
+ // This is a get request
+ if let Some(key) = data_frame.get(0) {
+ if data_frame.get(1).is_none() {
+ println!("GET {}", key);
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt Dataframe");
+ return;
+ }
+ }
+ _ => {
+ eprintln!("error: 4 Invalid Metaframe");
+ return;
+ }
+ }
+ } else {
+ eprintln!("error: 5 Corrupt dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt dataframe");
+ return;
+ }
+ } else {
+ eprintln!("error: 5 Corrupt dataframe");
+ return;
+ }
+}
+
+#[cfg(test)]
+#[test]
+fn test_parse_header_query() {
+ let query_packet_get = "TP 0.1.1/Q GET/5\nsayan".to_owned();
+ parse_query_packet(Version(0, 1, 1), &query_packet_get);
+ let query_packet_set = "TP 0.1.1/Q SET/8\nsayan 18".to_owned();
+ parse_query_packet(Version(0, 1, 1), &query_packet_set);
+ let erroring_packet_set = "TP 0.1.1/Q SET/13\nhi sayan".to_owned();
+ parse_query_packet(Version(0, 1, 1), &erroring_packet_set);
+}