Пример #1
0
void VDFileAsync9x::Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize) {
	try {
		mFilename = VDTextWToA(pszFilename);

		const DWORD slowFlags = mbWriteThrough ? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH : FILE_ATTRIBUTE_NORMAL;

		mhFileSlow = CreateFileA(mFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, slowFlags, NULL);
		if (mhFileSlow == INVALID_HANDLE_VALUE)
			throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());

		if (mbUseFastMode)
			mhFileFast = CreateFileA(mFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);

		mSectorSize = 4096;		// guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().

		mBlockSize = bufferSize;
		mBlockCount = count;
		mBuffer.Init(count * bufferSize);

		mState = kStateNormal;
	} catch(const MyError&) {
		Close();
		throw;
	}

	ThreadStart();
}
Пример #2
0
void MRUList::load() {
	clear();

	VDRegistryAppKey key(mpKeyName);
	if (!key.isReady())
		return;

	VDStringA s;
	if (!key.getString("MRUList", s))
		return;

	int nItems = std::min<int>(mMaxCount, s.length());

	mKey.resize(mMaxCount, 0);

	for(int i=0; i<nItems; i++) {
		char name[2]={s[i], 0};

		if (!name[0])
			break;

		if (!key.getString(name, mFiles[i]))
			break;

		mKey[i] = (char)('a'+i);
	}
}
Пример #3
0
void VDFileAsyncNT::Open(VDFileHandle h, uint32 count, uint32 bufferSize) {
	try {
		mFilename = "<anonymous pipe>";

		HANDLE hProcess = GetCurrentProcess();
		if (!DuplicateHandle(hProcess, h, hProcess, &mhFileSlow, 0, FALSE, DUPLICATE_SAME_ACCESS))
			throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());

		mSectorSize = 4096;		// guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().

		mBlockSize = bufferSize;
		mBlockCount = count;
		mBufferSize = mBlockSize * mBlockCount;

		mWriteOffset = 0;
		mBufferLevel = 0;

		mState = kStateNormal;

		if (mhFileFast != INVALID_HANDLE_VALUE) {
			mpBlocks = new VDFileAsyncNTBuffer[count];
			mBuffer.resize(count * bufferSize);
			ThreadStart();
		}
	} catch(const MyError&) {
		Close();
		throw;
	}
}
Пример #4
0
void VDFileAsyncNT::Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize) {
	try {
		mFilename = VDTextWToA(pszFilename);

		mhFileSlow = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (mhFileSlow == INVALID_HANDLE_VALUE)
			throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());

		mhFileFast = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
		if (mhFileFast == INVALID_HANDLE_VALUE)
			mhFileFast = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, NULL);

		mSectorSize = 4096;		// guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().

		mBlockSize = bufferSize;
		mBlockCount = count;
		mBufferSize = mBlockSize * mBlockCount;

		mWriteOffset = 0;
		mBufferLevel = 0;

		mState = kStateNormal;

		if (mhFileFast != INVALID_HANDLE_VALUE) {
			mpBlocks = new VDFileAsyncNTBuffer[count];
			mBuffer.resize(count * bufferSize);
			ThreadStart();
		}
	} catch(const MyError&) {
		Close();
		throw;
	}
}
Пример #5
0
void VDFileAsyncNT::Write(sint64 pos, const void *p, uint32 bytes) {
	Seek(pos);

	DWORD dwActual;
	if (!WriteFile(mhFileSlow, p, bytes, &dwActual, NULL) || (mClientSlowPointer += dwActual),(dwActual != bytes))
		throw MyWin32Error("Write error occurred on file \"%s\": %%s", GetLastError(), mFilename.c_str());
}
Пример #6
0
bool VDRegistryKey::getString(const char *pszName, VDStringA& str) const {
	DWORD type, s = sizeof(DWORD);

	if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, NULL, &s) || type != REG_SZ)
		return false;

	str.resize(s);
	if (RegQueryValueEx((HKEY)pHandle, pszName, 0, NULL, (BYTE *)str.data(), &s))
		return false;

	if (!s)
		str.clear();
	else
		str.resize(strlen(str.c_str()));		// Trim off pesky terminating NULLs.

	return true;
}
Пример #7
0
void VDScriptInterpreter::ExecuteLine(const char *s) {
	int t;

	mErrorExtraToken.clear();

	TokenBegin(s);

	while(t = Token()) {
		if (isExprFirstToken(t)) {
			TokenUnput(t);
			VDASSERT(mStack.empty());
			ParseExpression();

			VDASSERT(!mStack.empty());

			VDScriptValue& val = mStack.back();

			mStack.pop_back();
			VDASSERT(mStack.empty());

			if (Token() != ';')
				SCRIPT_ERROR(SEMICOLON_EXPECTED);
		} else if (t == TOK_DECLARE) {

			do {
				t = Token();

				if (t != TOK_IDENT)
					SCRIPT_ERROR(IDENTIFIER_EXPECTED);

				VariableTableEntry *vte = vartbl.Declare(szIdent);

				t = Token();

				if (t == '=') {
					ParseExpression();

					VDASSERT(!mStack.empty());
					vte->v = mStack.back();
					mStack.pop_back();

					t = Token();
				}

			} while(t == ',');

			if (t != ';')
				SCRIPT_ERROR(SEMICOLON_EXPECTED);

		} else
			SCRIPT_ERROR(PARSE_ERROR);
	}

	VDASSERT(mStack.empty());

	GC();
}
Пример #8
0
sint64 VDFileAsyncNT::GetSize() {
	DWORD dwSizeHigh;
	DWORD dwSizeLow = GetFileSize(mhFileSlow, &dwSizeHigh);

	if (dwSizeLow == (DWORD)-1 && GetLastError() != NO_ERROR)
		throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());

	return dwSizeLow + ((sint64)dwSizeHigh << 32);
}
Пример #9
0
VDStringA VDJob::ToString() const {
	VDStringA s;

	static const char *const kStateNames[]={
		"Waiting",
		"In progress",
		"Completed",
		"Postponed",
		"Aborted",
		"Error",
		"Aborting",
		"Starting",
	};

	VDASSERTCT(sizeof(kStateNames) / sizeof(kStateNames[0]) == kStateCount);

	s.sprintf("%s | %s | %-11s (%s:%d)", mInputFile.c_str(), mOutputFile.c_str(), kStateNames[mState], mRunnerName.c_str(), (uint32)mRunnerId);
	return s;
}
Пример #10
0
	void VDVideoFilterShowInfo::Run() {
		const VDXFBitmap& dst = *fa->mpOutputFrames[0];
		const VDXPixmap& pxdst = *dst.mpPixmap;

		const float size = 8.0f * 8.0f * 20.0f;

		VDPixmap pxdst2;
		pxdst2.data = pxdst.data;
		pxdst2.data2 = pxdst.data2;
		pxdst2.data3 = pxdst.data3;
		pxdst2.pitch = pxdst.pitch;
		pxdst2.pitch2 = pxdst.pitch2;
		pxdst2.pitch3 = pxdst.pitch3;
		pxdst2.format = pxdst.format;
		pxdst2.w = pxdst.w;
		pxdst2.h = pxdst.h;
		pxdst2.palette = pxdst.palette;

		float y = 20.0f;

		for(int lines=0; lines<3; ++lines) {
			switch(lines) {
			case 0:
				mTextLine.sprintf("Source frame: %d (%.3fs)", (int)fa->pfsi->lCurrentSourceFrame, (double)fa->pfsi->lSourceFrameMS / 1000.0);
				break;
			case 1:
				mTextLine.sprintf("Output frame: %d", (int)fa->pfsi->mOutputFrame);
				break;
			case 2:
				mTextLine.sprintf("Sequence frame: %d (%.3fs)", (int)fa->pfsi->lCurrentFrame, (double)fa->pfsi->lDestFrameMS / 1000.0);
				break;
			}

			mRasterizer.Clear();
			VDPixmapConvertTextToPath(mRasterizer, NULL, size, 8.0f * 8.0f * 10.0f, 8.0f * 8.0f * y, mTextLine.c_str());		
			mRasterizer.ScanConvert(mTextRegion);
			VDPixmapConvolveRegion(mShadowRegion, mTextRegion, mShadowBrush);
			VDPixmapFillRegionAntialiased8x(pxdst2, mShadowRegion, 0, 0, 0xFF000000);
			VDPixmapFillRegionAntialiased8x(pxdst2, mTextRegion, 0, 0, 0xFFFFFF00);

			y += 20.0f;
		}
	}
