3 * Copyright (C) 2007, Rus V. Brushkoff, All rights reserved.
7 // - ËÏÎÃÅÐÃÉÑ ÂÕÆÅÒÁ : buf->get/put(sfinx_t)
8 // - rewrite using text or binary XML (ebml) data format
9 // - fix all id's and sizes to 64 bit values
14 #include <arpa/inet.h>
27 typedef unsigned int u32_t;
28 typedef signed int s32_t;
29 typedef unsigned short u16_t;
30 typedef signed short s16_t;
31 typedef unsigned long long u64_t;
32 typedef signed long long s64_t;
33 typedef unsigned char u8_t;
34 typedef signed char s8_t;
36 // ÉÄÅÎÔÉÆÉËÁÔÏÒÙ ÏÂØÅËÔÏ×
37 typedef u32_t sfinx_tid_t;
38 typedef u64_t sfinx_id_t;
39 typedef u64_t sfinx_size_t;
41 typedef u32_t sfinx_type_t;
46 sfinx_t(const sfinx_t &st) { bug(); }
47 sfinx_t &operator=(const sfinx_t &st) { return operator=(&st); }
48 sfinx_t &operator=(const sfinx_t *st) { bug(); return *this; }
50 // ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÐÅÒÅÄÁÞÉ ÏÂØÅËÔÁ ÞÅÒÅÚ ÂÉÎÁÒÎÙÊ ÂÕÆÅÒ
51 // ×ÏÚ×ÒÁÝÁÅÔ ÒÁÚÍÅÒ ÐÏÌÏÖÅÎÎÙÈ × ÂÕÆÅÒ ÄÁÎÎÙÈ
52 virtual sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) = 0;
53 // ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ×ÏÓÓÔÁÎÏ×ÌÅÎÉÑ ÏÂØÅËÔÁ ÉÚ ÂÉÎÁÒÎÏÇÏ ÂÕÆÅÒÁ
54 // ×ÏÚ×ÒÁÝÁÅÔ ÒÁÚÍÅÒ ×ÙÎÕÔÙÈ ÉÚ ÂÕÆÅÒÁ ÄÁÎÎÙÈ
55 virtual sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) = 0;
59 sfinx_size_t size_; // ÒÁÚÍÅÒ ÏÂØÅËÔÁ × ÂÁÊÔÁÈ
60 sfinx_tid_t tid_; // sfinx element type id
61 void copy_size_tid(const sfinx_t *s) { size_ = s->size_; tid_ = s->tid_; }
66 virtual void copy(const sfinx_t *st) = 0;
68 sfinx_t(sfinx_tid_t _tid) { tid_ = _tid; size_ = 0; }
69 virtual ~sfinx_t() { }
71 sfinx_id_t tid() { return tid_; }
72 void tid(sfinx_id_t t) { tid_ = t; }
74 virtual const char *sidstr() { return "generic sfinx object"; }
75 // update size for object
76 virtual sfinx_size_t size() = 0;
77 // try copy object to string
78 virtual bool get(string &s) { debug("class - %s", typeid(*this).name()); bug(); return false; }
79 // try copy object to u32_t
80 virtual bool get(u32_t *v) { debug("class - %s", typeid(*this).name()); bug(); return false; }
81 // try to copy object from string
82 virtual bool set(string &s) { debug("class - %s", typeid(*this).name()); bug(); return false; }
83 // try to copy object from u32_t
84 virtual bool set(u32_t v) { debug("class - %s", typeid(*this).name()); bug(); return false; }
86 friend class sfinx_pair_t;
87 friend class sfinx_elements;
90 static sfinx_t *make_sfinx_element(sfinx_tid_t tid);
92 class sfinx_8bit_t : public sfinx_t {
94 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
95 if (object_size_in_buf) {
101 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
102 if (available_buf_space) {
109 void copy(const sfinx_t *s) {
110 if (!dynamic_cast<const sfinx_8bit_t *>(s))
113 val_ = ((const sfinx_8bit_t *)s)->val_;
115 sfinx_8bit_t() : sfinx_t(SFINX_ELEMENT_8BIT) { }
116 sfinx_8bit_t(sfinx_tid_t _tid) : sfinx_t(_tid) { }
117 sfinx_size_t size() { return (size_ = sizeof(u8_t)); }
118 u8_t get() { return val_; }
119 void set(u8_t v) { val_ = v; size_ = sizeof(u8_t); }
123 class sfinx_8bit_vector_t : public sfinx_t {
125 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
127 for (sfinx_size_t i = 0; i < object_size_in_buf; i++)
128 val.push_back(buf[i]);
131 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
132 if (available_buf_space < size_)
134 for (sfinx_size_t i = 0; i < size_; i++)
139 void copy(const sfinx_t *s) {
140 if (!dynamic_cast<const sfinx_8bit_vector_t *>(s))
144 for (sfinx_size_t i = 0; i < ((const sfinx_8bit_vector_t *)s)->val.size(); i++)
145 val.push_back(((const sfinx_8bit_vector_t *)s)->val[i]);
147 sfinx_8bit_vector_t(sfinx_tid_t _tid = SFINX_ELEMENT_8BIT_VECTOR) : sfinx_t(_tid) { }
148 void clear() { val.clear(); size_ = 0; }
149 void add(u8_t v) { val.push_back(v); size_+= sizeof(u8_t); }
150 bool set(u8_t *b, sfinx_size_t len) { return (get(b, len) != len); }
151 u8_t get(sfinx_size_t idx) { return val[idx]; }
152 sfinx_size_t size() { return (size_ = val.size()); }
153 sfinx_size_t len() { return size(); }
157 class sfinx_32bit_t : public sfinx_t {
159 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
160 if (object_size_in_buf < sizeof(u32_t))
162 val_ = ((u32_t *)buf)[0];
165 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
166 if (available_buf_space < sizeof(u32_t))
168 ((u32_t *)buf)[0] = val_;
172 void copy(const sfinx_t *s) {
173 if (!dynamic_cast<const sfinx_32bit_t *>(s))
176 val_ = ((const sfinx_32bit_t *)s)->val_;
178 sfinx_32bit_t() : sfinx_t(SFINX_ELEMENT_32BIT) { }
179 sfinx_32bit_t(sfinx_tid_t _tid) : sfinx_t(_tid) { }
180 u32_t get() { return val_; }
181 bool get(u32_t *v) { *v = val_; return 0; }
182 bool set(u32_t v) { val_ = v; size(); return 0; }
183 sfinx_size_t size() { return (size_ = sizeof(u32_t)); }
189 using namespace IBPP;
191 class sfinx_timestamp_t : public Timestamp {
193 sfinx_timestamp_t() : Timestamp() { mDate = IBPP::MinDate; mTime = 0; }
194 //sfinx_timestamp_t(const Timestamp &t) : Timestamp(t) { }
195 sfinx_size_t size() { return (sizeof(mDate) + sizeof(mTime)); }
196 sfinx_size_t get(u8_t *buf) {
198 memcpy(&date, buf, sizeof(date));
199 memcpy(&time, buf + sizeof(date), sizeof(time));
204 sfinx_size_t put(u8_t *buf) {
208 memcpy(buf, &date, sizeof(date));
209 memcpy(buf + sizeof(date), &time, sizeof(time));
213 tm *loctime = localtime(&t);
214 if (!IBPP::itod(&mDate, loctime->tm_year + 1900, loctime->tm_mon + 1, loctime->tm_mday))
215 log("sfinx_timestamp_t", "Out of range");
216 IBPP::itot(&mTime, loctime->tm_hour, loctime->tm_min, loctime->tm_sec, 0);
220 // make some libsfinx include
221 // serialize/deserialize methods
222 extern sfinx_size_t get(sfinx_id_t *v, u8_t *buf);
223 extern sfinx_size_t get(sfinx_type_t *v, u8_t *buf);
224 extern sfinx_size_t get(string *v, u8_t *buf);
225 extern sfinx_size_t get(u8_t *v, u8_t *buf);
226 extern sfinx_size_t get(float *v, u8_t *buf);
227 extern sfinx_size_t put(sfinx_id_t &v, u8_t *buf);
228 extern sfinx_size_t put(sfinx_type_t &v, u8_t *buf);
229 extern sfinx_size_t put(string &v, u8_t *buf);
230 extern sfinx_size_t put(u8_t &v, u8_t *buf);
231 extern sfinx_size_t put(float &v, u8_t *buf);
233 class sfinx_object_t {
235 sfinx_id_t id, slice_id;
237 string name, path_name, description;
238 sfinx_timestamp_t ctime, etime;
239 sfinx_object_t() { id = type = 0; }
240 sfinx_object_t(sfinx_type_t t, sfinx_id_t i, sfinx_id_t s = 0) {
245 sfinx_object_t(sfinx_type_t t, sfinx_id_t i, sfinx_id_t s, const char *n, sfinx_timestamp_t &ct,
246 sfinx_timestamp_t &et) {
254 bool cmp(sfinx_object_t *o) {
255 if ((o->id == id) && (o->type == type) && (o->slice_id == o->slice_id))
259 sfinx_size_t size() { return (2 * sizeof(sfinx_id_t) + sizeof(sfinx_type_t) + name.size() + 1 +
260 path_name.size() + 1 + description.size() + 1 + ctime.size() + etime.size()); }
261 sfinx_size_t get(u8_t *buf) {
263 buf += ::get(&id, buf);
264 buf += ::get(&slice_id, buf);
265 buf += ::get(&type, buf);
266 buf += ::get(&name, buf);
267 buf += ::get(&path_name, buf);
268 buf += ::get(&description, buf);
269 buf += ctime.get(buf);
270 buf += etime.get(buf);
273 u32_t put(u8_t *buf) {
275 buf += ::put(id, buf);
276 buf += ::put(slice_id, buf);
277 buf += ::put(type, buf);
278 buf += ::put(name, buf);
279 buf += ::put(path_name, buf);
280 buf += ::put(description, buf);
281 buf += ctime.put(buf);
282 buf += etime.put(buf);
287 extern char tag2char(sfinx_object_t &tag);
288 extern const char *tagtype2str(sfinx_object_t &tag);
290 class sfinx_slice_t : public sfinx_t {
292 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
293 if (available_buf_space < size())
296 buf += ::put(id, buf);
297 buf += ::put(parent_id, buf);
298 buf += ::put(name_, buf);
299 buf += ::put(directory_, buf);
300 buf += ::put(description_, buf);
301 buf += ::put(parent_name_, buf);
302 buf += ctime.put(buf);
303 buf += etime.put(buf);
305 u32_t l = objs.size();
306 buf += ::put(l, buf);
307 for (u32_t i = 0; i < l; i++)
308 buf += objs[i].put(buf);
311 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
313 buf += ::get(&id, buf);
314 buf += ::get(&parent_id, buf);
315 buf += ::get(&name_, buf);
316 buf += ::get(&directory_, buf);
317 buf += ::get(&description_, buf);
318 buf += ::get(&parent_name_, buf);
319 buf += ctime.get(buf);
320 buf += etime.get(buf);
323 buf += ::get(&l, buf);
324 for (u32_t i = 0; i < l; i++) {
329 // hmm, ÐÒÏ×ÅÒËÁ ÌÉÛØ × ËÏÎÃÅ
330 if ((sfinx_size_t)(buf - t) > object_size_in_buf)
337 void copy(const sfinx_t *s) {
338 if (!dynamic_cast<const sfinx_slice_t *>(s))
341 const sfinx_slice_t *s_ = (const sfinx_slice_t *)s;
344 directory_ = s_->directory_;
345 parent_name_ = s_->parent_name_;
346 description_ = s_->description_;
347 parent_id = s_->parent_id;
353 string name_, directory_, description_, parent_name_;
354 sfinx_id_t parent_id;
355 sfinx_timestamp_t ctime, etime;
356 vector <sfinx_object_t> objs; // ×ÌÏÖÅÎÎÙÅ × ÓÌÁÊÓ ÏÂØÅËÔÙ
357 sfinx_object_t slice_obj;
359 const char *name() { return name_.c_str(); }
360 const char *directory() { return directory_.c_str(); }
361 const char *description() { return description_.c_str(); }
362 const char *parent_name() { return parent_name_.c_str(); }
363 sfinx_object_t *object() {
364 slice_obj.ctime = ctime;
365 slice_obj.etime = etime;
366 slice_obj.name = name_;
367 slice_obj.type = SFINX_SLICE_OBJECT;
368 slice_obj.slice_id = slice_obj.id = id;
369 slice_obj.path_name = directory_;
370 slice_obj.description = description_;
374 void add(sfinx_object_t &obj) { objs.push_back(obj); }
375 void name(const char *s) { name_ = s; size(); }
376 void directory(const char *d) { directory_ = d; size(); }
377 void description(const char *s) { description_ = s; size(); }
378 void parent_name(const char *s) { parent_name_ = s; size(); }
380 sfinx_slice_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid) {
384 sfinx_slice_t(sfinx_slice_t *s) : sfinx_t(SFINX_ELEMENT_SLICE) { copy(s); }
385 sfinx_slice_t(sfinx_id_t id_, string &name__, string &directory__, string &description__,
386 string &parent_name__, sfinx_id_t parent_id, sfinx_timestamp_t ctime_, sfinx_timestamp_t etime_,
387 sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid), id(id_), name_(name__),
388 directory_(directory__), description_(description__), parent_name_(parent_name__),
389 parent_id(parent_id), ctime(ctime_), etime(etime_) { size(); }
390 sfinx_size_t size() {
391 u32_t s = sizeof(u32_t); // ÄÌÉÎÁ ÓÞÅÔÞÉËÁ ÏÂØÅËÔÏ×
392 for (u32_t i = 0; i < objs.size(); i++)
394 return (size_ = sizeof(id) + name_.size() + 1 + directory_.size() + 1 +
395 description_.size() + 1 + parent_name_.size() + 1 + sizeof(parent_id) + ctime.size() +
398 friend class sfinx_slice_vector_t;
401 class sfinx_slice_vector_t : public sfinx_t {
403 vector <sfinx_slice_t *> slices;
405 sfinx_size_t size() {
407 for (u32_t i = 0; i < slices.size(); i++)
408 size_ += slices[i]->size();
411 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
413 for (u32_t i = 0; i < slices.size(); i++) {
414 if (slices[i]->put(buf + offset, available_buf_space) != slices[i]->size())
416 available_buf_space -= slices[i]->size();
417 offset += slices[i]->size();
421 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
423 while (object_size_in_buf) {
424 sfinx_slice_t *slice = new sfinx_slice_t;
425 sfinx_size_t res = slice->get(buf + size(), object_size_in_buf);
426 if (res != slice->size()) {
431 if (object_size_in_buf < slice->size())
433 object_size_in_buf -= slice->size();
438 for (u32_t i = 0; i < slices.size(); i++)
444 void copy(const sfinx_t *s) {
445 const sfinx_slice_vector_t *src = dynamic_cast<const sfinx_slice_vector_t *>(s);
450 for (u32_t i = 0; i < src->slices.size(); i++) {
451 sfinx_slice_t *slice = new sfinx_slice_t(src->slices[i]);
452 slices.push_back(slice);
455 sfinx_slice_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE_VECTOR) : sfinx_t(tid) { }
456 ~sfinx_slice_vector_t() { clear(); }
457 void add(sfinx_slice_t *slice) {
458 sfinx_slice_t *s = new sfinx_slice_t(slice);
459 slices.push_back(s); // ËÏÐÉÒÕÅÍ ÏÂØÅËÔ
460 size_ += slice->size();
462 void add(sfinx_slice_t &slice) { add(&slice); }
463 u32_t len() { return slices.size(); }
464 sfinx_slice_t *get(u32_t idx) { return slices[idx]; }
465 sfinx_slice_t *find(u32_t id) {
466 for (u32_t i = 0; i < slices.size(); i++) {
467 if (id == slices[i]->id)
474 class sfinx_string_t : public sfinx_t {
476 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
477 if (available_buf_space < (s.size() + 1))
482 strcpy((char *)buf, s.c_str());
485 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
490 void copy(const sfinx_t *s_) {
491 if (!dynamic_cast<const sfinx_string_t *>(s_))
494 s = ((const sfinx_string_t *)s_)->s;
496 sfinx_size_t size() { return (size_ = s.size() + 1); }
497 sfinx_string_t(sfinx_tid_t tid = SFINX_ELEMENT_STRING) : sfinx_t(tid) { size_ = 1; }
498 sfinx_string_t(const char *s_) : sfinx_t(SFINX_ELEMENT_STRING) {
502 const char *c_str() { return s.c_str(); }
503 bool get(string &s_) { s_ = s; return true; }
504 bool set(string &s_) {
512 bool set(const char *s_) {
522 // ÐÁÒÁ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
523 class sfinx_pair_t : public sfinx_t {
527 key_ = SFINX_KEY_UNASSIGNED;
533 sfinx_size_t size() { return (size_ = element->size() + 2 * sizeof(u32_t)); } // + element id
534 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
535 if (available_buf_space < size())
537 buf += ::put(key_, buf);
538 sfinx_tid_t eid = element->tid();
539 buf += ::put(eid, buf);
540 //debug("eid - %x, size - %d, space - %d", eid, size(), available_buf_space);
541 if (!element->put(buf, available_buf_space - (sizeof(eid) + sizeof(key_))))
545 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
547 buf += ::get(&key_, buf);
549 buf += ::get(&eid, buf);
550 //debug("eid - %x, size_in_buf - %d", eid, object_size_in_buf);
553 element = make_sfinx_element(eid);
555 element->get(buf, object_size_in_buf - (sizeof(eid) + sizeof(key_)));
561 void copy(const sfinx_t *s) {
562 const sfinx_pair_t *src = dynamic_cast<const sfinx_pair_t *>(s);
567 element = make_sfinx_element(src->element->tid());
570 element->copy(src->element);
573 sfinx_pair_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR) : sfinx_t(tid) {
574 key_ = SFINX_KEY_UNASSIGNED; element = 0;
576 u32_t key() { return key_; }
577 ~sfinx_pair_t() { clear(); }
578 bool get(u32_t k, uint32_t *v) {
581 return element->get(v);
583 bool get(u32_t k, string &s) {
586 return element->get(s);
588 bool get(u32_t k, sfinx_t **el) {
594 bool set(u32_t k, sfinx_t &e) { return set(k, &e); }
595 bool set(u32_t k, sfinx_t *e) {
596 // ÎÅÐÌÏÈÏ ÂÙ ÐÒÏ×ÅÒÉÔØ ÞÔÏ id() != SFINX_ELEMENT_PAIR
598 element = make_sfinx_element(e->tid()); // ÆÁÂÒÉËÁ ÐÕÓÔÙÈ ÅÌÅÍÅÎÔÏ× ÏÐÒ. ÔÉÐÁ
600 element->copy(e); // ÔÉÐÁ ËÏÎÔÓÒÕËÔÏÒ ËÏÐÉÒÏ×ÁÎÉÑ
607 bool set(u32_t k, string &s) {
609 element = new sfinx_string_t;
612 if (!element->set(s))
619 bool set(u32_t k, const char *s) { string t(s); return set(k, t); }
620 bool set(u32_t k, u32_t v) {
622 element = new sfinx_32bit_t;
628 friend class sfinx_pair_vector_t;
631 // ÎÁÂÏÒ ÐÁÒ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
632 class sfinx_pair_vector_t : public sfinx_t {
633 vector <sfinx_pair_t *> pairs;
634 sfinx_size_t size() {
636 for (u32_t i = 0; i < pairs.size(); i++)
637 size_ += pairs[i]->size();
640 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
641 int32_t space = available_buf_space;
643 for (u32_t i = 0; i < pairs.size(); i++) {
644 u32_t sz = pairs[i]->put(buf + offset, available_buf_space - offset);
645 if (!sz || ((space - sz) < 0))
652 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
653 int32_t space = object_size_in_buf;
657 sfinx_pair_t *pair = new sfinx_pair_t; // id ÔÅÒÑÅÍ
658 int32_t sz = pair->get(buf + offset, object_size_in_buf - offset);
660 if (!sz || (space - sz) < 0)
662 pairs.push_back(pair);
663 size_ += pair->size();
665 //debug("offset - %d, all_size - %d, space - %d", offset, object_size_in_buf, space);
671 for (u32_t i = 0; i < pairs.size(); i++)
676 void copy(const sfinx_t *s) {
677 const sfinx_pair_vector_t *src = dynamic_cast<const sfinx_pair_vector_t *>(s);
682 for (u32_t i = 0; i < src->pairs.size(); i++)
683 if (!add(src->pairs[i]))
686 sfinx_pair_t *find(u32_t k) {
687 for (u32_t i = 0; i < pairs.size(); i++) {
688 if (k == pairs[i]->key())
693 u32_t len() { return pairs.size(); }
694 bool find(u32_t k, u32_t *idx) {
695 for (u32_t i = 0; i < pairs.size(); i++) {
696 if (k == pairs[i]->key()) {
703 sfinx_pair_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR_VECTOR) : sfinx_t(tid) { }
704 bool add(sfinx_pair_t *p) {
707 sfinx_pair_t *pair = new sfinx_pair_t(p->tid());
709 pairs.push_back(pair);
710 size_ += pair->size();
713 // returns false on error (key exists)
714 bool add(u32_t k, sfinx_t *e) {
717 sfinx_pair_t *p = new sfinx_pair_t;
727 // return false if key not found
728 bool get(u32_t k, uint32_t *v) {
729 sfinx_pair_t *pair = find(k);
732 return pair->get(k, v);
734 bool get(u32_t k, string &s) {
735 sfinx_pair_t *pair = find(k);
738 return pair->get(k, s);
741 // bool get(u32_t k, sfinx_t *s) {
742 // sfinx_pair_t *pair = find(k);
745 // return pair->get(k, s);
748 bool add(u32_t k, uint32_t v) {
751 sfinx_pair_t *pair = new sfinx_pair_t;
756 bool add(u32_t k, string &s) {
759 sfinx_pair_t *pair = new sfinx_pair_t;
764 bool add(u32_t k, const char *s) { string t(s); return add(k, t); }
767 class sfinx_file_t : public sfinx_t {
768 sfinx_size_t size() {
769 u32_t tags_size = sizeof(u32_t); // obj counter
770 for (u32_t i = 0; i < tags.size(); i++)
771 tags_size += tags[i].size();
772 return (size_ = sizeof(sfinx_id_t) + mtag.size() + 2 * sizeof(sfinx_size_t) + tags_size +
773 name.size() + 1 + orig_name.size() + 1 + title.size() + 1 + authority.size() + 1 +
774 description.size() + 1 + comments.size() + 1 + ctime.size() + etime.size() +
775 4 * sizeof(u8_t) + mimetype.size() + 1 + csum.size() + 1 + compressed_csum.size() + 1);
777 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
778 if (size() > available_buf_space)
780 buf += ::put(id, buf);
781 u8_t v = is_directory;
782 buf += ::put(v, buf);
784 buf += ::put(v, buf);
785 v = store_compressed;
786 buf += ::put(v, buf);
788 buf += ::put(v, buf);
789 buf += mtag.put(buf);
790 buf += ::put(fsize, buf);
791 buf += ::put(compressed_fsize, buf);
792 u32_t t = tags.size();
793 buf += ::put(t, buf);
794 for (u32_t i = 0; i < tags.size(); i++)
795 buf += tags[i].put(buf);
796 buf += ::put(name, buf);
797 buf += ::put(orig_name, buf);
798 buf += ::put(title, buf);
799 buf += ::put(authority, buf);
800 buf += ::put(description, buf);
801 buf += ::put(comments, buf);
802 buf += ::put(mimetype, buf);
803 buf += ::put(csum, buf);
804 buf += ::put(compressed_csum, buf);
805 buf += ctime.put(buf);
806 buf += etime.put(buf);
809 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
812 buf += ::get(&id, buf);
814 buf += ::get(&v, buf);
816 buf += ::get(&v, buf);
818 buf += ::get(&v, buf);
819 store_compressed = v;
820 buf += ::get(&v, buf);
822 buf += mtag.get(buf);
823 buf += ::get(&fsize, buf);
824 buf += ::get(&compressed_fsize, buf);
826 buf += ::get(&tags_size, buf);
827 for (u32_t i = 0; i < tags_size; i++) {
832 buf += ::get(&name, buf);
833 buf += ::get(&orig_name, buf);
834 buf += ::get(&title, buf);
835 buf += ::get(&authority, buf);
836 buf += ::get(&description, buf);
837 buf += ::get(&comments, buf);
838 buf += ::get(&mimetype, buf);
839 buf += ::get(&csum, buf);
840 buf += ::get(&compressed_csum, buf);
841 buf += ctime.get(buf);
842 buf += etime.get(buf);
843 if (size() != (sfinx_size_t)(buf - tmp))
850 id = mtag.type = mtag.id = fsize = 0;
851 is_directory = false;
853 } void copy(const sfinx_t *s) {
854 const sfinx_file_t *src = dynamic_cast<const sfinx_file_t *>(s);
858 ((sfinx_t *)s)->size();
863 compressed_fsize = src->compressed_fsize;
865 orig_name = src->orig_name;
867 authority = src->authority;
868 description = src->description;
869 comments = src->comments;
873 is_directory = src->is_directory;
874 sorted_location = src->sorted_location;
875 store_compressed = src->store_compressed;
876 generate_csum = src->generate_csum;
877 mimetype = src->mimetype;
879 compressed_csum = src->compressed_csum;
883 sfinx_size_t fsize, compressed_fsize;
884 string name, orig_name, title, authority, description, comments, mimetype, csum,
886 sfinx_timestamp_t ctime, etime;
887 bool is_directory, sorted_location, store_compressed, generate_csum;
888 vector <sfinx_object_t> tags;
889 sfinx_file_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE) : sfinx_t(tid) { clear(); }
890 const char *sidstr() { return "File"; }
892 friend class sfinx_files_vector_t;
895 class sfinx_files_vector_t : public sfinx_t {
897 for (u32_t i = 0; i < files.size(); i++)
902 sfinx_size_t size() {
904 for (u32_t i = 0; i < files.size(); i++)
905 size_ += files[i]->size();
908 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
909 int32_t space = available_buf_space;
911 for (u32_t i = 0; i < files.size(); i++) {
912 int32_t sz = files[i]->put(buf + offset, available_buf_space - offset);
913 if (!sz || ((space - sz) < 0))
920 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
921 int32_t space = object_size_in_buf;
925 sfinx_file_t *file = new sfinx_file_t;
926 int32_t sz = file->get(buf + offset, object_size_in_buf - offset);
930 if ((space - sz) < 0)
932 files.push_back(file);
933 size_ += file->size();
939 void copy(const sfinx_t *s) {
940 const sfinx_files_vector_t *src = dynamic_cast<const sfinx_files_vector_t *>(s);
945 for (u32_t i = 0; i < src->files.size(); i++)
946 if (!add(src->files[i]))
949 vector <sfinx_file_t *> files;
950 sfinx_files_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE_VECTOR) : sfinx_t(tid) { clear(); }
951 ~sfinx_files_vector_t() { clear(); }
952 bool add(sfinx_file_t &f) { return add(&f); }
953 bool add(sfinx_file_t *f) {
954 sfinx_file_t *nf = new sfinx_file_t;
963 class sfinx_note_t : public sfinx_t {
964 sfinx_size_t size() {
966 u32_t tags_size = sizeof(u32_t);
967 for (u32_t i = 0; i < tags.size(); i++)
968 tags_size += tags[i].size();
969 return (size_ = tags_size + sizeof(sfinx_id_t) + mtag.size() + name.size() + 1 +
970 url.size() + 1 + text.size() + 1 + sizeof(u8_t) + ctime.size() + etime.size());
972 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
973 if (size() > available_buf_space)
975 buf += ::put(id, buf);
976 buf += mtag.put(buf);
977 buf += ::put(name, buf);
978 buf += ::put(url, buf);
979 buf += ::put(text, buf);
980 buf += ::put(secured, buf);
981 buf += ctime.put(buf);
982 buf += etime.put(buf);
983 u32_t x = tags.size();
984 buf += ::put(x, buf);
985 for (u32_t i = 0; i < x; i++)
986 buf += tags[i].put(buf);
989 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
991 buf += ::get(&id, buf);
992 buf += mtag.get(buf);
993 buf += ::get(&name, buf);
994 buf += ::get(&url, buf);
995 buf += ::get(&text, buf);
996 buf += ::get(&secured, buf);
997 buf += ctime.get(buf);
998 buf += etime.get(buf);
1000 buf += ::get(&x, buf);
1001 for (u32_t i = 0; i < x; i++) {
1006 if (size() != (sfinx_size_t)(buf - tmp))
1011 void copy(const sfinx_t *s) {
1012 const sfinx_note_t *src = dynamic_cast<const sfinx_note_t *>(s);
1015 ((sfinx_t *)s)->size();
1022 secured = src->secured;
1028 string name, url, text;
1029 u8_t secured; // 0 - none, 1 - crypted text, 2 - crypted text + url, 3 - all crypted
1030 sfinx_timestamp_t ctime, etime;
1031 sfinx_object_t mtag; // main tag
1032 vector <sfinx_object_t> tags;
1033 sfinx_note_t(sfinx_tid_t tid = SFINX_ELEMENT_NOTE) : sfinx_t(tid) { size(); secured = 0; }
1038 class sfinx_progress_t : public sfinx_t {
1040 string label_, strval_;
1041 u8_t status_, type_, precision_;
1042 float max_, val_, old_val;
1043 sfinx_size_t size() {
1044 return (size_ = 3 * sizeof(u8_t) + label_.size() + 1 + 2 * sizeof(float));
1046 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1048 buf += ::get(&label_, buf);
1049 buf += ::get(&status_, buf);
1050 buf += ::get(&type_, buf);
1051 buf += ::get(&precision_, buf);
1052 buf += ::get(&max_, buf);
1053 buf += ::get(&val_, buf);
1054 if (size() != (sfinx_size_t)(buf - tmp))
1058 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1059 if (size() > available_buf_space)
1061 buf += ::put(label_, buf);
1062 buf += ::put(status_, buf);
1063 buf += ::put(type_, buf);
1064 buf += ::put(precision_, buf);
1065 buf += ::put(max_, buf);
1066 buf += ::put(val_, buf);
1070 void copy(const sfinx_t *s) {
1071 const sfinx_progress_t *src = dynamic_cast<const sfinx_progress_t *>(s);
1075 label_ = src->label_;
1076 status_ = src->status_;
1080 precision_ = src->precision_;
1082 sfinx_progress_t(sfinx_tid_t tid = SFINX_ELEMENT_PROGRESS) : sfinx_t(tid) {
1083 val_ = max_ = old_val = 0;
1084 type_ = SFINX_PROGRESS_PERCENT;
1086 status_ = SFINX_PROGRESS_NONE;
1089 void precision(char p) { precision_ = p; }
1090 void type(char t) { type_ = t; }
1091 sfinx_progress_t(const char *l) : sfinx_t(SFINX_ELEMENT_PROGRESS) {
1093 val_ = max_ = old_val = 0;
1094 type_ = SFINX_PROGRESS_PERCENT;
1096 status_ = SFINX_PROGRESS_START;
1099 void max(float m) { max_ = m; status_ = SFINX_PROGRESS_START; }
1100 float max() { return max_; }
1101 float value() { return val_; }
1102 const char *strvalue() {
1105 case SFINX_PROGRESS_PERCENT:
1106 sprintf(buf, "%.*f %%", (int) precision_, (val_/max_) * 100.0);
1108 case SFINX_PROGRESS_INTEGER:
1109 sprintf(buf, "%d", (int) val_);
1111 case SFINX_PROGRESS_FLOAT:
1112 sprintf(buf, "%.*f", (int) precision_, val_);
1116 return strval_.c_str();
1118 void end() { status_ = SFINX_PROGRESS_END; };
1119 int status() { return status_; }
1120 const char *label() { return label_.c_str(); }
1121 // p - percent offset - ÅÓÌÉ ÚÎÁÞÅÎÉÅ ÉÚÍÅÎÉÌÏÓØ ÂÏÌÅÅ ÞÅÍ ÎÁ p - return true
1122 bool set(float v, float p) {
1124 if (fabsf((v - old_val)/100.0) >= p) {
1135 class sfinx_search_query_t : public sfinx_t {
1137 vector <u32_t> areas;
1140 sfinx_size_t size() { return (size_ = pattern.size() + 1); }
1141 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1142 if (size() > available_buf_space)
1144 buf += ::put(pattern, buf);
1147 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1148 buf += ::get(&pattern, buf);
1152 void copy(const sfinx_t *s) {
1153 const sfinx_search_query_t *q = dynamic_cast<const sfinx_search_query_t *>(s);
1157 pattern = q->pattern;
1161 sfinx_search_query_t(sfinx_tid_t tid = SFINX_ELEMENT_SEARCH_QUERY) : sfinx_t(tid) { size(); }
1162 void add_area(u32_t area) { areas.push_back(area); }
1165 static sfinx_t *make_sfinx_element(sfinx_tid_t tid)
1168 case SFINX_ELEMENT_8BIT:
1169 case SFINX_ACCESS_GRANTED:
1170 case SFINX_ACCESS_DENIED:
1171 // case SFINX_SLICES_MODULE_TREE_REQUEST:
1172 case SFINX_FILES_MODULE_CONF_REQUEST:
1173 return new sfinx_8bit_t(tid);
1174 case SFINX_ELEMENT_32BIT:
1175 case SFINX_DELETE_SLICE_WITH_REATTACH:
1176 case SFINX_DELETE_SLICE_ASSOC_DATA:
1177 case SFINX_DELETE_SLICE_ASSOC_DATA_RECURSIVLY:
1178 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED:
1179 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED_RECURSIVLY:
1180 case SFINX_DELETE_SLICE_RECURSIVLY:
1181 case SFINX_EDIT_SLICE_REQUEST:
1182 // case SFINX_SLICES_MODULE_TREE_REQUEST_EXCEPT:
1183 case SFINX_OBJECTS_TREE_REQUEST:
1184 return new sfinx_32bit_t(tid);
1185 case SFINX_ELEMENT_8BIT_VECTOR:
1186 case SFINX_DAEMON_VERSION:
1187 case SFINX_PACKET_CRYPT_TYPES:
1188 case SFINX_MIN_AUTH_LEVELS:
1190 case SFINX_AUTH_REQUEST:
1191 return new sfinx_8bit_vector_t(tid);
1192 case SFINX_ELEMENT_SLICE:
1193 case SFINX_EDIT_SLICE:
1194 case SFINX_NEW_SLICE:
1195 case SFINX_SLICE_RELINK:
1196 // case SFINX_NOTES_MODULE_TREE_REQUEST:
1197 return new sfinx_slice_t(tid);
1198 case SFINX_ELEMENT_SLICE_VECTOR:
1199 // case SFINX_SLICES_MODULE_TREE:
1200 // case SFINX_SLICES_MODULE_TREE_EXCEPT:
1201 // case SFINX_NOTES_MODULE_TREE:
1202 case SFINX_OBJECTS_TREE:
1203 return new sfinx_slice_vector_t(tid);
1204 case SFINX_ELEMENT_PAIR:
1205 return new sfinx_pair_t(tid);
1206 case SFINX_ELEMENT_PAIR_VECTOR:
1207 case SFINX_FILES_MODULE_CONF:
1208 return new sfinx_pair_vector_t(tid);
1209 case SFINX_ELEMENT_STRING:
1211 case SFINX_FILES_MODULE_CLASSIFY_REPLY:
1212 case SFINX_FILES_MODULE_EDIT_REPLY:
1213 case SFINX_NOTES_MODULE_ADD_REPLY:
1214 case SFINX_NOTES_MODULE_EDIT_REPLY:
1215 case SFINX_NOTES_MODULE_UNLINK_REPLY:
1216 case SFINX_NOTES_MODULE_UNSORT_REPLY:
1217 case SFINX_FILES_MODULE_SORTED_UNLINK_REPLY:
1218 case SFINX_FILES_MODULE_UNSORT_REPLY:
1219 return new sfinx_string_t(tid);
1220 case SFINX_ELEMENT_FILE_VECTOR:
1221 // case SFINX_FILES_MODULE_SORTED_TREE:
1222 case SFINX_FILES_MODULE_UNSORTED_TREE:
1223 return new sfinx_files_vector_t(tid);
1224 case SFINX_ELEMENT_PROGRESS:
1225 return new sfinx_progress_t(tid);
1226 case SFINX_ELEMENT_FILE:
1227 case SFINX_FILES_MODULE_CLASSIFY_REQUEST:
1228 // case SFINX_FILES_MODULE_SORTED_TREE_REQUEST:
1229 case SFINX_FILES_MODULE_UNSORTED_TREE_REQUEST:
1230 case SFINX_FILES_MODULE_EDIT_REQUEST:
1231 case SFINX_FILES_MODULE_EDIT_FILE:
1232 case SFINX_FILES_MODULE_SORTED_UNLINK:
1233 case SFINX_FILES_MODULE_UNSORT:
1234 case SFINX_FILES_MODULE_UNSORTED_DELETE:
1235 return new sfinx_file_t(tid);
1236 case SFINX_ELEMENT_SEARCH_QUERY:
1237 return new sfinx_search_query_t(tid);
1238 case SFINX_ELEMENT_SEARCH_RESULT:
1239 return new sfinx_pair_vector_t(tid);
1240 case SFINX_ELEMENT_NOTE:
1241 case SFINX_NOTES_MODULE_ADD:
1242 case SFINX_NOTES_MODULE_EDIT_REQUEST:
1243 case SFINX_NOTES_MODULE_EDIT:
1244 case SFINX_NOTES_MODULE_UNLINK:
1245 case SFINX_NOTES_MODULE_UNSORT:
1246 return new sfinx_note_t(tid);
1248 debug("Unknown element %s (id 0x%x)", sfinx_cmd2str(tid), tid);
1253 //sfinx_32bit_vector_t
1255 //sfinx_64bit_vector_t
1257 //sfinx_float_vector_t
1259 //sfinx_double_vector_t
1260 //sfinx_string_vector_t
1262 //sfinx_date_vector_t
1265 // TODO: - support for 64 bit lengths/values
1267 // ÎÅËÉÊ ÂÕÆÅÒ ÉÚ sfinx ÜÌÅÍÅÎÔÏ×
1268 class sfinx_elements {
1270 sfinx_size_t data_offset_, allocated_size_;
1272 u32_t n_elements, current_element;
1274 vector <sfinx_t *> elements;
1275 // u32_t curr_offset;
1278 u32_t count(sfinx_tid_t tid) {
1280 for (u32_t i = 0; i < elements.size(); i++) {
1281 if (elements[i]->tid() == tid)
1287 if (current_element == elements.size())
1290 return elements[current_element++];
1292 sfinx_t *get(sfinx_tid_t el_id, u32_t el_offset = 0) {
1293 for (u32_t i = 0; i < elements.size(); i++) {
1295 if (elements[i]->tid() == el_id) {
1304 // parse elements from binary buffer
1305 bool parse(u8_t *buf, u32_t buf_len) {
1306 u32_t current_position = 0;
1307 current_element = 0;
1308 s32_t buf_len_ = buf_len;
1312 u8_t first_byte = buf[current_position]; // id byte
1313 u8_t id_len = decoded_size(first_byte);
1314 memcpy(((u8_t *)&id_be32) + (sizeof(u32_t) - id_len), buf + current_position, id_len);
1315 sfinx_tid_t id = decode(id_be32, id_len);
1316 current_position += id_len;
1319 first_byte = buf[current_position]; // len byte
1320 u8_t len_size = decoded_size(first_byte);
1321 memcpy(((u8_t *)&len_be32) + (sizeof(u32_t) - len_size), buf + current_position, len_size);
1322 u32_t len = decode(len_be32, len_size);
1323 current_position += len_size;
1324 buf_len_ -= (id_len + len_size + len);
1325 debug("got object %s, id_len - %d, len_size - %d, object len - %d, buf_len - %d",
1326 sfinx_cmd2str(id), id_len, len_size, len, buf_len);
1328 debug("Obj %s has zero len", sfinx_cmd2str(id));
1330 debug("Too small buf len");
1335 el = make_sfinx_element(id);
1339 sfinx_size_t copied = el->get(buf + current_position, len);
1340 if (copied != len) {
1341 debug("%s parsing error, copied %lld from %d !", sfinx_cmd2str(id), copied, len);
1346 elements.push_back(el);
1347 debug("parsed ok: object: %s, len - %d", sfinx_cmd2str(id), len);
1348 } // else buf_len is ok
1350 current_position += len;
1354 sfinx_elements() { buf_ = 0; clear(); }
1355 ~sfinx_elements() { clear(); }
1356 static s8_t decoded_size(u8_t first_byte) {
1358 for (s8_t size = 0; size < 4; size++) {
1359 if (first_byte & (mask >> size))
1364 static s8_t coded_size(u32_t val) {
1365 if (val < 0x7F) // 2^7 - 1
1367 else if (val < 0x3FFFL) // 2^14 - 1
1369 else if (val < 0x1FFFFFL) // 2^21 - 1
1371 else if (val < 0x0FFFFFFFL) // 2^28 - 1
1376 // code value in utf8-like manner
1377 // returns be32 value
1378 static u32_t code(u32_t val, s8_t *coded_size_ = 0) {
1379 s8_t _coded_size_ = coded_size(val);
1380 if (_coded_size_ < 1)
1382 u8_t msb = (val >> ((_coded_size_ - 1) * 8)) & 0xFF;
1384 msb &= (0xFF >> (_coded_size_ - 1));
1385 msb |= (0x80 >> (_coded_size_ - 1));
1386 val &= ~(0xFFL << ((_coded_size_ - 1) * 8));
1387 val |= (msb << ((_coded_size_ - 1) * 8));
1389 *coded_size_ = _coded_size_;
1392 static u32_t decode(u32_t val_be32, s8_t decode_size) {
1393 val_be32 &= ~((0x80000000L >> (8 * (decode_size - 1))) >> (decode_size - 1));
1394 return ntohl(val_be32);
1397 data_offset_ = allocated_size_ = 0;
1402 for (u32_t i = 0; i < elements.size(); i++)
1405 current_element = 0;
1407 int add(sfinx_t &el) { return add(&el); }
1408 int add(sfinx_t *element) {
1409 s8_t element_id_size = -1, element_length_size = -1;
1410 u32_t coded_id_be32 = code(element->tid(), &element_id_size),
1411 coded_element_length_be32 = code(element->size(), &element_length_size);
1412 if ((element_id_size < 0) || (element_length_size < 0))
1414 sfinx_size_t space = element->size() + data_offset_ + element_id_size + element_length_size;
1415 if (space > allocated_size_) {
1417 u8_t *buf = new u8_t[space];
1418 if (allocated_size_) {
1419 memcpy(buf, buf_, allocated_size_);
1422 allocated_size_ = space;
1426 memcpy(buf_ + data_offset_, ((u8_t *)&coded_id_be32) + (sizeof(u32_t) - element_id_size),
1428 data_offset_ += element_id_size;
1429 // add element length
1430 memcpy(buf_ + data_offset_, ((u8_t *)&coded_element_length_be32) + (sizeof(u32_t) -
1431 element_length_size), element_length_size);
1432 data_offset_ += element_length_size;
1434 sfinx_size_t res = element->put(buf_ + data_offset_, allocated_size_ - data_offset_);
1435 if (res != element->size()) {
1436 debug("%s data copy error: buf_size - %lld, el_size - %lld, copied - %lld",
1437 sfinx_cmd2str(element->tid()), allocated_size_ - data_offset_, element->size(), res);
1440 data_offset_ += element->size();
1441 debug("sending %s, el_id_size - %d, el_len - %lld (be_len 0x%x), el_len_size - %d, "
1442 "copied - %lld, data_size in tx_buf - %lld", sfinx_cmd2str(element->tid()),
1443 element_id_size, element->size(), coded_element_length_be32, element_length_size,
1448 sfinx_size_t size() { return data_offset_; }
1449 u8_t *buf() { return buf_; }