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 // ËÏÎÓÔÒÕËÔÏÒ ËÏÐÉÒÏ×ÁÎÉÑ ÐÏÄÈÏÄÉÔ ÐÏ ÕÍÏÌÞÁÎÉÀ
194 sfinx_timestamp_t() : Timestamp() { mDate = IBPP::MinDate; mTime = 0; }
195 sfinx_timestamp_t(const Timestamp &t) : Timestamp(t) { }
196 sfinx_size_t size() { return (sizeof(mDate) + sizeof(mTime)); }
197 sfinx_size_t get(u8_t *buf) {
199 memcpy(&date, buf, sizeof(date));
200 memcpy(&time, buf + sizeof(date), sizeof(time));
205 sfinx_size_t put(u8_t *buf) {
209 memcpy(buf, &date, sizeof(date));
210 memcpy(buf + sizeof(date), &time, sizeof(time));
214 tm *loctime = localtime(&t);
215 if (!IBPP::itod(&mDate, loctime->tm_year + 1900, loctime->tm_mon + 1, loctime->tm_mday))
216 log("sfinx_timestamp_t", "Out of range");
217 IBPP::itot(&mTime, loctime->tm_hour, loctime->tm_min, loctime->tm_sec, 0);
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, main_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 m) {
245 sfinx_object_t(sfinx_type_t t, sfinx_id_t i, sfinx_id_t m, const char *n, sfinx_timestamp_t &ct,
246 sfinx_timestamp_t &et) {
254 sfinx_size_t size() { return (2 * sizeof(sfinx_id_t) + sizeof(sfinx_type_t) + name.size() + 1 +
255 path_name.size() + 1 + description.size() + 1 + ctime.size() + etime.size()); }
256 sfinx_size_t get(u8_t *buf) {
258 buf += ::get(&id, buf);
259 buf += ::get(&main_slice_id, buf);
260 buf += ::get(&type, buf);
261 buf += ::get(&name, buf);
262 buf += ::get(&path_name, buf);
263 buf += ::get(&description, buf);
264 buf += ctime.get(buf);
265 buf += etime.get(buf);
268 u32_t put(u8_t *buf) {
270 buf += ::put(id, buf);
271 buf += ::put(main_slice_id, buf);
272 buf += ::put(type, buf);
273 buf += ::put(name, buf);
274 buf += ::put(path_name, buf);
275 buf += ::put(description, buf);
276 buf += ctime.put(buf);
277 buf += etime.put(buf);
282 class sfinx_slice_t : public sfinx_t {
284 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
285 if (available_buf_space < size())
288 buf += ::put(id, buf);
289 buf += ::put(parent_id, buf);
290 buf += ::put(name_, buf);
291 buf += ::put(directory_, buf);
292 buf += ::put(description_, buf);
293 buf += ::put(parent_name_, buf);
294 buf += ctime.put(buf);
295 buf += etime.put(buf);
297 u32_t l = objs.size();
298 buf += ::put(l, buf);
299 for (u32_t i = 0; i < l; i++)
300 buf += objs[i].put(buf);
303 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
305 buf += ::get(&id, buf);
306 buf += ::get(&parent_id, buf);
307 buf += ::get(&name_, buf);
308 buf += ::get(&directory_, buf);
309 buf += ::get(&description_, buf);
310 buf += ::get(&parent_name_, buf);
311 buf += ctime.get(buf);
312 buf += etime.get(buf);
315 buf += ::get(&l, buf);
316 for (u32_t i = 0; i < l; i++) {
321 // hmm, ÐÒÏ×ÅÒËÁ ÌÉÛØ × ËÏÎÃÅ
322 if ((sfinx_size_t)(buf - t) > object_size_in_buf)
329 void copy(const sfinx_t *s) {
330 if (!dynamic_cast<const sfinx_slice_t *>(s))
333 const sfinx_slice_t *s_ = (const sfinx_slice_t *)s;
336 directory_ = s_->directory_;
337 parent_name_ = s_->parent_name_;
338 description_ = s_->description_;
339 parent_id = s_->parent_id;
345 string name_, directory_, description_, parent_name_;
346 sfinx_id_t parent_id;
347 sfinx_timestamp_t ctime, etime;
348 vector <sfinx_object_t> objs; // ×ÌÏÖÅÎÎÙÅ × ÓÌÁÊÓ ÏÂØÅËÔÙ
350 const char *name() { return name_.c_str(); }
351 const char *directory() { return directory_.c_str(); }
352 const char *description() { return description_.c_str(); }
353 const char *parent_name() { return parent_name_.c_str(); }
355 void add(sfinx_object_t &obj) { objs.push_back(obj); }
356 void name(const char *s) { name_ = s; size(); }
357 void directory(const char *d) { directory_ = d; size(); }
358 void description(const char *s) { description_ = s; size(); }
359 void parent_name(const char *s) { parent_name_ = s; size(); }
361 sfinx_slice_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid) {
365 sfinx_slice_t(sfinx_slice_t *s) : sfinx_t(SFINX_ELEMENT_SLICE) { copy(s); }
366 sfinx_slice_t(sfinx_id_t id_, string &name__, string &directory__, string &description__,
367 string &parent_name__, sfinx_id_t parent_id, sfinx_timestamp_t ctime_, sfinx_timestamp_t etime_,
368 sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid), id(id_), name_(name__),
369 directory_(directory__), description_(description__), parent_name_(parent_name__),
370 parent_id(parent_id), ctime(ctime_), etime(etime_) { size(); }
371 sfinx_size_t size() {
372 u32_t s = sizeof(u32_t); // ÄÌÉÎÁ ÓÞÅÔÞÉËÁ ÏÂØÅËÔÏ×
373 for (u32_t i = 0; i < objs.size(); i++)
375 return (size_ = sizeof(id) + name_.size() + 1 + directory_.size() + 1 +
376 description_.size() + 1 + parent_name_.size() + 1 + sizeof(parent_id) + ctime.size() +
379 friend class sfinx_slice_vector_t;
382 class sfinx_slice_vector_t : public sfinx_t {
384 vector <sfinx_slice_t *> slices;
386 sfinx_size_t size() {
388 for (u32_t i = 0; i < slices.size(); i++)
389 size_ += slices[i]->size();
392 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
394 for (u32_t i = 0; i < slices.size(); i++) {
395 if (slices[i]->put(buf + offset, available_buf_space) != slices[i]->size())
397 available_buf_space -= slices[i]->size();
398 offset += slices[i]->size();
402 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
404 while (object_size_in_buf) {
405 sfinx_slice_t *slice = new sfinx_slice_t;
406 sfinx_size_t res = slice->get(buf + size(), object_size_in_buf);
407 if (res != slice->size()) {
412 if (object_size_in_buf < slice->size())
414 object_size_in_buf -= slice->size();
419 for (u32_t i = 0; i < slices.size(); i++)
425 void copy(const sfinx_t *s) {
426 const sfinx_slice_vector_t *src = dynamic_cast<const sfinx_slice_vector_t *>(s);
431 for (u32_t i = 0; i < src->slices.size(); i++) {
432 sfinx_slice_t *slice = new sfinx_slice_t(src->slices[i]);
433 slices.push_back(slice);
436 sfinx_slice_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE_VECTOR) : sfinx_t(tid) { }
437 ~sfinx_slice_vector_t() { clear(); }
438 void add(sfinx_slice_t *slice) {
439 sfinx_slice_t *s = new sfinx_slice_t(slice);
440 slices.push_back(s); // ËÏÐÉÒÕÅÍ ÏÂØÅËÔ
441 size_ += slice->size();
443 void add(sfinx_slice_t &slice) { add(&slice); }
444 u32_t len() { return slices.size(); }
445 sfinx_slice_t *get(u32_t idx) { return slices[idx]; }
446 sfinx_slice_t *find(u32_t id) {
447 for (u32_t i = 0; i < slices.size(); i++) {
448 if (id == slices[i]->id)
455 class sfinx_string_t : public sfinx_t {
457 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
458 if (available_buf_space < (s.size() + 1))
463 strcpy((char *)buf, s.c_str());
466 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
471 void copy(const sfinx_t *s_) {
472 if (!dynamic_cast<const sfinx_string_t *>(s_))
475 s = ((const sfinx_string_t *)s_)->s;
477 sfinx_size_t size() { return (size_ = s.size() + 1); }
478 sfinx_string_t(sfinx_tid_t tid = SFINX_ELEMENT_STRING) : sfinx_t(tid) { size_ = 1; }
479 sfinx_string_t(const char *s_) : sfinx_t(SFINX_ELEMENT_STRING) {
483 const char *c_str() { return s.c_str(); }
484 bool get(string &s_) { s_ = s; return true; }
485 bool set(string &s_) {
493 bool set(const char *s_) {
503 // ÐÁÒÁ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
504 class sfinx_pair_t : public sfinx_t {
508 key_ = SFINX_KEY_UNASSIGNED;
514 sfinx_size_t size() { return (size_ = element->size() + 2 * sizeof(u32_t)); } // + element id
515 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
516 if (available_buf_space < size())
518 buf += ::put(key_, buf);
519 sfinx_tid_t eid = element->tid();
520 buf += ::put(eid, buf);
521 //debug("eid - %x, size - %d, space - %d", eid, size(), available_buf_space);
522 if (!element->put(buf, available_buf_space - (sizeof(eid) + sizeof(key_))))
526 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
528 buf += ::get(&key_, buf);
530 buf += ::get(&eid, buf);
531 //debug("eid - %x, size_in_buf - %d", eid, object_size_in_buf);
534 element = make_sfinx_element(eid);
536 element->get(buf, object_size_in_buf - (sizeof(eid) + sizeof(key_)));
542 void copy(const sfinx_t *s) {
543 const sfinx_pair_t *src = dynamic_cast<const sfinx_pair_t *>(s);
548 element = make_sfinx_element(src->element->tid());
551 element->copy(src->element);
554 sfinx_pair_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR) : sfinx_t(tid) {
555 key_ = SFINX_KEY_UNASSIGNED; element = 0;
557 u32_t key() { return key_; }
558 ~sfinx_pair_t() { clear(); }
559 bool get(u32_t k, uint32_t *v) {
562 return element->get(v);
564 bool get(u32_t k, string &s) {
567 return element->get(s);
569 bool get(u32_t k, sfinx_t **el) {
575 bool set(u32_t k, sfinx_t &e) { return set(k, &e); }
576 bool set(u32_t k, sfinx_t *e) {
577 // ÎÅÐÌÏÈÏ ÂÙ ÐÒÏ×ÅÒÉÔØ ÞÔÏ id() != SFINX_ELEMENT_PAIR
579 element = make_sfinx_element(e->tid()); // ÆÁÂÒÉËÁ ÐÕÓÔÙÈ ÅÌÅÍÅÎÔÏ× ÏÐÒ. ÔÉÐÁ
581 element->copy(e); // ÔÉÐÁ ËÏÎÔÓÒÕËÔÏÒ ËÏÐÉÒÏ×ÁÎÉÑ
588 bool set(u32_t k, string &s) {
590 element = new sfinx_string_t;
593 if (!element->set(s))
600 bool set(u32_t k, const char *s) { string t(s); return set(k, t); }
601 bool set(u32_t k, u32_t v) {
603 element = new sfinx_32bit_t;
609 friend class sfinx_pair_vector_t;
612 // ÎÁÂÏÒ ÐÁÒ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
613 class sfinx_pair_vector_t : public sfinx_t {
614 vector <sfinx_pair_t *> pairs;
615 sfinx_size_t size() {
617 for (u32_t i = 0; i < pairs.size(); i++)
618 size_ += pairs[i]->size();
621 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
622 int32_t space = available_buf_space;
624 for (u32_t i = 0; i < pairs.size(); i++) {
625 u32_t sz = pairs[i]->put(buf + offset, available_buf_space - offset);
626 if (!sz || ((space - sz) < 0))
633 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
634 int32_t space = object_size_in_buf;
638 sfinx_pair_t *pair = new sfinx_pair_t; // id ÔÅÒÑÅÍ
639 int32_t sz = pair->get(buf + offset, object_size_in_buf - offset);
641 if (!sz || (space - sz) < 0)
643 pairs.push_back(pair);
644 size_ += pair->size();
646 //debug("offset - %d, all_size - %d, space - %d", offset, object_size_in_buf, space);
652 for (u32_t i = 0; i < pairs.size(); i++)
657 void copy(const sfinx_t *s) {
658 const sfinx_pair_vector_t *src = dynamic_cast<const sfinx_pair_vector_t *>(s);
663 for (u32_t i = 0; i < src->pairs.size(); i++)
664 if (!add(src->pairs[i]))
667 sfinx_pair_t *find(u32_t k) {
668 for (u32_t i = 0; i < pairs.size(); i++) {
669 if (k == pairs[i]->key())
674 u32_t len() { return pairs.size(); }
675 bool find(u32_t k, u32_t *idx) {
676 for (u32_t i = 0; i < pairs.size(); i++) {
677 if (k == pairs[i]->key()) {
684 sfinx_pair_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR_VECTOR) : sfinx_t(tid) { }
685 bool add(sfinx_pair_t *p) {
688 sfinx_pair_t *pair = new sfinx_pair_t(p->tid());
690 pairs.push_back(pair);
691 size_ += pair->size();
694 // returns false on error (key exists)
695 bool add(u32_t k, sfinx_t *e) {
698 sfinx_pair_t *p = new sfinx_pair_t;
708 // return false if key not found
709 bool get(u32_t k, uint32_t *v) {
710 sfinx_pair_t *pair = find(k);
713 return pair->get(k, v);
715 bool get(u32_t k, string &s) {
716 sfinx_pair_t *pair = find(k);
719 return pair->get(k, s);
722 // bool get(u32_t k, sfinx_t *s) {
723 // sfinx_pair_t *pair = find(k);
726 // return pair->get(k, s);
729 bool add(u32_t k, uint32_t v) {
732 sfinx_pair_t *pair = new sfinx_pair_t;
737 bool add(u32_t k, string &s) {
740 sfinx_pair_t *pair = new sfinx_pair_t;
745 bool add(u32_t k, const char *s) { string t(s); return add(k, t); }
748 class sfinx_file_t : public sfinx_t {
749 sfinx_size_t size() {
750 u32_t objs_size = sizeof(u32_t); // obj counter
751 for (u32_t i = 0; i < objects.size(); i++)
752 objs_size += objects[i].size();
753 return (size_ = 4 * sizeof(sfinx_id_t) + 2 * sizeof(sfinx_size_t) + objs_size +
754 name.size() + 1 + orig_name.size() + 1 + title.size() + 1 + authority.size() + 1 +
755 description.size() + 1 + comments.size() + 1 + ctime.size() + etime.size() +
756 4 * sizeof(u8_t) + mimetype.size() + 1 + csum.size() + 1 + compressed_csum.size() + 1);
758 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
759 if (size() > available_buf_space)
761 buf += ::put(file_id, buf);
762 u8_t v = is_directory;
763 buf += ::put(v, buf);
765 buf += ::put(v, buf);
766 v = store_compressed;
767 buf += ::put(v, buf);
769 buf += ::put(v, buf);
770 buf += ::put(main_obj_id, buf);
771 buf += ::put(main_obj_type, buf);
772 buf += ::put(main_slice_id, buf);
773 buf += ::put(fsize, buf);
774 buf += ::put(compressed_fsize, buf);
775 u32_t t = objects.size();
776 buf += ::put(t, buf);
777 for (u32_t i = 0; i < objects.size(); i++)
778 buf += objects[i].put(buf);
779 buf += ::put(name, buf);
780 buf += ::put(orig_name, buf);
781 buf += ::put(title, buf);
782 buf += ::put(authority, buf);
783 buf += ::put(description, buf);
784 buf += ::put(comments, buf);
785 buf += ::put(mimetype, buf);
786 buf += ::put(csum, buf);
787 buf += ::put(compressed_csum, buf);
788 buf += ctime.put(buf);
789 buf += etime.put(buf);
792 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
795 buf += ::get(&file_id, buf);
797 buf += ::get(&v, buf);
799 buf += ::get(&v, buf);
801 buf += ::get(&v, buf);
802 store_compressed = v;
803 buf += ::get(&v, buf);
805 buf += ::get(&main_obj_id, buf);
806 buf += ::get(&main_obj_type, buf);
807 buf += ::get(&main_slice_id, buf);
808 buf += ::get(&fsize, buf);
809 buf += ::get(&compressed_fsize, buf);
811 buf += ::get(&objects_size, buf);
812 for (u32_t i = 0; i < objects_size; i++) {
815 objects.push_back(o);
817 buf += ::get(&name, buf);
818 buf += ::get(&orig_name, buf);
819 buf += ::get(&title, buf);
820 buf += ::get(&authority, buf);
821 buf += ::get(&description, buf);
822 buf += ::get(&comments, buf);
823 buf += ::get(&mimetype, buf);
824 buf += ::get(&csum, buf);
825 buf += ::get(&compressed_csum, buf);
826 buf += ctime.get(buf);
827 buf += etime.get(buf);
828 if (size() != (sfinx_size_t)(buf - tmp))
835 file_id = main_obj_type = main_obj_id = fsize = 0;
836 is_directory = false;
838 } void copy(const sfinx_t *s) {
839 const sfinx_file_t *src = dynamic_cast<const sfinx_file_t *>(s);
843 ((sfinx_t *)s)->size();
845 file_id = src->file_id;
846 main_obj_id = src->main_obj_id;
847 main_obj_type = src->main_obj_type;
848 main_slice_id = src->main_slice_id;
850 compressed_fsize = src->compressed_fsize;
852 orig_name = src->orig_name;
854 authority = src->authority;
855 description = src->description;
856 comments = src->comments;
859 objects = src->objects;
860 is_directory = src->is_directory;
861 sorted_location = src->sorted_location;
862 store_compressed = src->store_compressed;
863 generate_csum = src->generate_csum;
864 mimetype = src->mimetype;
866 compressed_csum = src->compressed_csum;
868 sfinx_id_t file_id, main_obj_id, main_obj_type, main_slice_id;
869 sfinx_size_t fsize, compressed_fsize;
870 string name, orig_name, title, authority, description, comments, mimetype, csum,
872 sfinx_timestamp_t ctime, etime;
873 bool is_directory, sorted_location, store_compressed, generate_csum;
874 vector <sfinx_object_t> objects; // ÍÁÓÓÉ× ÔÉÐÏ× É id ÄÏÐÏÌÎÉÔÅÌØÎÙÈ ÏÂØÅËÔÏ×
875 sfinx_file_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE) : sfinx_t(tid) { clear(); }
876 const char *sidstr() { return "File"; }
878 friend class sfinx_files_vector_t;
881 class sfinx_files_vector_t : public sfinx_t {
883 for (u32_t i = 0; i < files.size(); i++)
888 sfinx_size_t size() {
890 for (u32_t i = 0; i < files.size(); i++)
891 size_ += files[i]->size();
894 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
895 int32_t space = available_buf_space;
897 for (u32_t i = 0; i < files.size(); i++) {
898 int32_t sz = files[i]->put(buf + offset, available_buf_space - offset);
899 if (!sz || ((space - sz) < 0))
906 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
907 int32_t space = object_size_in_buf;
911 sfinx_file_t *file = new sfinx_file_t;
912 int32_t sz = file->get(buf + offset, object_size_in_buf - offset);
916 if ((space - sz) < 0)
918 files.push_back(file);
919 size_ += file->size();
925 void copy(const sfinx_t *s) {
926 const sfinx_files_vector_t *src = dynamic_cast<const sfinx_files_vector_t *>(s);
931 for (u32_t i = 0; i < src->files.size(); i++)
932 if (!add(src->files[i]))
935 vector <sfinx_file_t *> files;
936 sfinx_files_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE_VECTOR) : sfinx_t(tid) { clear(); }
937 ~sfinx_files_vector_t() { clear(); }
938 bool add(sfinx_file_t &f) { return add(&f); }
939 bool add(sfinx_file_t *f) {
940 sfinx_file_t *nf = new sfinx_file_t;
949 class sfinx_note_t : public sfinx_t {
950 sfinx_size_t size() {
951 return (size_ = sizeof(u32_t) * 4 + name.size() + 1 + url.size() + 1 + text.size() + 1 +
952 sizeof(u8_t) + ctime.size() + etime.size());
954 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
955 if (size() > available_buf_space)
957 buf += ::put(id, buf);
958 buf += ::put(main_obj_id, buf);
959 buf += ::put(main_obj_type, buf);
960 buf += ::put(main_slice_id, buf);
961 buf += ::put(name, buf);
962 buf += ::put(url, buf);
963 buf += ::put(text, buf);
964 buf += ::put(secured, buf);
965 buf += ctime.put(buf);
966 buf += etime.put(buf);
967 u32_t x = tags.size();
968 buf += ::put(x, buf);
969 for (u32_t i = 0; i < x; i++)
970 buf += tags[i].put(buf);
973 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
975 buf += ::get(&id, buf);
976 buf += ::get(&main_obj_id, buf);
977 buf += ::get(&main_obj_type, buf);
978 buf += ::get(&main_slice_id, buf);
979 buf += ::get(&name, buf);
980 buf += ::get(&url, buf);
981 buf += ::get(&text, buf);
982 buf += ::get(&secured, buf);
983 buf += ctime.get(buf);
984 buf += etime.get(buf);
986 buf += ::get(&x, buf);
987 for (u32_t i = 0; i < x; i++) {
992 if (size() != (sfinx_size_t)(buf - tmp))
997 void copy(const sfinx_t *s) {
998 const sfinx_note_t *src = dynamic_cast<const sfinx_note_t *>(s);
1001 ((sfinx_t *)s)->size();
1004 main_obj_id = src->main_obj_id;
1005 main_obj_type = src->main_obj_type;
1006 main_slice_id = src->main_slice_id;
1010 secured = src->secured;
1015 sfinx_id_t id, main_obj_id, main_obj_type, main_slice_id;
1016 string name, url, text;
1017 u8_t secured; // 0 - none, 1 - crypted text, 2 - crypted text + url, 3 - all crypted
1018 sfinx_timestamp_t ctime, etime;
1019 vector <sfinx_object_t> tags;
1020 sfinx_note_t(sfinx_tid_t tid = SFINX_ELEMENT_NOTE) : sfinx_t(tid) { size(); }
1021 // sfinx_note_t(sfinx_id_t id_, sfinx_id_t mobj_id, sfinx_id_t mobj_type,
1022 // sfinx_id_t mslice_id, string n, sfinx_timestamp_t ct, sfinx_timestamp_t et) :
1023 // sfinx_t(SFINX_ELEMENT_NOTE), id(id_), main_obj_id(mobj_id), main_obj_type(mobj_type),
1024 // main_slice_id(mslice_id), name(n), ctime(ct), etime(et) { }
1029 class sfinx_progress_t : public sfinx_t {
1031 string label_, strval_;
1032 u8_t status_, type_, precision_;
1033 float max_, val_, old_val;
1034 sfinx_size_t size() {
1035 return (size_ = 3 * sizeof(u8_t) + label_.size() + 1 + 2 * sizeof(float));
1037 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1039 buf += ::get(&label_, buf);
1040 buf += ::get(&status_, buf);
1041 buf += ::get(&type_, buf);
1042 buf += ::get(&precision_, buf);
1043 buf += ::get(&max_, buf);
1044 buf += ::get(&val_, buf);
1045 if (size() != (sfinx_size_t)(buf - tmp))
1049 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1050 if (size() > available_buf_space)
1052 buf += ::put(label_, buf);
1053 buf += ::put(status_, buf);
1054 buf += ::put(type_, buf);
1055 buf += ::put(precision_, buf);
1056 buf += ::put(max_, buf);
1057 buf += ::put(val_, buf);
1061 void copy(const sfinx_t *s) {
1062 const sfinx_progress_t *src = dynamic_cast<const sfinx_progress_t *>(s);
1066 label_ = src->label_;
1067 status_ = src->status_;
1071 precision_ = src->precision_;
1073 sfinx_progress_t(sfinx_tid_t tid = SFINX_ELEMENT_PROGRESS) : sfinx_t(tid) {
1074 val_ = max_ = old_val = 0;
1075 type_ = SFINX_PROGRESS_PERCENT;
1077 status_ = SFINX_PROGRESS_NONE;
1080 void precision(char p) { precision_ = p; }
1081 void type(char t) { type_ = t; }
1082 sfinx_progress_t(const char *l) : sfinx_t(SFINX_ELEMENT_PROGRESS) {
1084 val_ = max_ = old_val = 0;
1085 type_ = SFINX_PROGRESS_PERCENT;
1087 status_ = SFINX_PROGRESS_START;
1090 void max(float m) { max_ = m; status_ = SFINX_PROGRESS_START; }
1091 float max() { return max_; }
1092 float value() { return val_; }
1093 const char *strvalue() {
1096 case SFINX_PROGRESS_PERCENT:
1097 sprintf(buf, "%.*f %%", (int) precision_, (val_/max_) * 100.0);
1099 case SFINX_PROGRESS_INTEGER:
1100 sprintf(buf, "%d", (int) val_);
1102 case SFINX_PROGRESS_FLOAT:
1103 sprintf(buf, "%.*f", (int) precision_, val_);
1107 return strval_.c_str();
1109 void end() { status_ = SFINX_PROGRESS_END; };
1110 int status() { return status_; }
1111 const char *label() { return label_.c_str(); }
1112 // p - percent offset - ÅÓÌÉ ÚÎÁÞÅÎÉÅ ÉÚÍÅÎÉÌÏÓØ ÂÏÌÅÅ ÞÅÍ ÎÁ p - return true
1113 bool set(float v, float p) {
1115 if (fabsf((v - old_val)/100.0) >= p) {
1126 class sfinx_search_query_t : public sfinx_t {
1128 vector <u32_t> areas;
1131 sfinx_size_t size() { return (size_ = pattern.size() + 1); }
1132 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1133 if (size() > available_buf_space)
1135 buf += ::put(pattern, buf);
1138 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1139 buf += ::get(&pattern, buf);
1143 void copy(const sfinx_t *s) {
1144 const sfinx_search_query_t *q = dynamic_cast<const sfinx_search_query_t *>(s);
1148 pattern = q->pattern;
1152 sfinx_search_query_t(sfinx_tid_t tid = SFINX_ELEMENT_SEARCH_QUERY) : sfinx_t(tid) { size(); }
1153 void add_area(u32_t area) { areas.push_back(area); }
1156 static sfinx_t *make_sfinx_element(sfinx_tid_t tid)
1159 case SFINX_ELEMENT_8BIT:
1160 case SFINX_ACCESS_GRANTED:
1161 case SFINX_ACCESS_DENIED:
1162 case SFINX_SLICES_MODULE_TREE_REQUEST:
1163 case SFINX_FILES_MODULE_CONF_REQUEST:
1164 return new sfinx_8bit_t(tid);
1165 case SFINX_ELEMENT_32BIT:
1166 case SFINX_DELETE_SLICE_WITH_REATTACH:
1167 case SFINX_DELETE_SLICE_ASSOC_DATA:
1168 case SFINX_DELETE_SLICE_ASSOC_DATA_RECURSIVLY:
1169 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED:
1170 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED_RECURSIVLY:
1171 case SFINX_DELETE_SLICE_RECURSIVLY:
1172 case SFINX_EDIT_SLICE_REQUEST:
1173 case SFINX_SLICES_MODULE_TREE_REQUEST_EXCEPT:
1174 case SFINX_OBJECTS_TREE_REQUEST:
1175 return new sfinx_32bit_t(tid);
1176 case SFINX_ELEMENT_8BIT_VECTOR:
1177 case SFINX_DAEMON_VERSION:
1178 case SFINX_PACKET_CRYPT_TYPES:
1179 case SFINX_MIN_AUTH_LEVELS:
1181 case SFINX_AUTH_REQUEST:
1182 return new sfinx_8bit_vector_t(tid);
1183 case SFINX_ELEMENT_SLICE:
1184 case SFINX_EDIT_SLICE:
1185 case SFINX_NEW_SLICE:
1186 case SFINX_SLICE_RELINK:
1187 case SFINX_NOTES_MODULE_TREE_REQUEST:
1188 return new sfinx_slice_t(tid);
1189 case SFINX_ELEMENT_SLICE_VECTOR:
1190 case SFINX_SLICES_MODULE_TREE:
1191 case SFINX_SLICES_MODULE_TREE_EXCEPT:
1192 case SFINX_NOTES_MODULE_TREE:
1193 case SFINX_OBJECTS_TREE:
1194 return new sfinx_slice_vector_t(tid);
1195 case SFINX_ELEMENT_PAIR:
1196 return new sfinx_pair_t(tid);
1197 case SFINX_ELEMENT_PAIR_VECTOR:
1198 case SFINX_FILES_MODULE_CONF:
1199 return new sfinx_pair_vector_t(tid);
1200 case SFINX_ELEMENT_STRING:
1202 case SFINX_FILES_MODULE_CLASSIFY_REPLY:
1203 case SFINX_FILES_MODULE_EDIT_REPLY:
1204 case SFINX_NOTES_MODULE_ADD_REPLY:
1205 case SFINX_NOTES_MODULE_EDIT_REPLY:
1206 case SFINX_FILES_MODULE_UNLINK:
1207 return new sfinx_string_t(tid);
1208 case SFINX_ELEMENT_FILE_VECTOR:
1209 case SFINX_FILES_MODULE_SORTED_TREE:
1210 case SFINX_FILES_MODULE_UNSORTED_TREE:
1211 return new sfinx_files_vector_t(tid);
1212 case SFINX_ELEMENT_PROGRESS:
1213 return new sfinx_progress_t(tid);
1214 case SFINX_ELEMENT_FILE:
1215 case SFINX_FILES_MODULE_CLASSIFY_REQUEST:
1216 case SFINX_FILES_MODULE_SORTED_TREE_REQUEST:
1217 case SFINX_FILES_MODULE_UNSORTED_TREE_REQUEST:
1218 case SFINX_FILES_MODULE_EDIT_FILE_REQUEST:
1219 case SFINX_FILES_MODULE_EDIT_FILE:
1220 case SFINX_FILES_MODULE_SORTED_UNLINK:
1221 case SFINX_FILES_MODULE_UNSORT:
1222 return new sfinx_file_t(tid);
1223 case SFINX_ELEMENT_SEARCH_QUERY:
1224 return new sfinx_search_query_t(tid);
1225 case SFINX_ELEMENT_SEARCH_RESULT:
1226 return new sfinx_pair_vector_t(tid);
1227 case SFINX_NOTES_MODULE_ADD:
1228 return new sfinx_note_t(tid);
1230 debug("Unknown element id 0x%x", tid);
1235 //sfinx_32bit_vector_t
1237 //sfinx_64bit_vector_t
1239 //sfinx_float_vector_t
1241 //sfinx_double_vector_t
1242 //sfinx_string_vector_t
1244 //sfinx_date_vector_t
1247 // TODO: - support for 64 bit lengths/values
1249 // ÎÅËÉÊ ÂÕÆÅÒ ÉÚ sfinx ÜÌÅÍÅÎÔÏ×
1250 class sfinx_elements {
1252 sfinx_size_t data_offset_, allocated_size_;
1254 u32_t n_elements, current_element;
1256 vector <sfinx_t *> elements;
1257 // u32_t curr_offset;
1260 u32_t count(sfinx_tid_t tid) {
1262 for (u32_t i = 0; i < elements.size(); i++) {
1263 if (elements[i]->tid() == tid)
1269 if (current_element == elements.size())
1272 return elements[current_element++];
1274 sfinx_t *get(sfinx_tid_t el_id, u32_t el_offset = 0) {
1275 for (u32_t i = 0; i < elements.size(); i++) {
1277 if (elements[i]->tid() == el_id) {
1286 // parse elements from binary buffer
1287 bool parse(u8_t *buf, u32_t buf_len) {
1288 u32_t current_position = 0;
1289 current_element = 0;
1290 s32_t buf_len_ = buf_len;
1294 u8_t first_byte = buf[current_position]; // id byte
1295 u8_t id_len = decoded_size(first_byte);
1296 memcpy(((u8_t *)&id_be32) + (sizeof(u32_t) - id_len), buf + current_position, id_len);
1297 sfinx_tid_t id = decode(id_be32, id_len);
1298 current_position += id_len;
1301 first_byte = buf[current_position]; // len byte
1302 u8_t len_size = decoded_size(first_byte);
1303 memcpy(((u8_t *)&len_be32) + (sizeof(u32_t) - len_size), buf + current_position, len_size);
1304 u32_t len = decode(len_be32, len_size);
1305 current_position += len_size;
1306 buf_len_ -= (id_len + len_size + len);
1307 //debug("got object id %s, id_len - %d, len_size - %d, object len - %d, buf_len - %d",
1308 // sfinx_cmd2str(id), id_len, len_size, len, buf_len);
1310 debug("Obj %s has zero len", sfinx_cmd2str(id));
1312 debug("Too small buf len");
1317 el = make_sfinx_element(id);
1321 sfinx_size_t copied = el->get(buf + current_position, len);
1322 if (copied != len) {
1323 debug("%s parsing error, copied %lld from %d !", sfinx_cmd2str(id), copied, len);
1328 elements.push_back(el);
1329 debug("parsed ok: object: %s, len - %d", sfinx_cmd2str(id), len);
1330 } // else buf_len is ok
1332 current_position += len;
1336 sfinx_elements() { buf_ = 0; clear(); }
1337 ~sfinx_elements() { clear(); }
1338 static s8_t decoded_size(u8_t first_byte) {
1340 for (s8_t size = 0; size < 4; size++) {
1341 if (first_byte & (mask >> size))
1346 static s8_t coded_size(u32_t val) {
1347 if (val < 0x7F) // 2^7 - 1
1349 else if (val < 0x3FFFL) // 2^14 - 1
1351 else if (val < 0x1FFFFFL) // 2^21 - 1
1353 else if (val < 0x0FFFFFFFL) // 2^28 - 1
1358 // code value in utf8-like manner
1359 // returns be32 value
1360 static u32_t code(u32_t val, s8_t *coded_size_ = 0) {
1361 s8_t _coded_size_ = coded_size(val);
1362 if (_coded_size_ < 1)
1364 u8_t msb = (val >> ((_coded_size_ - 1) * 8)) & 0xFF;
1366 msb &= (0xFF >> (_coded_size_ - 1));
1367 msb |= (0x80 >> (_coded_size_ - 1));
1368 val &= ~(0xFFL << ((_coded_size_ - 1) * 8));
1369 val |= (msb << ((_coded_size_ - 1) * 8));
1371 *coded_size_ = _coded_size_;
1374 static u32_t decode(u32_t val_be32, s8_t decode_size) {
1375 val_be32 &= ~((0x80000000L >> (8 * (decode_size - 1))) >> (decode_size - 1));
1376 return ntohl(val_be32);
1379 data_offset_ = allocated_size_ = 0;
1384 for (u32_t i = 0; i < elements.size(); i++)
1387 current_element = 0;
1389 int add(sfinx_t &el) { return add(&el); }
1390 int add(sfinx_t *element) {
1391 s8_t element_id_size = -1, element_length_size = -1;
1392 u32_t coded_id_be32 = code(element->tid(), &element_id_size),
1393 coded_element_length_be32 = code(element->size(), &element_length_size);
1394 if ((element_id_size < 0) || (element_length_size < 0))
1396 sfinx_size_t space = element->size() + data_offset_ + element_id_size + element_length_size;
1397 if (space > allocated_size_) {
1399 u8_t *buf = new u8_t[space];
1400 if (allocated_size_) {
1401 memcpy(buf, buf_, allocated_size_);
1404 allocated_size_ = space;
1408 memcpy(buf_ + data_offset_, ((u8_t *)&coded_id_be32) + (sizeof(u32_t) - element_id_size),
1410 data_offset_ += element_id_size;
1411 // add element length
1412 memcpy(buf_ + data_offset_, ((u8_t *)&coded_element_length_be32) + (sizeof(u32_t) -
1413 element_length_size), element_length_size);
1414 data_offset_ += element_length_size;
1416 sfinx_size_t res = element->put(buf_ + data_offset_, allocated_size_ - data_offset_);
1417 if (res != element->size()) {
1418 debug("%s data copy error: buf_size - %lld, el_size - %lld, copied - %lld",
1419 sfinx_cmd2str(element->tid()), allocated_size_ - data_offset_, element->size(), res);
1422 data_offset_ += element->size();
1423 debug("added %s, el_id_size - %d, el_len - %lld (be_len 0x%x), el_len_size - %d, "
1424 "copied - %lld, data_size in tx_buf - %lld", sfinx_cmd2str(element->tid()),
1425 element_id_size, element->size(), coded_element_length_be32, element_length_size,
1430 sfinx_size_t size() { return data_offset_; }
1431 u8_t *buf() { return buf_; }