YARP
Yet Another Robot Platform
WireBottle.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <cstdio>
11 #include "WireBottle.h"
12 
13 #include <yarp/os/NetInt32.h>
14 #include <yarp/os/Bottle.h>
15 #include <yarp/os/NetType.h>
16 
17 using namespace yarp::os;
18 using namespace yarp::wire_rep_utils;
19 
20 static NetInt32 getInt(char *cursor) {
21  auto* icursor = reinterpret_cast<NetInt32 *> (cursor);
22  return *icursor;
23 }
24 
25 static char *checkBottle(char *cursor, int& remaining, int ct, int list_tag) {
26  while (remaining>0 && ct>0) {
27  ct--;
28  //printf("at %ld : %d : %d\n", (long int) cursor, remaining, list_tag);
29  int tag = 0;
30  if (list_tag!=0) {
31  tag = list_tag;
32  } else {
33  if (remaining<4) {
34  return nullptr;
35  }
36  tag = getInt(cursor);
37  cursor += 4;
38  remaining -= 4;
39  }
40  //printf("tag is %d\n", tag);
41  switch (tag) {
42  case BOTTLE_TAG_INT32:
43  case BOTTLE_TAG_VOCAB:
44  if (remaining<4) { return nullptr; }
45  cursor += 4;
46  remaining -= 4;
47  break;
48  case BOTTLE_TAG_FLOAT64:
49  if (remaining<8) { return nullptr; }
50  cursor += 8;
51  remaining -= 8;
52  break;
53  case BOTTLE_TAG_STRING:
54  case BOTTLE_TAG_BLOB:
55  {
56  if (remaining<4) {
57  return nullptr;
58  }
59  NetInt32 len = getInt(cursor);
60  cursor += 4;
61  remaining -= 4;
62  if (len<0||len>remaining) {
63  return nullptr;
64  }
65  cursor += len;
66  remaining -= len;
67  }
68  break;
69  default:
70  if (tag&BOTTLE_TAG_LIST) {
71  if (remaining<4) {
72  return nullptr;
73  }
74  NetInt32 len = getInt(cursor);
75  cursor += 4;
76  remaining -= 4;
77  cursor = checkBottle(cursor,remaining,len,tag&0xff);
78  if (cursor == nullptr) {
79  return nullptr;
80  }
81  } else {
82  return nullptr;
83  }
84  break;
85  }
86  }
87  if (remaining!=0) { return nullptr; }
88  if (ct!=0) { return nullptr; }
89  return cursor;
90 }
91 
92 bool WireBottle::checkBottle(void *cursor, int len) {
93  int rem = len;
94  return ::checkBottle((char *)cursor,rem,1,0) != nullptr;
95 }
96 
97 bool WireBottle::extractBlobFromBottle(yarp::os::SizedWriter& src,
98  SizedWriterTail& dest) {
99  size_t total_len = 0;
100  for (size_t i=0; i<src.length(); i++) {
101  total_len += src.length(i);
102  }
103  bool has_header = false;
104  int payload_index = 0;
105  int payload_offset = 0;
106  if (src.length(0)>=12) {
107  // could this be a Bottle compatible blob?
108  char *base = (char*)src.data(0);
109  Bytes b1(base,4);
110  Bytes b2(base+4,4);
111  Bytes b3(base+8,4);
112  int i1 = NetType::netInt(b1);
113  int i2 = NetType::netInt(b2);
114  int i3 = NetType::netInt(b3);
115  //dbg_printf(">>> %d %d %d\n", i1, i2, i3);
117  if (i2==1) {
118  if ((size_t)i3==total_len - 12) {
119  // good enough
120  //dbg_printf("Header detected\n");
121  has_header = true;
122  payload_index = 0;
123  payload_offset = 12;
124  }
125  }
126  }
127  }
128  if (has_header) {
129  dest.setDelegate(&src,payload_index,payload_offset);
130  return true;
131  }
132  return false;
133 }
yarp::os::SizedWriter::length
virtual size_t length() const =0
BOTTLE_TAG_LIST
#define BOTTLE_TAG_LIST
Definition: Bottle.h:30
NetInt32.h
BOTTLE_TAG_STRING
#define BOTTLE_TAG_STRING
Definition: Bottle.h:28
getInt
static NetInt32 getInt(char *cursor)
Definition: WireBottle.cpp:20
BOTTLE_TAG_INT32
#define BOTTLE_TAG_INT32
Definition: Bottle.h:23
NetType.h
BOTTLE_TAG_VOCAB
#define BOTTLE_TAG_VOCAB
Definition: Bottle.h:25
yarp::wire_rep_utils::SizedWriterTail
Definition: WireBottle.h:22
yarp::wire_rep_utils::SizedWriterTail::setDelegate
void setDelegate(yarp::os::SizedWriter *delegate, int index, int offset)
Definition: WireBottle.h:27
checkBottle
static char * checkBottle(char *cursor, int &remaining, int ct, int list_tag)
Definition: WireBottle.cpp:25
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
BOTTLE_TAG_BLOB
#define BOTTLE_TAG_BLOB
Definition: Bottle.h:29
BOTTLE_TAG_FLOAT64
#define BOTTLE_TAG_FLOAT64
Definition: Bottle.h:27
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::SizedWriter::data
virtual const char * data(size_t index) const =0
WireBottle.h
yarp::wire_rep_utils
Definition: BlobNetworkHeader.h:18
yarp::os::NetType::netInt
static int netInt(const yarp::os::Bytes &code)
Definition: NetType.cpp:96
Bottle.h
yarp::os::SizedWriter
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:36
yarp::os::NetInt32
std::int32_t NetInt32
Definition of the NetInt32 type.
Definition: NetInt32.h:33