Пример #11
0
void JobAddConfigurationInputs(JobScriptOutput& output, const wchar_t *szFileInput, const wchar_t *pszInputDriver, List2<InputFilenameNode> *pListAppended) {
	do {
		const VDStringA filename(strCify(VDTextWToU8(VDStringW(szFileInput)).c_str()));

		if (g_pInputOpts) {
			int req = g_pInputOpts->write(NULL, 0);

			vdfastvector<char> srcbuf(req);

			int srcsize = g_pInputOpts->write(srcbuf.data(), req);

			if (srcsize) {
				vdfastvector<char> encbuf((srcsize + 2) / 3 * 4 + 1);
				membase64(encbuf.data(), srcbuf.data(), srcsize);

				const VDStringA filename(strCify(VDTextWToU8(VDStringW(szFileInput)).c_str()));

				output.addf("VirtualDub.Open(\"%s\",\"%s\",0,\"%s\");", filename.c_str(), pszInputDriver?strCify(VDTextWToU8(VDStringW(pszInputDriver)).c_str()):"", encbuf.data());
				break;
			}
		}

		output.addf("VirtualDub.Open(\"%s\",\"%s\",0);", filename.c_str(), pszInputDriver?strCify(VDTextWToU8(VDStringW(pszInputDriver)).c_str()):"");

	} while(false);

	if (pListAppended) {
		InputFilenameNode *ifn = pListAppended->AtHead(), *ifn_next;

		if (ifn = ifn->NextFromHead())
			while(ifn_next = ifn->NextFromHead()) {
				output.addf("VirtualDub.Append(\"%s\");", strCify(VDTextWToU8(VDStringW(ifn->name)).c_str()));
				ifn = ifn_next;
			}
	}
}
Пример #12
0
void JobCreateScript(JobScriptOutput& output, const DubOptions *opt, bool bIncludeEditList = true, bool bIncludeTextInfo = true) {
	char *mem= NULL;
	char buf[4096];
	long l;

	int audioSourceMode = g_project->GetAudioSourceMode();

	switch(audioSourceMode) {

	case kVDAudioSourceMode_External:
		{
			const VDStringA& encodedFileName = VDEncodeScriptString(VDStringW(g_szInputWAVFile));
			const VDStringA& encodedDriverName = VDEncodeScriptString(VDTextWToU8(g_project->GetAudioSourceDriverName(), -1));

			// check if we have options to write out
			const InputFileOptions *opts = g_project->GetAudioSourceOptions();
			if (opts) {
				int l;
				char buf[256];

				l = opts->write(buf, (sizeof buf)/7*3);

				if (l) {
					membase64(buf+l, (char *)buf, l);

					output.addf("VirtualDub.audio.SetSource(\"%s\", \"%s\", \"%s\");", encodedFileName.c_str(), encodedDriverName.c_str(), buf+l);
					break;
				}
			}

			// no options
			output.addf("VirtualDub.audio.SetSource(\"%s\", \"%s\");", encodedFileName.c_str(), encodedDriverName.c_str());
		}
		break;

	default:
		if (audioSourceMode >= kVDAudioSourceMode_Source) {
			int index = audioSourceMode - kVDAudioSourceMode_Source;

			if (!index)
				output.addf("VirtualDub.audio.SetSource(1);");
			else
				output.addf("VirtualDub.audio.SetSource(1,%d);", index);
			break;
		}
		// fall through
	case kVDAudioSourceMode_None:
		output.addf("VirtualDub.audio.SetSource(0);");
		break;
	
	}

	output.addf("VirtualDub.audio.SetMode(%d);", opt->audio.mode);

	output.addf("VirtualDub.audio.SetInterleave(%d,%d,%d,%d,%d);",
			opt->audio.enabled,
			opt->audio.preload,
			opt->audio.interval,
			opt->audio.is_ms,
			opt->audio.offset);

	output.addf("VirtualDub.audio.SetClipMode(%d,%d);",
			opt->audio.fStartAudio,
			opt->audio.fEndAudio);

	output.addf("VirtualDub.audio.SetConversion(%d,%d,%d,0,%d);",
			opt->audio.new_rate,
			opt->audio.newPrecision,
			opt->audio.newChannels,
			opt->audio.fHighQuality);

	if (opt->audio.mVolume >= 0.0f)
		output.addf("VirtualDub.audio.SetVolume(%d);", VDRoundToInt(256.0f * opt->audio.mVolume));
	else
		output.addf("VirtualDub.audio.SetVolume();");

	if (g_ACompressionFormat) {
		if (g_ACompressionFormat->mExtraSize) {
			mem = (char *)allocmem(((g_ACompressionFormat->mExtraSize+2)/3)*4 + 1);
			if (!mem) throw MyMemoryError();

			membase64(mem, (char *)(g_ACompressionFormat+1), g_ACompressionFormat->mExtraSize);
			output.addf("VirtualDub.audio.SetCompressionWithHint(%d,%d,%d,%d,%d,%d,%d,\"%s\",\"%s\");"
						,g_ACompressionFormat->mTag
						,g_ACompressionFormat->mSamplingRate
						,g_ACompressionFormat->mChannels
						,g_ACompressionFormat->mSampleBits
						,g_ACompressionFormat->mDataRate
						,g_ACompressionFormat->mBlockSize
						,g_ACompressionFormat->mExtraSize
						,mem
						,VDEncodeScriptString(g_ACompressionFormatHint).c_str()
						);

			freemem(mem);
		} else
			output.addf("VirtualDub.audio.SetCompressionWithHint(%d,%d,%d,%d,%d,%d,\"%s\");"
						,g_ACompressionFormat->mTag
						,g_ACompressionFormat->mSamplingRate
						,g_ACompressionFormat->mChannels
						,g_ACompressionFormat->mSampleBits
						,g_ACompressionFormat->mDataRate
						,g_ACompressionFormat->mBlockSize
						,VDEncodeScriptString(g_ACompressionFormatHint).c_str()
						);
	} else
		output.addf("VirtualDub.audio.SetCompression();");

	output.addf("VirtualDub.audio.EnableFilterGraph(%d);", opt->audio.bUseAudioFilterGraph);

	output.addf("VirtualDub.video.SetInputFormat(%d);", opt->video.mInputFormat);
	output.addf("VirtualDub.video.SetOutputFormat(%d);", opt->video.mOutputFormat);

	output.addf("VirtualDub.video.SetMode(%d);", opt->video.mode);
	output.addf("VirtualDub.video.SetSmartRendering(%d);", opt->video.mbUseSmartRendering);
	output.addf("VirtualDub.video.SetPreserveEmptyFrames(%d);", opt->video.mbPreserveEmptyFrames);

	output.addf("VirtualDub.video.SetFrameRate2(%u,%u,%d);",
			opt->video.mFrameRateAdjustHi,
			opt->video.mFrameRateAdjustLo,
			opt->video.frameRateDecimation);

	if (opt->video.frameRateTargetLo) {
		output.addf("VirtualDub.video.SetTargetFrameRate(%u,%u);",
				opt->video.frameRateTargetHi,
				opt->video.frameRateTargetLo);
	}

	output.addf("VirtualDub.video.SetIVTC(0, 0, 0, 0);");

	if ((g_Vcompression.dwFlags & ICMF_COMPVARS_VALID) && g_Vcompression.fccHandler) {
		output.addf("VirtualDub.video.SetCompression(0x%08lx,%d,%d,%d);",
				g_Vcompression.fccHandler,
				g_Vcompression.lKey,
				g_Vcompression.lQ,
				g_Vcompression.lDataRate);

		l = ICGetStateSize(g_Vcompression.hic);

		if (l>0) {
			mem = (char *)allocmem(l + ((l+2)/3)*4 + 1);
			if (!mem) throw MyMemoryError();

			if (ICGetState(g_Vcompression.hic, mem, l)<0) {
				freemem(mem);
//				throw MyError("Bad state data returned from compressor");

				// Fine then, be that way.  Stupid Pinnacle DV200 driver.
				mem = NULL;
			}

			if (mem) {
				membase64(mem+l, mem, l);
				// urk... Windows Media 9 VCM uses a very large configuration struct (~7K pre-BASE64).
				sprintf(buf, "VirtualDub.video.SetCompData(%d,\"", l);

				VDStringA line(buf);
				line += (mem+l);
				line += "\");";
				output.adds(line.c_str());
				freemem(mem);
			}
		}

	} else
		output.addf("VirtualDub.video.SetCompression();");

	output.addf("VirtualDub.video.filters.Clear();");

	// Add video filters

	FilterInstance *fa = (FilterInstance *)g_listFA.tail.next, *fa_next;
	int iFilter = 0;

	while(fa_next = (FilterInstance *)fa->next) {
		output.addf("VirtualDub.video.filters.Add(\"%s\");", strCify(fa->GetName()));

		if (fa->IsCroppingEnabled()) {
			const vdrect32& cropInsets = fa->GetCropInsets();

			output.addf("VirtualDub.video.filters.instance[%d].SetClipping(%d,%d,%d,%d%s);"
						, iFilter
						, cropInsets.left
						, cropInsets.top
						, cropInsets.right
						, cropInsets.bottom
						, fa->IsPreciseCroppingEnabled() ? "" : ",0"
						);
		}

		VDStringA scriptStr;
		if (fa->GetScriptString(scriptStr))
			output.addf("VirtualDub.video.filters.instance[%d].%s;", iFilter, scriptStr.c_str());

		if (!fa->IsEnabled())
			output.addf("VirtualDub.video.filters.instance[%d].SetEnabled(false);", iFilter);

		VDParameterCurve *pc = fa->GetAlphaParameterCurve();
		if (pc) {
			output.addf("declare curve = VirtualDub.video.filters.instance[%d].AddOpacityCurve();", iFilter);

			const VDParameterCurve::PointList& pts = pc->Points();
			for(VDParameterCurve::PointList::const_iterator it(pts.begin()), itEnd(pts.end()); it!=itEnd; ++it) {
				const VDParameterCurvePoint& pt = *it;

				output.addf("curve.AddPoint(%g, %g, %d);", pt.mX, pt.mY, pt.mbLinear);
			}
		}

		++iFilter;
		fa = fa_next;
	}

	// Add audio filters

	{
		VDAudioFilterGraph::FilterList::const_iterator it(g_audioFilterGraph.mFilters.begin()), itEnd(g_audioFilterGraph.mFilters.end());
		int connidx = 0;
		int srcfilt = 0;

		output.addf("VirtualDub.audio.filters.Clear();");

		for(; it!=itEnd; ++it, ++srcfilt) {
			const VDAudioFilterGraph::FilterEntry& fe = *it;

			output.addf("VirtualDub.audio.filters.Add(\"%s\");", strCify(VDTextWToU8(fe.mFilterName).c_str()));

			for(unsigned i=0; i<fe.mInputPins; ++i) {
				const VDAudioFilterGraph::FilterConnection& conn = g_audioFilterGraph.mConnections[connidx++];
				output.addf("VirtualDub.audio.filters.Connect(%d, %d, %d, %d);", conn.filt, conn.pin, srcfilt, i);
			}

			VDPluginConfig::const_iterator itc(fe.mConfig.begin()), itcEnd(fe.mConfig.end());

			for(; itc!=itcEnd; ++itc) {
				const unsigned idx = (*itc).first;
				const VDPluginConfigVariant& var = (*itc).second;

				switch(var.GetType()) {
				case VDPluginConfigVariant::kTypeU32:
					output.addf("VirtualDub.audio.filters.instance[%d].SetInt(%d, %d);", srcfilt, idx, var.GetU32());
					break;
				case VDPluginConfigVariant::kTypeS32:
					output.addf("VirtualDub.audio.filters.instance[%d].SetInt(%d, %d);", srcfilt, idx, var.GetS32());
					break;
				case VDPluginConfigVariant::kTypeU64:
					output.addf("VirtualDub.audio.filters.instance[%d].SetLong(%d, %I64d);", srcfilt, idx, var.GetU64());
					break;
				case VDPluginConfigVariant::kTypeS64:
					output.addf("VirtualDub.audio.filters.instance[%d].SetLong(%d, %I64d);", srcfilt, idx, var.GetS64());
					break;
				case VDPluginConfigVariant::kTypeDouble:
					output.addf("VirtualDub.audio.filters.instance[%d].SetDouble(%d, %g);", srcfilt, idx, var.GetDouble());
					break;
				case VDPluginConfigVariant::kTypeAStr:
					output.addf("VirtualDub.audio.filters.instance[%d].SetString(%d, \"%s\");", srcfilt, idx, strCify(VDTextWToU8(VDTextAToW(var.GetAStr())).c_str()));
					break;
				case VDPluginConfigVariant::kTypeWStr:
					output.addf("VirtualDub.audio.filters.instance[%d].SetString(%d, \"%s\");", srcfilt, idx, strCify(VDTextWToU8(var.GetWStr(), -1).c_str()));
					break;
				case VDPluginConfigVariant::kTypeBlock:
					output.addf("VirtualDub.audio.filters.instance[%d].SetBlock(%d, %d, \"%s\");", srcfilt, idx, var.GetBlockLen(), VDEncodeBase64A(var.GetBlockPtr(), var.GetBlockLen()).c_str());
					break;
				}
			}
		}
	}

	// Add subset information

	if (bIncludeEditList) {
		const FrameSubset& fs = g_project->GetTimeline().GetSubset();

		output.addf("VirtualDub.subset.Clear();");

		for(FrameSubset::const_iterator it(fs.begin()), itEnd(fs.end()); it!=itEnd; ++it)
			output.addf("VirtualDub.subset.Add%sRange(%I64d,%I64d);", it->bMask ? "Masked" : "", it->start, it->len);

		// Note that this must be AFTER the subset (we used to place it before, which was a bug).
		if (g_project->IsSelectionPresent()) {
			output.addf("VirtualDub.video.SetRangeFrames(%I64d,%I64d);",
				g_project->GetSelectionStartFrame(),
				g_project->GetSelectionEndFrame());
		} else {
			output.addf("VirtualDub.video.SetRange();");
		}
	}

	// Add text information
	if (bIncludeTextInfo) {
		typedef std::list<std::pair<uint32, VDStringA> > tTextInfo;
		const tTextInfo& textInfo = g_project->GetTextInfo();

		output.addf("VirtualDub.project.ClearTextInfo();");
		for(tTextInfo::const_iterator it(textInfo.begin()), itEnd(textInfo.end()); it!=itEnd; ++it) {
			char buf[5]={0};
			
			memcpy(buf, &(*it).first, 4);

			output.addf("VirtualDub.project.AddTextInfo(\"%s\", \"%s\");", buf, VDEncodeScriptString((*it).second).c_str());
		}
	}
}
Пример #13
0
size_t vdhash<VDStringA>::operator()(const VDStringA& s) const {
	return VDHashString32(s.data(), s.length());
}
Пример #14
0
bool VDFile::open_internal(const char *pszFilename, const wchar_t *pwszFilename, uint32 flags, bool throwOnError) {
	close();

	mpFilename = _wcsdup(VDFileSplitPath(pszFilename ? VDTextAToW(pszFilename).c_str() : pwszFilename));
	if (!mpFilename) {
		if (!throwOnError)
			return false;
		throw MyMemoryError();
	}

	// At least one of the read/write flags must be set.
	VDASSERT(flags & (kRead | kWrite));

	DWORD dwDesiredAccess = 0;

	if (flags & kRead)  dwDesiredAccess  = GENERIC_READ;
	if (flags & kWrite) dwDesiredAccess |= GENERIC_WRITE;

	// Win32 docs are screwed here -- FILE_SHARE_xxx is the inverse of a deny flag.

	DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
	if (flags & kDenyRead)	dwShareMode = FILE_SHARE_WRITE;
	if (flags & kDenyWrite) dwShareMode &= ~FILE_SHARE_WRITE;

	// One of the creation flags must be set.
	VDASSERT(flags & kCreationMask);

	DWORD dwCreationDisposition;

	uint32 creationType = flags & kCreationMask;

	switch(creationType) {
	case kOpenExisting:		dwCreationDisposition = OPEN_EXISTING; break;
	case kOpenAlways:		dwCreationDisposition = OPEN_ALWAYS; break;
	case kCreateAlways:		dwCreationDisposition = CREATE_ALWAYS; break;
	case kCreateNew:		dwCreationDisposition = CREATE_NEW; break;
	case kTruncateExisting:	dwCreationDisposition = TRUNCATE_EXISTING; break;
	default:
		VDNEVERHERE;
		return false;
	}

	VDASSERT((flags & (kSequential | kRandomAccess)) != (kSequential | kRandomAccess));

	DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL;

	if (flags & kSequential)	dwAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
	if (flags & kRandomAccess)	dwAttributes |= FILE_FLAG_RANDOM_ACCESS;
	if (flags & kWriteThrough)	dwAttributes |= FILE_FLAG_WRITE_THROUGH;
	if (flags & kUnbuffered)	dwAttributes |= FILE_FLAG_NO_BUFFERING;

	VDStringA tempFilenameA;
	VDStringW tempFilenameW;

	if (IsWindowsNT()) {
		if (pszFilename) {
			tempFilenameW = VDTextAToW(pszFilename);
			pwszFilename = tempFilenameW.c_str();
			pszFilename = NULL;
		}
	} else {
		if (pwszFilename) {
			tempFilenameA = VDTextWToA(pwszFilename);
			pszFilename = tempFilenameA.c_str();
			pwszFilename = NULL;
		}
	}

	if (pszFilename)
		mhFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwAttributes, NULL);
	else {
		if (!IsHardDrivePath(pwszFilename))
			flags &= ~FILE_FLAG_NO_BUFFERING;

		mhFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwAttributes, NULL);
	}

	DWORD err = GetLastError();

	// If we failed and FILE_FLAG_NO_BUFFERING was set, strip it and try again.
	// VPC and Novell shares sometimes do this....
	if (mhFile == INVALID_HANDLE_VALUE && err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND) {
		if (dwAttributes & FILE_FLAG_NO_BUFFERING) {
			dwAttributes &= ~FILE_FLAG_NO_BUFFERING;
			dwAttributes |= FILE_FLAG_WRITE_THROUGH;

			if (pszFilename)
				mhFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwAttributes, NULL);
			else
				mhFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwAttributes, NULL);

			err = GetLastError();
		}
	}

	// INVALID_HANDLE_VALUE isn't NULL.  *sigh*

	if (mhFile == INVALID_HANDLE_VALUE) {
		mhFile = NULL;

		if (!throwOnError)
			return false;

		throw MyWin32Error("Cannot open file \"%ls\":\n%%s", err, mpFilename.get());
	}

	mFilePosition = 0;
	return true;
}
Пример #15
0
void VDFileAsyncNT::ThreadRun() {
	int requestHead = 0;
	int requestTail = 0;
	int requestCount = mBlockCount;
	uint32 pendingLevel = 0;
	uint32 readOffset = 0;
	bool	bPreemptiveExtend = mbPreemptiveExtend;
	sint64	currentSize;

	try {
		if (!VDGetFileSizeW32(mhFileFast, currentSize))
			throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());

		for(;;) {
			int state = mState;

			if (state == kStateAbort) {
				typedef BOOL (WINAPI *tpCancelIo)(HANDLE);
				static const tpCancelIo pCancelIo = (tpCancelIo)GetProcAddress(GetModuleHandle(L"kernel32"), "CancelIo");
				pCancelIo(mhFileFast);

				// Wait for any pending blocks to complete.
				for(int i=0; i<requestCount; ++i) {
					VDFileAsyncNTBuffer& buf = mpBlocks[i];

					if (buf.mbActive) {
						WaitForSingleObject(buf.hEvent, INFINITE);
						buf.mbActive = false;
					}
				}
				break;
			}

			uint32 actual = mBufferLevel - pendingLevel;
			VDASSERT((int)actual >= 0);
			if (readOffset + actual > mBufferSize)
				actual = mBufferSize - readOffset;

			if (actual < mBlockSize) {
				if (state == kStateNormal || actual < mSectorSize) {
					// check for blocks that have completed
					bool blocksCompleted = false;
					for(;;) {
						VDFileAsyncNTBuffer& buf = mpBlocks[requestTail];

						if (!buf.mbActive) {
							if (state == kStateFlush)
								goto all_done;

							if (!blocksCompleted) {
								// wait for further writes
								mWriteOccurred.wait();
							}
							break;
						}

						if (buf.mbPending) {
							HANDLE h[2] = {buf.hEvent, mWriteOccurred.getHandle()};
							DWORD waitResult = WaitForMultipleObjects(2, h, FALSE, INFINITE);

							if (waitResult == WAIT_OBJECT_0+1)	// write pending
								break;

							DWORD dwActual;
							if (!GetOverlappedResult(mhFileFast, &buf, &dwActual, TRUE))
								throw MyWin32Error("Write error occurred on file \"%s\": %%s", GetLastError(), mFilename.c_str());
						}

						buf.mbActive = false;

						blocksCompleted = true;

						if (++requestTail >= requestCount)
							requestTail = 0;

						mBufferLevel -= buf.mLength;
						pendingLevel -= buf.mLength;
						VDASSERT((int)mBufferLevel >= 0);
						VDASSERT((int)pendingLevel >= 0);

						mReadOccurred.signal();

					}

					continue;
				}

				VDASSERT(state == kStateFlush);

				actual &= ~(mSectorSize-1);

				VDASSERT(actual > 0);
			} else {
				actual = mBlockSize;

				if (bPreemptiveExtend) {
					sint64 checkpt = mFastPointer + mBlockSize + mBufferSize;

					if (checkpt > currentSize) {
						currentSize += mBufferSize;
						if (currentSize < checkpt)
							currentSize = checkpt;

						if (!VDSetFilePointerW32(mhFileFast, currentSize, FILE_BEGIN)
							|| !SetEndOfFile(mhFileFast))
							mbPreemptiveExtend = bPreemptiveExtend = false;
					}
				}
			}

			// Issue a write to OS
			VDFileAsyncNTBuffer& buf = mpBlocks[requestHead];

			VDASSERT(!buf.mbActive);

			DWORD dwActual;

			buf.Offset = (DWORD)mFastPointer;
			buf.OffsetHigh = (DWORD)((uint64)mFastPointer >> 32);
			buf.Internal = 0;
			buf.InternalHigh = 0;
			buf.mLength = actual;
			buf.mbPending = false;

			if (!WriteFile(mhFileFast, &mBuffer[readOffset], actual, &dwActual, &buf)) {
				if (GetLastError() != ERROR_IO_PENDING)
					throw MyWin32Error("Write error occurred on file \"%s\": %%s", GetLastError(), mFilename.c_str());

				buf.mbPending = true;
			}

			buf.mbActive = true;

			pendingLevel += actual;
			VDASSERT(pendingLevel <= (uint32)mBufferLevel);

			readOffset += actual;
			VDASSERT(readOffset <= mBufferSize);
			if (readOffset >= mBufferSize)
				readOffset = 0;

			mFastPointer += actual;

			if (++requestHead >= requestCount)
				requestHead = 0;
		}
all_done:
		;

	} catch(MyError& e) {
		MyError *p = new MyError;

		p->TransferFrom(e);
		delete mpError.xchg(p);
		mReadOccurred.signal();
	}
}
Пример #16
0
void VDFileAsyncNT::Seek(sint64 pos) {
	if (!SeekNT(pos))
		throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());
}
Пример #17
0
void VDFileAsyncNT::Truncate(sint64 pos) {
	Seek(pos);
	if (!SetEndOfFile(mhFileSlow))
		throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());
}
Пример #18
0
bool VDRegistryProviderMemory::Key::KeyPred::operator()(const VDStringA& s, const char *t) const {
	return s.comparei(t) == 0;
}
Пример #19
0
const char *VDScriptInterpreter::TranslateScriptError(const VDScriptError& cse) {
	int i;
	char szError[1024];

	switch(cse.err) {
	case VDScriptError::OVERLOADED_FUNCTION_NOT_FOUND:
	case VDScriptError::AMBIGUOUS_CALL:
		{
			if (cse.err == VDScriptError::OVERLOADED_FUNCTION_NOT_FOUND) {
				if (mpCurrentInvocationMethod && mpCurrentInvocationMethod->name)
					sprintf(szError, "Overloaded method %s(", mpCurrentInvocationMethod->name);
				else
					strcpy(szError, "Overloaded method (");
			} else {
				if (mpCurrentInvocationMethod && mpCurrentInvocationMethod->name)
					sprintf(szError, "Ambiguous call with arguments %s(", mpCurrentInvocationMethod->name);
				else
					strcpy(szError, "Ambiguous call with arguments (");
			}

			mError.assign(szError, szError + strlen(szError));

			const VDScriptValue *const argv = &*(mStack.end() - mMethodArgumentCount);

			for(i=0; i<mMethodArgumentCount; i++) {
				if (i) {
					if (argv[i].isVoid()) break;

					mError.push_back(',');
				}

				switch(argv[i].type) {
				case VDScriptValue::T_VOID:		strveccat(mError, "void"); break;
				case VDScriptValue::T_INT:		strveccat(mError, "int"); break;
				case VDScriptValue::T_LONG:		strveccat(mError, "long"); break;
				case VDScriptValue::T_DOUBLE:		strveccat(mError, "double"); break;
				case VDScriptValue::T_STR:		strveccat(mError, "string"); break;
				case VDScriptValue::T_OBJECT:	strveccat(mError, "object"); break;
				case VDScriptValue::T_FNAME:		strveccat(mError, "method"); break;
				case VDScriptValue::T_FUNCTION:	strveccat(mError, "function"); break;
				case VDScriptValue::T_VARLV:		strveccat(mError, "var"); break;
				}
			}

			strveccat(mError, ")");
			if (cse.err == VDScriptError::OVERLOADED_FUNCTION_NOT_FOUND)
				strveccat(mError, " not found");
		}
		mError.push_back(0);

		return mError.data();
	case VDScriptError::MEMBER_NOT_FOUND:
		sprintf(szError, "Class '%s' does not have a member called '%s'", mErrorObject.asObjectDef()->mpName, szIdent);
		mError.assign(szError, szError + strlen(szError) + 1);
		return mError.data();
	case VDScriptError::VAR_NOT_FOUND:
		if (!mErrorExtraToken.empty()) {
			sprintf(szError, "Variable '%s' not found", mErrorExtraToken.c_str());
			mError.assign(szError, szError + strlen(szError) + 1);
			return mError.data();
		}
		break;
	}
	return ::VDScriptTranslateError(cse);
}
Пример #20
0
void vdmove<VDStringA>(VDStringA& dst, VDStringA& src) {
	dst.move_from(src);
}
Пример #21
0
void VDFileAsync9x::ThreadRun() {
	bool	bPreemptiveExtend = mbPreemptiveExtend;
	sint64	currentSize;
	sint64	pos = 0;
	uint32	bufferSize = mBlockCount * mBlockSize;
	HANDLE  hFile = mhFileFast != INVALID_HANDLE_VALUE ? mhFileFast : mhFileSlow;

	try {
		if (bPreemptiveExtend && !VDGetFileSizeW32(hFile, currentSize))
			throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());

		for(;;) {
			int state = mState;

			if (state == kStateAbort)
				break;

			int actual;
			const void *p = mBuffer.LockRead(mBlockSize, actual);

			if ((uint32)actual < mBlockSize) {
				if (state == kStateNormal) {
					mWriteOccurred.wait();
					continue;
				}

				VDASSERT(state == kStateFlush);

				actual &= ~(mSectorSize-1);
				if (!actual)
					break;
			} else {
				if (bPreemptiveExtend) {
					sint64 checkpt = pos + mBlockSize + bufferSize;

					if (checkpt > currentSize) {
						currentSize += bufferSize;
						if (currentSize < checkpt)
							currentSize = checkpt;

						if (!VDSetFilePointerW32(hFile, currentSize, FILE_BEGIN)
							|| !SetEndOfFile(hFile))
							mbPreemptiveExtend = bPreemptiveExtend = false;

						if (!VDSetFilePointerW32(hFile, pos, FILE_BEGIN))
							throw MyWin32Error("Seek error occurred on file \"%s\": %%s\n", GetLastError(), mFilename.c_str());
					}
				}
			}

			DWORD dwActual;
			if (!WriteFile(hFile, p, actual, &dwActual, NULL) || dwActual != actual) {
				DWORD dwError = GetLastError();
				throw MyWin32Error("Write error occurred on file \"%s\": %%s\n", dwError, mFilename.c_str());
			}

			pos += actual;

			mBuffer.UnlockRead(actual);

			mReadOccurred.signal();
		}
	} catch(MyError& e) {
		MyError *p = new MyError;

		p->TransferFrom(e);
		delete mpError.xchg(p);
		mReadOccurred.signal();
	}
}
Пример #22
0
bool VDDialogEditAccelerators::OnCommand(uint32 id, uint32 extcode) {
	if (id == IDC_FILTER) {
		if (extcode == EN_CHANGE) {
			VDStringA s("*");
			s += VDTextWToA(GetControlValueString(id)).c_str();
			s += '*';

			RefilterCommands(s.c_str());
			return true;
		}
	} else if (id == IDC_ADD) {
		VDUIAccelerator accel;

		int selIdx = LBGetSelectedIndex(IDC_AVAILCOMMANDS);

		if ((size_t)selIdx < mFilteredCommands.size()) {
			const VDAccelToCommandEntry *ace = mFilteredCommands[selIdx];

			if (mpHotKeyControl) {
				mpHotKeyControl->GetAccelerator(accel);

				// Look for a conflicting command.
				for(BoundCommands::iterator it(mBoundCommands.begin()), itEnd(mBoundCommands.end()); it != itEnd; ++it) {
					BoundCommand *obc = *it;

					if (obc->mAccel == accel) {
						VDStringW keyName;
						VDUIGetAcceleratorString(accel, keyName);

						VDStringA msg;
						msg.sprintf("The key %ls is already bound to %hs. Rebind it to %hs?", keyName.c_str(), obc->mpCommand, ace->mpName);

						if (IDOK != MessageBox(mhdlg, msg.c_str(), g_szWarning, MB_OKCANCEL | MB_ICONEXCLAMATION))
							return true;

						mBoundCommands.erase(it);
						obc->Release();
					}
				}

				vdrefptr<BoundCommand> bc(new_nothrow BoundCommand);
				
				if (bc) {
					bc->mpCommand = ace->mpName;
					bc->mCommandId = ace->mId;
					bc->mAccel = accel;

					mBoundCommands.push_back(bc.release());
					RefreshBoundList();
				}
			}
		}

		return true;
	} else if (id == IDC_REMOVE) {
		int selIdx = mListViewBoundCommands.GetSelectedIndex();

		if ((unsigned)selIdx < mBoundCommands.size()) {
			BoundCommand *bc = mBoundCommands[selIdx];

			mBoundCommands.erase(mBoundCommands.begin() + selIdx);

			bc->Release();

			RefreshBoundList();
		}

		return true;
	} else if (id == IDC_RESET) {
		if (IDOK == MessageBox(mhdlg, "Really reset?", g_szWarning, MB_OKCANCEL | MB_ICONEXCLAMATION))
			LoadTable(mBoundCommandsDefault);

		return true;
	}

	return false;
}
Пример #23
0
size_t VDRegistryProviderMemory::Key::KeyHash::operator()(const VDStringA& s) const {
	return VDHashString32I(s.data(), s.size());
}
Пример #24
0
void VDDumpChangeLog() {
    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_CHANGES), "STUFF");

    if (!hResource)
        return;

    HGLOBAL hGlobal = LoadResource(NULL, hResource);
    if (!hGlobal)
        return;

    LPVOID lpData = LockResource(hGlobal);
    if (!lpData)
        return;

    const char *s = (const char *)lpData;

    while(*s!='\r') ++s;

    s+=2;

    tTextStream lineBuffer;
    VDStringA breakLineBuffer;

    bool foundNonIndentedLine = false;

    while(*s) {
        // parse line
        if (*s != ' ') {
            if (foundNonIndentedLine)
                break;

            foundNonIndentedLine = true;
        }

        const char *end = s;
        while(*end && *end != '\r' && *end != '\n')
            ++end;

        lineBuffer.clear();
        append_cooked(lineBuffer, s, end, false);

        // skip line termination
        s = end;
        if (*s == '\r' || *s == '\n') {
            ++s;
            if ((s[0] ^ s[-1]) == ('\r' ^ '\n'))
                ++s;
        }

        lineBuffer.push_back(0);

        // break into lines
        const char *t = lineBuffer.data();
        int maxLine = 78;

        breakLineBuffer.clear();

        do {
            const char *lineStart = t;
            const char *break1 = NULL;
            const char *break2 = NULL;

            do {
                while(*t && *t != ' ')
                    ++t;

                const char *u = t;

                while(*t && *t == ' ')
                    ++t;

                if (u - lineStart > maxLine) {
                    if (!break1) {
                        break1 = u + maxLine;
                        break2 = break1;
                    }

                    break;
                }

                break1 = u;
                break2 = t;
            } while(*t);

            breakLineBuffer.append(lineStart, break1);
            VDLog(kVDLogInfo, VDTextAToW(breakLineBuffer.data(), breakLineBuffer.size()));

            t = break2;
            breakLineBuffer.clear();
            breakLineBuffer.resize(5, ' ');

            maxLine = 73;
        } while(*t);
    }
}