1258882Semaste/* 2258882Semaste * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3353358Sdim * Distributed under the terms of the MIT License. 4353358Sdim */ 5353358Sdim 6258882Semaste 7258882Semaste#include "UnpackingAttributeDirectoryCookie.h" 8258882Semaste 9258882Semaste#include "DebugSupport.h" 10353358Sdim#include "PackageNode.h" 11258882Semaste#include "Utils.h" 12258882Semaste 13288943Sdim 14288943SdimUnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie( 15258882Semaste PackageNode* packageNode) 16314564Sdim : 17258882Semaste fPackageNode(packageNode), 18327952Sdim fAttribute(NULL), 19341825Sdim fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST) 20321369Sdim{ 21258882Semaste if (fPackageNode != NULL) { 22321369Sdim fPackageNode->AcquireReference(); 23321369Sdim fAttribute = fPackageNode->Attributes().Head(); 24288943Sdim } 25288943Sdim} 26258882Semaste 27258882Semaste 28258882SemasteUnpackingAttributeDirectoryCookie::~UnpackingAttributeDirectoryCookie() 29258882Semaste{ 30258882Semaste if (fPackageNode != NULL) 31353358Sdim fPackageNode->ReleaseReference(); 32314564Sdim} 33314564Sdim 34314564Sdim 35314564Sdim/*static*/ status_t 36314564SdimUnpackingAttributeDirectoryCookie::Open(PackageNode* packageNode, 37314564Sdim AttributeDirectoryCookie*& _cookie) 38258882Semaste{ 39314564Sdim UnpackingAttributeDirectoryCookie* cookie = new(std::nothrow) 40314564Sdim UnpackingAttributeDirectoryCookie(packageNode); 41314564Sdim if (cookie == NULL) 42314564Sdim return B_NO_MEMORY; 43314564Sdim 44314564Sdim _cookie = cookie; 45314564Sdim return B_OK; 46314564Sdim} 47258882Semaste 48258882Semaste 49258882Semastestatus_t 50258882SemasteUnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID, 51353358Sdim struct dirent* buffer, size_t bufferSize, uint32* _count) 52341825Sdim{ 53314564Sdim uint32 maxCount = *_count; 54314564Sdim uint32 count = 0; 55314564Sdim 56314564Sdim dirent* previousEntry = NULL; 57314564Sdim 58314564Sdim while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT || fAttribute != NULL) { 59314564Sdim // don't read more entries than requested 60314564Sdim if (count >= maxCount) 61314564Sdim break; 62314564Sdim 63314564Sdim // align the buffer for subsequent entries 64341825Sdim if (count > 0) { 65258882Semaste addr_t offset = (addr_t)buffer % 8; 66258882Semaste if (offset > 0) { 67314564Sdim offset = 8 - offset; 68353358Sdim if (bufferSize <= offset) 69353358Sdim break; 70353358Sdim 71314564Sdim previousEntry->d_reclen += offset; 72314564Sdim buffer = (dirent*)((addr_t)buffer + offset); 73314564Sdim bufferSize -= offset; 74314564Sdim } 75353358Sdim } 76353358Sdim 77353358Sdim // get the attribute name 78314564Sdim const char* name; 79258882Semaste if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) { 80258882Semaste name = AutoPackageAttributes::NameForAttribute( 81314564Sdim (AutoPackageAttribute)fState); 82314564Sdim } else 83314564Sdim name = fAttribute->Name(); 84353358Sdim 85353358Sdim // fill in the entry name -- checks whether the entry fits into the 86353358Sdim // buffer 87353358Sdim if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) { 88353358Sdim if (count == 0) 89353358Sdim RETURN_ERROR(B_BUFFER_OVERFLOW); 90314564Sdim break; 91258882Semaste } 92258882Semaste 93314564Sdim // fill in the other data 94353358Sdim buffer->d_dev = volumeID; 95353358Sdim buffer->d_ino = nodeID; 96314564Sdim 97353358Sdim count++; 98314564Sdim previousEntry = buffer; 99258882Semaste bufferSize -= buffer->d_reclen; 100258882Semaste buffer = (dirent*)((addr_t)buffer + buffer->d_reclen); 101314564Sdim 102353358Sdim if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) 103353358Sdim fState++; 104353358Sdim else 105314564Sdim fAttribute = fPackageNode->Attributes().GetNext(fAttribute); 106314564Sdim } 107314564Sdim 108314564Sdim *_count = count; 109258882Semaste return B_OK; 110258882Semaste} 111314564Sdim 112353358Sdim 113353358Sdimstatus_t 114314564SdimUnpackingAttributeDirectoryCookie::Rewind() 115258882Semaste{ 116258882Semaste if (fPackageNode != NULL) 117314564Sdim fAttribute = fPackageNode->Attributes().Head(); 118314564Sdim 119314564Sdim fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST; 120353358Sdim 121353358Sdim return B_OK; 122353358Sdim} 123353358Sdim