implement file tag parsing
[ecparse.git] / CollectionReader.cpp
index 00427ff..d27eba0 100644 (file)
@@ -43,7 +43,7 @@ StringTag* CollectionReader::readStringTag(bool header) {
        growingBuffer.read(&tagLength, 2);
        GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] read tag length %d.\n", __FILE__, __LINE__, tagLength);
        char* tagValue = (char*) malloc(tagLength + 1);
-       if (!ensureBufferCapacity(tagLength)) {
+       if (!ensureBufferCapacity(tagLength) || !tagValue) {
                return NULL;
        }
        growingBuffer.read(tagValue, tagLength);
@@ -187,6 +187,79 @@ ED2KLink* CollectionReader::getNextLink() {
                firstLink = false;
        }
        if (collectionFileIndex < fileCollectionCount) {
+               uint32_t fileTagCount = 0;
+               if (!ensureBufferCapacity(4)) {
+                       return NULL;
+               }
+               growingBuffer.read(&fileTagCount, 4);
+               GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] will read %d file tags.\n", __FILE__, __LINE__, fileTagCount);
+               StringTag* filenameTag = NULL;
+               uint64_t size = 0;
+               HashTag* hashTag = NULL;
+               for (uint32_t fileTagIndex = 0; fileTagIndex < fileTagCount; fileTagIndex++) {
+                       uint8_t tagType = 0;
+                       if (!ensureBufferCapacity(1)) {
+                               return NULL;
+                       }
+                       growingBuffer.read(&tagType, 1);
+                       tagType &= 0x7f;
+                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] reading tag type %d.\n", __FILE__, __LINE__, tagType);
+                       if (tagType == 0x01) {
+                               hashTag = readHashTag();
+                               if (!hashTag) {
+                                       return NULL;
+                               }
+                       } else if (tagType == 0x02) {
+                               StringTag* stringTag = readStringTag();
+                               if (!stringTag) {
+                                       return NULL;
+                               }
+                               if (stringTag->getId() == 0x01) {
+                                       filenameTag = stringTag;
+                                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] read file name ā€œ%sā€.\n", __FILE__, __LINE__, (char*) stringTag->getValue());
+                               } else if (stringTag->getId() == 0xf6) {
+                                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] read file comment ā€œ%sā€.\n", __FILE__, __LINE__, (char*) stringTag->getValue());
+                                       delete stringTag;
+                               }
+                       } else if ((tagType == 0x03) || (tagType == 0x08) || (tagType == 0x09) || (tagType == 0x0b)) {
+                               if (!ensureBufferCapacity(1)) {
+                                       return NULL;
+                               }
+                               uint8_t id = 0;
+                               growingBuffer.read(&id, 1);
+                               if (id == 0x02) {
+                                       int neededBytes = (tagType == 0x03) ? 4 : ((tagType == 0x08) ? 2 : ((tagType == 0x09) ? 1 : 8));
+                                       if (!ensureBufferCapacity(neededBytes)) {
+                                               return NULL;
+                                       }
+                                       growingBuffer.read(&size, neededBytes);
+                                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] file size is %llu bytes.\n", __FILE__, __LINE__, size);
+                               } else if (id == 0xf7) {
+                                       uint8_t fileRating = 0;
+                                       if (!ensureBufferCapacity(1)) {
+                                               return NULL;
+                                       }
+                                       growingBuffer.read(&fileRating, 1);
+                                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] read file rating %d.\n", __FILE__, __LINE__, fileRating);
+                               }
+                       }
+               }
+               collectionFileIndex++;
+               growingBuffer.cut();
+               if (filenameTag && hashTag) {
+                       ED2KLink* ed2kLink = new ED2KLink((char*) filenameTag->getValue(), size, hashTag->getValue());
+                       delete filenameTag;
+                       delete hashTag;
+                       return ed2kLink;
+               } else {
+                       GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] not enough data to decode file.\n", __FILE__, __LINE__);
+               }
+               if (filenameTag) {
+                       delete filenameTag;
+               }
+               if (hashTag) {
+                       delete hashTag;
+               }
        } else {
                GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] reached end of collection.\n", __FILE__, __LINE__);
        }