about summary refs log tree commit diff
path: root/src/test/run-pass/issue-4241.rs
blob: 18bc471afab1d4b10ec21c0463aefe67d0af9d85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
extern mod std;

use std::net::tcp::TcpSocketBuf;

use core::io::{ReaderUtil,WriterUtil};

enum Result {
  Nil,
  Int(int),
  Data(~[u8]),
  List(~[Result]),
  Error(~str),
  Status(~str)
}

priv fn parse_data(len: uint, io: @io::Reader) -> Result {
  let res =
      if (len > 0) {
      let bytes = io.read_bytes(len as uint);
      assert!(bytes.len() == len);
      Data(bytes)
  } else {
      Data(~[])
  };
  assert!(io.read_char() == '\r');
  assert!(io.read_char() == '\n');
  return res;
}

priv fn parse_list(len: uint, io: @io::Reader) -> Result {
  let mut list: ~[Result] = ~[];
    for len.times {
    let v =
        match io.read_char() {
        '$' => parse_bulk(io),
        ':' => parse_int(io),
         _ => fail!()
    };
    list.push(v);
    }
  return List(list);
}

priv fn chop(s: ~str) -> ~str {
  s.slice(0, s.len() - 1).to_owned()
}
  
priv fn parse_bulk(io: @io::Reader) -> Result {
    match int::from_str(chop(io.read_line())) {
    None => fail!(),
    Some(-1) => Nil,
    Some(len) if len >= 0 => parse_data(len as uint, io),
    Some(_) => fail!()
    }
}

priv fn parse_multi(io: @io::Reader) -> Result {
    match int::from_str(chop(io.read_line())) {
    None => fail!(),
    Some(-1) => Nil,
    Some(0) => List(~[]),
    Some(len) if len >= 0 => parse_list(len as uint, io),
    Some(_) => fail!()
    }
}

priv fn parse_int(io: @io::Reader) -> Result {
    match int::from_str(chop(io.read_line())) {
    None => fail!(),
    Some(i) => Int(i)
    }
}

priv fn parse_response(io: @io::Reader) -> Result {
    match io.read_char() {
    '$' => parse_bulk(io),
    '*' => parse_multi(io),
    '+' => Status(chop(io.read_line())),
    '-' => Error(chop(io.read_line())),
    ':' => parse_int(io),
    _ => fail!()
    }
}

priv fn cmd_to_str(cmd: ~[~str]) -> ~str {
  let mut res = ~"*";
  str::push_str(&mut res, cmd.len().to_str());
  str::push_str(&mut res, "\r\n");
    for cmd.each |s| {
    str::push_str(&mut res, str::concat(~[~"$", s.len().to_str(), ~"\r\n",
                                          copy *s, ~"\r\n"]));
    }
  res
}

fn query(cmd: ~[~str], sb: TcpSocketBuf) -> Result {
  let cmd = cmd_to_str(cmd);
  //io::println(cmd);
  sb.write_str(cmd);
  let res = parse_response(@sb as @io::Reader);
  //io::println(fmt!("%?", res));
  res
}

fn query2(cmd: ~[~str]) -> Result {
  let _cmd = cmd_to_str(cmd);
    do io::with_str_reader(~"$3\r\nXXX\r\n") |sb| {
    let res = parse_response(@sb as @io::Reader);
    io::println(fmt!("%?", res));
    res
    }
}


fn main() {
}