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