inline bool check(int m, std::string& a, std::string& b)
{
    std::set<Hash> s;

    Hash hash;
    for (int i = 0; i < m; ++i)
	hash.add(a[i]);
    s.insert(hash);

    for (unsigned i = m, len = a.size(); i < len; ++i) {
	hash.rem(a[i - m], m - 1);
	hash.add(a[i]);
	s.insert(hash);
    }

    hash = Hash();
    for (int i = 0; i < m; ++i) {
	hash.add(b[i]);
    }
    if (s.find(hash) != s.end()) {
	return true;
    }

    for (unsigned i = m, len = b.size(); i < len; ++i) {
	hash.rem(b[i - m], m - 1);
	hash.add(b[i]);
	if (s.find(hash) != s.end())
	    return true;
    }

    return false;
}
예제 #2
0
void FW::profilePush(const char* id)
{
    if (!s_profileStarted)
        return;
    if (!Thread::isMain())
        fail("profilePush() can only be used in the main thread!");

    // Find or create token.

    S32 token;
    S32* found = s_profilePointerToToken.search(id);
    if (found)
        token = *found;
    else
    {
        found = s_profileStringToToken.search(id);
        if (found)
            token = *found;
        else
        {
            token = s_profileStringToToken.getSize();
            s_profileStringToToken.add(id, token);
        }
        s_profilePointerToToken.add(id, token);
    }

    // Find or create timer.

    Vec2i timerKey(-1, token);
    if (s_profileStack.getSize())
        timerKey.x = s_profileStack.getLast();

    S32 timerIdx;
    found = s_profileTimerHash.search(timerKey);
    if (found)
        timerIdx = *found;
    else
    {
        timerIdx = s_profileTimers.getSize();
        s_profileTimerHash.add(timerKey, timerIdx);
        ProfileTimer& timer = s_profileTimers.add();
        timer.id = id;
        timer.parent = timerKey.x;
        if (timerKey.x != -1)
            s_profileTimers[timerKey.x].children.add(timerIdx);
    }

    // Push timer.

    if (s_profileStack.getSize() == 1)
        s_profileTimers[s_profileStack[0]].timer.start();
    s_profileStack.add(timerIdx);
    if (s_profileStack.getSize() > 1)
        s_profileTimers[timerIdx].timer.start();
}
예제 #3
0
int _tmain(int argc, _TCHAR* argv[])
{

	Hash *h = new Hash;
	h->init();
	printf("Reading from file...\n");

	FILE * fd = fopen("FILE.TXT", "r"); 

	char str[100];
	while(fscanf(fd, "%s", str) != EOF)
		h->add(str);

	fclose(fd);

	/*printf("Input word which needs to find\n");
	scanf("%s", str);

	HashList *tmp = h->find(str);
	if (tmp)
		printf("words count is %d\n", tmp->count);
	else
		printf("There is no \"%s\"", str);
	*/
	h->printStats();


	delete h;
	scanf("%*s");

	return 0;
}
예제 #4
0
int main()
{
	cout << "Welcome to this awesome Phone Book\n" << endl;

	Hash hash;
	int choice;
	string name;
	string phone;
	Node* entry;
	do
	{
		menu();
		cin >> choice;
		switch (choice)
		{
		case 1:
			getchar();
			cout << "Name: ";
			getline(cin, name);
			cout << "Phone: ";
			getline(cin, phone);
			entry = new Node();
			entry->name = name;
			entry->phone = phone;
			hash.add(entry);
			break;
		case 2:
			getchar();
			cout << "Enter full name: ";
			getline(cin, name);
			hash.search(name);
			break;
		case 3:
			getchar();
			cout << "Name: ";
			getline(cin, name);
			hash.remove(name);
			break;
		case 4:
			hash.printAll();
			break;
		case 0:
			hash.clearAll();
			break;
		default:
			cout << "Invalid entry. Please try again" << endl;
			break;
		}
	} while (choice != 0);
	
	cout << "Have a good day!" << endl;

	return 0;
}
예제 #5
0
void hashFile(const boost::filesystem::path& path, Hash& algorithm)
{
    std::ifstream fileStream(path.generic_string(), std::ios::binary);
    if(fileStream.is_open()) {
        while(!fileStream.eof()) {
            char buffer[4096];
            fileStream.read(buffer, 4096);
            int bytesRead = fileStream.gcount();
            algorithm.add(buffer, bytesRead);
        }
    }
}
예제 #6
0
void FW::printMemStats(void)
{
#if FW_MEM_DEBUG
    // Create snapshot of the alloc list.

    s_lock.enter();
    AllocHeader* first = NULL;
    for (AllocHeader* src = s_memAllocs.next; src != &s_memAllocs; src = src->next)
    {
        AllocHeader* alloc = (AllocHeader*)::malloc(sizeof(AllocHeader));
        *alloc = *src;
        alloc->next = first;
        first = alloc;
    }
    s_lock.leave();

    // Calculate total size per owner.

    Hash<String, S64> owners;
    for (AllocHeader* alloc = first; alloc;)
    {
        if (!owners.contains(alloc->ownerID))
            owners.add(alloc->ownerID, 0);
        owners[alloc->ownerID] += alloc->size;

        AllocHeader* next = alloc->next;
        ::free(alloc);
        alloc = next;
    }

    // Print.

    printf("\n");
    printf("%-32s%.2f\n", "Memory usage / megs", (F32)s_memoryUsed * exp2(-20));
    for (int slot = owners.firstSlot(); slot != -1; slot = owners.nextSlot(slot))
    {
        const HashEntry<String, S64>& entry = owners.getSlot(slot);
        printf("  %-30s%-12.2f%.0f%%\n",
            entry.key.getPtr(),
            (F32)entry.value * exp2(-20),
            (F32)entry.value / (F32)s_memoryUsed * 100.0f);
    }
    printf("\n");
#endif
}
void App::downscaleTextures(MeshBase* mesh)
{
    FW_ASSERT(mesh);
    Hash<const Image*, Texture> hash;
    for (int submeshIdx = 0; submeshIdx < mesh->numSubmeshes(); submeshIdx++)
    for (int textureIdx = 0; textureIdx < MeshBase::TextureType_Max; textureIdx++)
    {
        Texture& tex = mesh->material(submeshIdx).textures[textureIdx];
        if (tex.exists())
        {
            const Image* orig = tex.getImage();
            if (!hash.contains(orig))
            {
                Image* scaled = orig->downscale2x();
                hash.add(orig, (scaled) ? Texture(scaled, tex.getID()) : tex);
            }
            tex = hash.get(orig);
        }
    }
}
예제 #8
0
void FW::pushMemOwner(const char* id)
{
#if !FW_MEM_DEBUG
    FW_UNREF(id);
#else
    s_lock.enter();
    s_memPushingOwner = true;

    U32 threadID = Thread::getID();
    Array<const char*>* stack = s_memOwnerStacks.search(threadID);
    if (!stack)
    {
        stack = &s_memOwnerStacks.add(threadID);
        stack->clear();
    }
    stack->add(id);

    s_memPushingOwner = false;
    s_lock.leave();
#endif
}
예제 #9
0
void FW::exportWavefrontMesh(BufferedOutputStream& stream, const MeshBase* mesh, const String& fileName)
{
    FW_ASSERT(mesh);
    Mesh<VertexPNT> pnt(*mesh);

    // Extract base name.

    String dirName = fileName.getDirName();
    String baseName = fileName.getFileName();
    int idx = baseName.indexOf('.');
    if (idx != -1)
        baseName = baseName.substring(0, idx);

    // Write OBJ file.

    if (baseName.getLength())
    {
        stream.writef("mtllib %s.mtl\n", baseName.getPtr());
        stream.writef("\n");
    }

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("v %g %g %g\n", v.p.x, v.p.y, v.p.z);
    }
    stream.writef("\n");

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("vt %g %g\n", v.t.x, 1.0f - v.t.y);
    }
    stream.writef("\n");

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("vn %g %g %g\n", v.n.x, v.n.y, v.n.z);
    }

    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        stream.writef("\n");
        if (baseName.getLength())
            stream.writef("usemtl %d\n", i);

        const Array<Vec3i>& tris = pnt.indices(i);
        for (int j = 0; j < tris.getSize(); j++)
        {
            Vec3i v = tris[j] + 1;
            stream.writef("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
                v.x, v.x, v.x,
                v.y, v.y, v.y,
                v.z, v.z, v.z);
        }
    }

    // No base name => do not write materials.

    if (!baseName.getLength())
        return;

    // Hash textures and determine file names.

    Hash<const Image*, String> texImageHash;
    Set<String> texNameSet;

    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        const MeshBase::Material& mat = pnt.material(i);
        for (int j = 0; j < MeshBase::TextureType_Max; j++)
        {
            const Texture& tex = mat.textures[j];
            if (!tex.exists() || texImageHash.contains(tex.getImage()))
                continue;

            // Extract name from ID.

            String name = tex.getID().getFileName();
            int idx = name.indexOf('.');
            if (idx != -1)
                name = name.substring(0, idx);

            // No name => generate one.

            if (!name.getLength())
                name = sprintf("tex%d", texImageHash.getSize());

            // Ensure that the name is unique.

            String oldName = name;
            for (int k = 0; texNameSet.contains(name); k++)
                name = sprintf("%s_%d", oldName.getPtr(), k);

            // Append format postfix.

            name += ".png";

            // Record.

            texImageHash.add(tex.getImage(), name);
            texNameSet.add(name);
        }
    }

    // Write MTL file.

    File mtlFile(dirName + '/' + baseName +  ".mtl", File::Create);
    BufferedOutputStream mtlOut(mtlFile);
    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        if (i)
            mtlOut.writef("\n");

        const MeshBase::Material& mat = pnt.material(i);
        mtlOut.writef("newmtl %d\n", i);
        mtlOut.writef("Ka 0 0 0\n");
        mtlOut.writef("Kd %g %g %g\n", mat.diffuse.x, mat.diffuse.y, mat.diffuse.z);
        mtlOut.writef("d %g\n", mat.diffuse.w);
        mtlOut.writef("Ks %g %g %g\n", mat.specular.x, mat.specular.y, mat.specular.z);
        mtlOut.writef("Ns %g\n", mat.glossiness);

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Diffuse].getImage()))
            mtlOut.writef("map_Kd %s\n", texImageHash[mat.textures[MeshBase::TextureType_Diffuse].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Alpha].getImage()))
            mtlOut.writef("map_d %s\n", texImageHash[mat.textures[MeshBase::TextureType_Alpha].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Displacement].getImage()))
            mtlOut.writef("disp -mm %g %g %s\n",
                mat.displacementBias / mat.displacementCoef, mat.displacementCoef,
                texImageHash[mat.textures[MeshBase::TextureType_Displacement].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Normal].getImage()))
            mtlOut.writef("bump %s\n", texImageHash[mat.textures[MeshBase::TextureType_Normal].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Environment].getImage()))
            mtlOut.writef("refl -type sphere %s\n", texImageHash[mat.textures[MeshBase::TextureType_Environment].getImage()].getPtr());
    }
    mtlOut.flush();

    // Write textures.

    for (int i = texImageHash.firstSlot(); i != -1; i = texImageHash.nextSlot(i))
    {
        const Image* texImage = texImageHash.getSlot(i).key;
        const String& texName = texImageHash.getSlot(i).value;
        exportImage(dirName + '/' + texName, texImage);
    }
}
Image* FW::importTiffImage(InputStream& stream)
{
    // Detect endianess and check format.

    U8 endianTag = stream.readU8();
    Input in(stream, (endianTag == 'I'), 1);
    if ((endianTag != 'I' && endianTag != 'M') || in.readU8() != endianTag || in.readU16() != 42)
        setError("Not a TIFF file!");

    // Read directory header.

    U32 dirOfs = in.readU32();
    in.seek(dirOfs);
    int numEntries = in.readU16();
    if (!dirOfs || !numEntries)
        setError("Corrupt TIFF directory!");

    // Read directory entries.

    Hash<U32, Array<U32> > entries;
    for (int i = 0; i < numEntries && !hasError(); i++)
    {
        U16 tag   = in.readU16();
        U16 type  = in.readU16();
        U32 count = in.readU32();
        U32 ofs   = in.readU32();

        // Check type and count.

        int typeSize;
        switch (type)
        {
        case 1:     typeSize = 1; break;    // BYTE
        case 3:     typeSize = 2; break;    // SHORT
        case 4:     typeSize = 4; break;    // LONG
        default:    typeSize = 0; break;
        }

        if (!typeSize)
            continue;

        // Seek to the value.

        U32 oldOfs = in.tell();
        if (typeSize * count <= 4)
            in.seek(oldOfs - 4);
        else
            in.seek(ofs);

        // Read value.

        Array<U32>& data = entries.add(tag);
        data.resize(count);
        for (int j = 0; j < (int)count; j++)
        {
            switch (typeSize)
            {
            case 1:     data[j] = in.readU8(); break;
            case 2:     data[j] = in.readU16(); break;
            case 4:     data[j] = in.readU32(); break;
            default:    FW_ASSERT(false); break;
            }
        }
        in.seek(oldOfs);
    }

    // Find relevant entries and check their sizes.

    const Array<U32>* width         = entries.search(256);  // ImageWidth
    const Array<U32>* height        = entries.search(257);  // ImageLength
    const Array<U32>* numBits       = entries.search(258);  // BitsPerSample
    const Array<U32>* compression   = entries.search(259);  // Compression
    const Array<U32>* photometric   = entries.search(262);  // PhotometricInterpretation
    const Array<U32>* stripOfs      = entries.search(273);  // StripOffsets
    const Array<U32>* numChannels   = entries.search(277);  // SamplesPerPixel
    const Array<U32>* stripBytes    = entries.search(279);  // StripByteCounts
    const Array<U32>* predictor     = entries.search(317);  // Predictor
    const Array<U32>* extraSamples  = entries.search(338);  // ExtraSamples
    const Array<U32>* sampleFormat  = entries.search(339);  // SampleFormat

    if (!width          || width->getSize()         != 1 ||
        !height         || height->getSize()        != 1 ||
        !numBits        || numBits->getSize()       == 0 ||
        !compression    || compression->getSize()   != 1 ||
        !photometric    || photometric->getSize()   != 1 ||
        !stripOfs       || stripOfs->getSize()      == 0 ||
        !numChannels    || numChannels->getSize()   != 1 ||
        !stripBytes     || stripBytes->getSize()    != stripOfs->getSize() ||
        (predictor      && predictor->getSize()     != 1) ||
        (extraSamples   && extraSamples->getSize()  != 1) ||
        (sampleFormat   && sampleFormat->getSize()  != 1))
    {
        setError("Corrupt TIFF directory!");
    }

    if (hasError())
        return NULL;

    // Interpret size.

    Vec2i size(width->get(0), height->get(0));
    if (size.min() <= 0)
        setError("Invalid TIFF size!");

    // Interpret compression.

    bool packBits = false;
    switch (compression->get(0))
    {
    case 1:     packBits = false; break;
    case 32773: packBits = true; break;
    default:    setError("Unsupported TIFF compression %d!", compression->get(0)); break;
    }

    if (predictor && predictor->get(0) != 1)
        setError("Unsupported TIFF predictor %d!", predictor->get(0));

    // Read color format.

    bool floats = false;
    if (sampleFormat)
    {
        switch (sampleFormat->get(0))
        {
        case 1:     floats = false; break;
        case 3:     floats = true; break;
        default:    setError("Unsupported TIFF sample format %d!", sampleFormat->get(0)); break;
        }
    }

    U32 photo = photometric->get(0);
    int numColor = numChannels->get(0);
    int numAlpha = (extraSamples) ? extraSamples->get(0) : 0;
    if (numBits->getSize() != numColor + numAlpha)
        setError("Invalid TIFF color format!");
    for (int i = 0; i < numBits->getSize(); i++)
        if (numBits->get(i) != ((floats) ? 32u : 8u))
            setError("Invalid TIFF color format!");

    // Interpret color format.

    ImageFormat format;
    switch (photo)
    {
    case 1: // MinIsBlack
        if ((numColor == 0 && numAlpha == 1) || (numColor == 1 && numAlpha == 0))
            format = (floats) ? ImageFormat::A_F32 : ImageFormat::A8;
        else
            setError("Unsupported TIFF monochrome color format!");
        break;

    case 2: // RGB
        if (numColor == 3 && numAlpha == 0)
            format = (floats) ? ImageFormat::RGB_Vec3f : ImageFormat::R8_G8_B8;
        else if ((numColor == 3 && numAlpha == 1) || (numColor == 4 && numAlpha == 0))
            format = (floats) ? ImageFormat::RGBA_Vec4f : ImageFormat::R8_G8_B8_A8;
        else
            setError("Unsupported TIFF RGB color format!");
        break;

    default:
        setError("Unsupported TIFF photometric interpretation %d!", photo);
    }

    // Error => fail.

    if (hasError())
        return NULL;

    // Create image.

    Image* image = new Image(size, format);
    U8* data = image->getMutablePtr();
    const U8* dataEnd = data + image->getStride() * size.y;

    // Read each strip of image data.

    U8* dst = data;
    for (int i = 0; i < stripOfs->getSize() && !hasError(); i++)
    {
        int size = stripBytes->get(i);
        in.seek(stripOfs->get(i));
        const U8* src = in.read(size);
        const U8* srcEnd = src + size;

        // Uncompressed => just read the bytes.

        if (!packBits)
        {
            dst += size;
            if (dst > dataEnd)
                break;
            memcpy(dst - size, src, size);
            continue;
        }

        // PackBits => read each RLE packet.

        while (src < srcEnd)
        {
            int n = *src++;
            if (n < 128)
            {
                n++;
                dst += n;
                src += n;
                if (dst > dataEnd || src > srcEnd)
                    break;
                memcpy(dst - n, src - n, n);
            }
            else if (n > 128)
            {
                n = 257 - n;
                dst += n;
                src++;
                if (dst > dataEnd || src > srcEnd)
                    break;
                memset(dst - n, src[-1], n);
            }
        }

        if (dst > dataEnd || src != srcEnd)
            setError("Corrupt TIFF image data!");
    }

    if (dst != dataEnd)
        setError("Corrupt TIFF image data!");

    // Float-based format => fix endianess.

    if (floats)
        for (U8* ptr = data; ptr < dataEnd; ptr += 4)
            if (endianTag == 'I')
                *(U32*)ptr = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
            else
                *(U32*)ptr = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];

    // Handle errors.

    if (hasError())
    {
        delete image;
        return NULL;
    }
    return image;
}