1#![allow(dead_code)]
3
4use super::{
5 ParseResult,
6 Encoding,
7 PacketVal,
8 Encoder
9};
10use super::opcode::{
11 OpCode,
12 opcode_parse
13};
14use super::nom::{
15 be_u8,
16 be_u16,
17 be_u32,
18 be_u64
19};
20
21
22#[derive(Clone,Debug,PartialEq,Eq)]
26pub struct ReqHeader {
27 code: OpCode,
28 extralen: u8,
29 vbucket_id: u16,
30 keylen: u16,
31 bodylen: u32,
32 opaque: u32,
33 cas: u64
34}
35impl ReqHeader {
36 #[inline]
38 pub fn parse(buffer: &[u8]) -> ParseResult<Self> {
39 ParseResult::from(parse_req_header(buffer))
40 }
41 #[inline(always)]
42 pub fn get_opaque(&self) -> u32 {
43 self.opaque
44 }
45 #[inline(always)]
46 pub fn get_cas(&self) -> u64 {
47 self.cas
48 }
49 #[inline(always)]
50 pub fn get_opcode(&self) -> OpCode {
51 self.code
52 }
53 #[inline(always)]
54 pub fn get_vbucket_id(&self) -> u16 {
55 self.vbucket_id
56 }
57}
58impl PacketVal for ReqHeader {
59 #[inline(always)]
60 fn get_keylen(&self) -> usize {
61 self.keylen as usize
62 }
63 #[inline(always)]
64 fn get_bodylen(&self) -> usize {
65 self.bodylen as usize
66 }
67 #[inline(always)]
68 fn get_extralen(&self) -> usize {
69 self.extralen as usize
70 }
71}
72impl Encoding for ReqHeader {
73 #[inline(always)]
75 fn encode(&self, buffer: &mut Encoder) {
76 let magic = 0x80u8;
77 let datatype = 0x00u8;
78 magic.encode(buffer);
79 self.code.encode(buffer);
80 self.keylen.encode(buffer);
81 self.extralen.encode(buffer);
82 datatype.encode(buffer);
83 self.vbucket_id.encode(buffer);
84 ( (
85 self.get_bodylen() +
86 self.get_keylen() +
87 self.get_extralen()
88 ) as u32).encode(buffer);
89 self.opaque.encode(buffer);
90 self.cas.encode(buffer);
91 }
92}
93
94named!(pub parse_req_header<ReqHeader>, do_parse!(
96 tag!(b"\x80") >>
97 o: opcode_parse >>
98 kl: be_u16 >>
99 el: be_u8 >>
100 tag!(b"\x00") >>
101 vb_id: be_u16 >>
102 bl: be_u32 >>
103 op: be_u32 >>
104 cas: be_u64 >>
105 (
106 ReqHeader{
107 code: o,
108 extralen: el,
109 vbucket_id: vb_id,
110 keylen: kl,
111 bodylen: bl - (kl as u32 + el as u32),
112 opaque: op,
113 cas: cas
114 }
115)));
116
117
118#[inline(always)]
119fn get_len(x: &Option<&[u8]>) -> usize {
120 match x {
121 &Option::Some(ref b) => b.len(),
122 _ => 0
123 }
124}
125
126#[derive(Clone,Debug)]
134pub struct Request<'a> {
135 header: ReqHeader,
136 extra: Option<&'a [u8]>,
137 key: Option<&'a [u8]>,
138 body: Option<&'a [u8]>
139}
140impl<'a> Request<'a> {
141
142 pub fn parse(x: &'a [u8]) -> ParseResult<Self> {
144
145 #[inline(always)]
146 fn to_opt<'b>(z: &'b [u8]) -> Option<&'b [u8]> {
147 if z.len() == 0 {
148 None
149 } else {
150 Some(z)
151 }
152 }
153 named!(parse_request<Request>, do_parse!(
154 h: parse_req_header >>
155 e: take!(h.get_extralen()) >>
156 k: take!(h.get_keylen()) >>
157 b: take!(h.get_bodylen()) >>
158 (Request{
159 header: h,
160 extra: to_opt(e),
161 key: to_opt(k),
162 body: to_opt(b)
163 })
164 ));
165 ParseResult::from(parse_request(x))
166 }
167 #[inline]
179 pub fn new( opcode: OpCode, vbucket: u16, opaque: u32,cas: u64,extra: Option<&'a [u8]>,key: Option<&'a [u8]>,body: Option<&'a [u8]>) -> Request<'a> {
180 let e = get_len(&extra);
181 let k = get_len(&key);
182 let b = get_len(&body);
183 let bl = b + k + e;
184 Request {
185 header:ReqHeader {
186 code: opcode,
187 vbucket_id: vbucket,
188 extralen: e as u8,
189 keylen: k as u16,
190 bodylen: bl as u32,
191 opaque: opaque,
192 cas: cas
193 },
194 extra: extra,
195 key: key,
196 body: body
197 }
198 }
199 #[inline]
217 pub fn rebuild(&mut self,opcode: OpCode, vbucket: u16, opaque: u32,cas: u64,extra: Option<&'a [u8]>,key: Option<&'a [u8]>,body: Option<&'a [u8]>){
218 use std::mem::replace;
219
220 let e = get_len(&extra);
221 let k = get_len(&key);
222 let b = get_len(&body);
223 let bl = b + k + e;
224 self.header.code = opcode;
225 self.header.vbucket_id = vbucket;
226 self.header.extralen = e as u8;
227 self.header.keylen = k as u16;
228 self.header.bodylen = bl as u32;
229 self.header.opaque = opaque;
230 self.header.cas = cas;
231 let _ = replace(&mut self.extra, extra);
232 let _ = replace(&mut self.key, key);
233 let _ = replace(&mut self.body, body);
234 }
235 #[inline]
240 pub fn encode_self(&self) -> Encoder {
241 let mut e = Encoder::new(self);
242 self.encode(&mut e);
243 e
244 }
245 #[inline]
250 pub fn encode_into_buffer(&self, x: Vec<u8>) -> Encoder {
251 let mut e = Encoder::from_vec(self, x);
252 self.encode(&mut e);
253 e
254 }
255 #[inline(always)]
256 pub fn get_opcode(&self) -> OpCode {
257 self.header.get_opcode()
258 }
259 #[inline(always)]
260 pub fn get_opaque(&self) -> u32 {
261 self.header.opaque
262 }
263 #[inline(always)]
264 pub fn get_cas(&self) -> u64 {
265 self.header.cas
266 }
267 #[inline(always)]
268 pub fn get_vbucket_id(&self) -> u16 {
269 self.header.vbucket_id
270 }
271 #[inline(always)]
272 pub fn has_extra(&self) -> bool {
273 self.extra.is_some()
274 }
275 #[inline(always)]
276 pub fn has_key(&self) -> bool {
277 self.key.is_some()
278 }
279 #[inline(always)]
280 pub fn get_extra(&'a self) -> Option<&'a [u8]> {
281 self.extra
282 }
283 #[inline(always)]
284 pub fn get_key(&'a self) -> Option<&'a [u8]> {
285 self.key
286 }
287 #[inline(always)]
296 pub fn get_key_str(&'a self) -> Option<&'a str> {
297 use std::str::from_utf8_unchecked;
298 unsafe{ self.key.map(|x| from_utf8_unchecked(x)) }
299 }
300 #[inline(always)]
301 pub fn has_body(&self) -> bool {
302 self.body.is_some()
303 }
304 #[inline(always)]
305 pub fn get_body(&'a self) -> Option<&'a [u8]> {
306 self.body
307 }
308 #[inline]
315 pub fn to_owned(self) -> OwnedRequest {
316 fn to_vec(x: Option<&[u8]>) -> Vec<u8> {
317 match x {
318 Option::Some(ref b) => {
319 let mut v = Vec::with_capacity(b.len());
320 v.extend_from_slice(b);
321 v
322 },
323 _ => Vec::with_capacity(0)
324 }
325 }
326 OwnedRequest {
327 body: to_vec(self.get_body()),
328 key: to_vec(self.get_key()),
329 extra: to_vec(self.get_extra()),
330 header: self.header,
331 }
332 }
333}
334impl<'a> PacketVal for Request<'a> {
335 #[inline(always)]
337 fn get_keylen(&self) -> usize {
338 self.header.keylen as usize
339 }
340 #[inline(always)]
342 fn get_bodylen(&self) -> usize {
343 self.header.bodylen as usize
344 }
345 #[inline(always)]
347 fn get_extralen(&self) -> usize {
348 self.header.extralen as usize
349 }
350}
351impl<'a> Encoding for Request<'a> {
352 fn encode(&self, buffer: &mut Encoder) {
354 self.header.encode(buffer);
355 self.extra.encode(buffer);
356 self.key.encode(buffer);
357 self.body.encode(buffer);
358 }
359}
360
361#[derive(Clone)]
370pub struct OwnedRequest {
371 header: ReqHeader,
372 pub key: Vec<u8>,
373 pub extra: Vec<u8>,
374 pub body: Vec<u8>
375}
376impl OwnedRequest {
377
378 pub fn parse(x: &[u8]) -> ParseResult<Self> {
382 named!(parse_owned_request<OwnedRequest>, do_parse!(
383 h: parse_req_header >>
384 e: take!(h.get_extralen()) >>
385 k: take!(h.get_keylen()) >>
386 b: take!(h.get_bodylen()) >>
387 (OwnedRequest{
388 header: h,
389 extra: if e.len() == 0 { Vec::with_capacity(0) } else {e.to_vec()},
390 key: if k.len() == 0 { Vec::with_capacity(0) } else { k.to_vec() },
391 body: if b.len() == 0 { Vec::with_capacity(0) } else { b.to_vec() }
392 })
393 ));
394 ParseResult::from(parse_owned_request(x))
395 }
396 #[inline]
408 pub fn new(opcode: OpCode, vbucket: u16, opaque: u32, cas: u64, extra: Vec<u8>, key: Vec<u8>, body: Vec<u8>) -> Self {
409 let e = extra.len();
410 let k = key.len();
411 let b = body.len();
412 let bl = b + k + e;
413 OwnedRequest {
414 header:ReqHeader {
415 code: opcode,
416 vbucket_id: vbucket,
417 extralen: e as u8,
418 keylen: k as u16,
419 bodylen: bl as u32,
420 opaque: opaque,
421 cas: cas
422 },
423 extra: extra,
424 key: key,
425 body: body
426 }
427 }
428 #[inline]
446 pub fn rebuild(&mut self, opcode: OpCode, vbucket: u16, opaque: u32, cas: u64, extra: Vec<u8>, key: Vec<u8>, body: Vec<u8>){
447 use std::mem::replace;
448
449 let e = extra.len();
450 let k = key.len();
451 let b = body.len();
452 let bl = b + k + e;
453 self.header.code = opcode;
454 self.header.vbucket_id = vbucket;
455 self.header.extralen = e as u8;
456 self.header.keylen = k as u16;
457 self.header.bodylen = bl as u32;
458 self.header.opaque = opaque;
459 self.header.cas = cas;
460 let _ = replace(&mut self.extra, extra);
461 let _ = replace(&mut self.key, key);
462 let _ = replace(&mut self.body, body);
463 }
464 #[inline]
469 pub fn encode_self(&self) -> Encoder {
470 let mut e = Encoder::new(self);
471 self.encode(&mut e);
472 e
473 }
474 #[inline]
479 pub fn encode_into_buffer(&self, x: Vec<u8>) -> Encoder {
480 let mut e = Encoder::from_vec(self, x);
481 self.encode(&mut e);
482 e
483 }
484 #[inline(always)]
485 pub fn get_opcode(&self) -> OpCode {
486 self.header.code
487 }
488 #[inline(always)]
489 pub fn get_opaque(&self) -> u32 {
490 self.header.opaque
491 }
492 #[inline(always)]
493 pub fn get_cas(&self) -> u64 {
494 self.header.cas
495 }
496 #[inline(always)]
497 pub fn get_vbucket_id(&self) -> u16 {
498 self.header.vbucket_id
499 }
500 #[inline(always)]
501 pub fn has_extra(&self) -> bool {
502 self.extra.len() != 0
503 }
504 #[inline(always)]
505 pub fn get_extra<'a>(&'a self) -> Option<&'a [u8]> {
506 if self.has_extra() {
507 Some(self.extra.as_slice())
508 } else {
509 None
510 }
511 }
512 #[inline(always)]
513 pub fn has_key(&self) -> bool {
514 self.key.len() != 0
515 }
516 #[inline(always)]
517 pub fn get_key<'a>(&'a self) -> Option<&'a [u8]> {
518 if self.has_key() {
519 Some(self.key.as_slice())
520 } else {
521 None
522 }
523 }
524 #[inline(always)]
533 pub fn get_key_str<'a>(&'a self) -> Option<&'a str> {
534 use std::str::from_utf8_unchecked;
535 unsafe{ self.get_key().map(|x| from_utf8_unchecked(x)) }
536 }
537 #[inline(always)]
538 pub fn has_body(&self) -> bool {
539 self.body.len() != 0
540 }
541 #[inline(always)]
542 pub fn get_body<'a>(&'a self) -> Option<&'a [u8]> {
543 if self.has_body() {
544 Some(self.body.as_slice())
545 } else {
546 None
547 }
548 }
549}
550impl PacketVal for OwnedRequest {
551 #[inline(always)]
553 fn get_keylen(&self) -> usize {
554 self.header.keylen as usize
555 }
556 #[inline(always)]
558 fn get_bodylen(&self) -> usize {
559 self.header.bodylen as usize
560 }
561 #[inline(always)]
563 fn get_extralen(&self) -> usize {
564 self.header.extralen as usize
565 }
566}
567impl Encoding for OwnedRequest {
568 fn encode(&self, buffer: &mut Encoder) {
570 self.header.encode(buffer);
571 self.extra.encode(buffer);
572 self.key.encode(buffer);
573 self.body.encode(buffer);
574 }
575}
576
577