📄 stringpool.cxx
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <string.h>#include <unistd.h>#include <erosimg/App.hxx>#include <erosimg/Intern.hxx>#include <erosimg/StringPool.hxx>StringPool::StringPool(){ for (int i = 0; i < nPockets; i++) poolTable[i] = 0; poolsz = 0; poolLimit = 0; pool = 0; Add(InternedString("")); /* empty string is ALWAYS first! */}StringPool::~StringPool(){ for (int i = 0; i < nPockets; i++) { PoolEntry* pe = poolTable[i]; while (pe) { PoolEntry *npe = pe->pNext; delete pe; pe = npe; } } delete pool;}voidStringPool::reinit(){ if (pool) { for (int i = 0; i < nPockets; i++) { PoolEntry* pe = poolTable[i]; poolTable[i] = 0; while (pe) { PoolEntry *npe = pe->pNext; delete pe; pe = npe; } } delete pool; poolsz = 0; poolLimit = 0; pool = 0; } Add(InternedString("")); /* empty string is ALWAYS first! */}intStringPool::Lookup(const InternedString& is){ int pocket = is.Signature() % nPockets; PoolEntry *pe = poolTable[pocket]; while (pe) { if (pe->signature == is.Signature() && strcmp(is.str(), pool + pe->offset) == 0) return pe->offset; pe = pe->pNext; } return -1;}intStringPool::Add(const InternedString& is){ int pos = Lookup(is); if (pos != -1) return pos; int pocket = is.Signature() % nPockets; PoolEntry *pe = new PoolEntry; pe->signature = is.Signature(); pe->offset = poolsz; pe->pNext = poolTable[pocket]; poolTable[pocket] = pe; /* Now copy the string! */ const char *s = is.str(); int len = strlen(s); int need = len + 1; /* terminating null! */ int avail = poolLimit - poolsz; if (avail < need) { while (avail < need) { poolLimit += 4096; avail = poolLimit - poolsz; } char *newPool = new char[poolLimit]; /* buffer contains nulls, so must use memcpy!! */ if (pool) memcpy(newPool, pool, poolsz); delete [] pool; pool = newPool; } pos = poolsz; strcpy(pool + pos, s); /* copies trailing null */ poolsz += need;/* Diag::printf("Pool 0x08%x: add string \"%s\"\n", this, s); */ return pos;}InternedStringStringPool::Get(int offset) const{ if (offset < poolsz) return InternedString(&pool[offset]); return InternedString();}intStringPool::WriteToFile(int fd){ return ::write(fd, pool, poolsz);}/* This takes advantage of the fact that the logic for adding new * strings is append-always. */boolStringPool::ReadFromFile(int sfd, int len){ reinit(); char *tmpPool = new char[len]; if ( ::read(sfd, tmpPool, len) != len ) return false; /* Run through the temporary pool, interning all the strings and * adding them to the current pool. This works only because the * pool implementation is append-only and we are starting from an * empty pool: */ int offset = 0; while (offset < len) { InternedString is(&tmpPool[offset]); Add(is); offset += strlen(is.str()); offset += 1; } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -