Commit bc745ae209833d2af5b40f444dde825d02388c28

Authored by David René
1 parent c28ffdfb

Add buffered_connection management. It's useful for parsing Internet protocol with backtracking

Showing 1 changed file with 145 additions and 0 deletions   Show diff stats
anubis_dev/library/tools/buffered_connection.anubis 0 → 100644
  1 +/*
  2 + *
  3 + * User: David RENE
  4 + * Date: 16/08/2009
  5 + * Time: 21:28
  6 + * (c) Calexium
  7 + *
  8 + */
  9 +
  10 +read tools/basis.anubis
  11 +read tools/connections.anubis
  12 +
  13 +public type BC_Result:
  14 + failure,
  15 + timeout,
  16 + success(Word8).
  17 +
  18 +public type BC_Error: //BC for Buffered Connection
  19 + cannot_read_from_connection,
  20 + timeout(Int).
  21 +
  22 +public type Buffered_connection:
  23 + buffered_connection(Connection conn,
  24 + Var(ByteArray) buffer,
  25 + Var(Int) read_pos,
  26 + Var(List(Word8)) unput_buffer).
  27 +
  28 +
  29 +public define One
  30 + unput_byte // unputting a character (add it in front of the list)
  31 + (
  32 + Buffered_connection buf_con,
  33 + Word8 character
  34 + ) =
  35 + buf_con.unput_buffer <- (List(Word8))[character . * buf_con.unput_buffer].
  36 +
  37 +define String
  38 + pid
  39 + =
  40 + "[" + virtual_machine_id + "] ".
  41 +
  42 +
  43 +define One
  44 + put
  45 + (
  46 + ByteArray source,
  47 + ByteArray dest,
  48 + Int position,
  49 + Int i
  50 + ) =
  51 + if nth(i,source) is
  52 + {
  53 + failure then unique,
  54 + success(b) then if put(dest,position,b) is
  55 + {
  56 + failure then unique,
  57 + success(_) then put(source,dest,position+1,i+1)
  58 + }
  59 + }.
  60 +
  61 +define ReadResult
  62 + read_from_connexion
  63 + (
  64 + Buffered_connection connection,
  65 + Int size,
  66 + Int time_out,
  67 + ByteArray result_buffer,
  68 + Int position
  69 + ) =
  70 + //println(pid + "read_from_connexion(" + size + ")");
  71 +
  72 + if *connection.read_pos < length(*connection.buffer) then
  73 + //println(pid + " reading from buffer (size = " + length(*connection.buffer) + ", pos = " + *connection.read_pos);
  74 + //with t1_tmp = (UTime) unow,
  75 + with result = extract(*connection.buffer, *connection.read_pos, *connection.read_pos + size),
  76 + size_read = length(result),
  77 + put(result,result_buffer,position,0);
  78 + connection.read_pos <- *connection.read_pos + size_read;
  79 + //accumulate_t1(t1_tmp);
  80 + if size > size_read then
  81 + //println("Wanted " + size + ", read only " + size_read);
  82 +
  83 + terminal read_from_connexion(connection, size - size_read, time_out, result_buffer,position+size_read)
  84 +// {
  85 +// error then error,
  86 +// timeout then ok(result),
  87 +// ok(ba) then ok(result + ba)
  88 +// }
  89 + else
  90 + ok(result_buffer)
  91 + else
  92 + //if unow > dead_line then record_dubious_connection(connection,dead_line,dos) else
  93 + if read(connection.conn, 16384, time_out) is // the connection is closed after 10 minutes of inactivity
  94 + {
  95 + error then println(pid + "read failed)"); error,
  96 + timeout then timeout,
  97 + ok(ba) then
  98 +// println(pid + "ba = " + length(ba));
  99 + connection.buffer <- ba;
  100 + connection.read_pos <- 0;
  101 + //println(pid + "rb = " + length(*read_buffer));
  102 +
  103 + terminal read_from_connexion(connection, size, time_out, result_buffer,position)
  104 + }.
  105 +
  106 + /** next_char
  107 + * Read char on buffered connection.
  108 + * reading a character (check the list first, and read on the connection
  109 + * only when the list is empty).
  110 + */
  111 +public define BC_Result
  112 + read_byte
  113 + (
  114 + Buffered_connection connection,
  115 + Int t_out
  116 + ) =
  117 + if *connection.unput_buffer is
  118 + {
  119 + [ ] then
  120 + // ///////////////////
  121 + // Buffered reading
  122 + if nth(*connection.read_pos, *connection.buffer) is
  123 + {
  124 + failure then
  125 + if read_from_connexion(connection, 1, t_out, constant_byte_array(1,0),0) is // the connection is closed after 10 minutes of inactivity
  126 + {
  127 + error then failure, //error(cannot_read_from_connection), */
  128 + timeout then timeout, //error(timeout(600)), */
  129 + ok(ba) then if nth(0,ba) is
  130 + {
  131 + failure then failure // error(cannot_read_from_connection),
  132 + success(c) then
  133 + //println("read_byte 1 ["+c+"]");
  134 + success(c)
  135 + }
  136 + },
  137 + success(c) then connection.read_pos <- *connection.read_pos + 1;
  138 + //println("read_byte 2 ["+c+"]");
  139 + success(c)
  140 + },
  141 + [h . t] then
  142 + connection.unput_buffer <- t;
  143 + //println("read byte from unput queue ["+h+"]");
  144 + success(h)
  145 + }.
... ...