From 96a32415ab43377cf1575bd3f4f2980f58028209 Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 14 Aug 2015 11:51:42 +0800 Subject: add implementation for kaldi io (by ymz) --- .../tools/openfst/include/fst/script/script-impl.h | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 kaldi_io/src/tools/openfst/include/fst/script/script-impl.h (limited to 'kaldi_io/src/tools/openfst/include/fst/script/script-impl.h') diff --git a/kaldi_io/src/tools/openfst/include/fst/script/script-impl.h b/kaldi_io/src/tools/openfst/include/fst/script/script-impl.h new file mode 100644 index 0000000..452c7c5 --- /dev/null +++ b/kaldi_io/src/tools/openfst/include/fst/script/script-impl.h @@ -0,0 +1,206 @@ + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright 2005-2010 Google, Inc. +// Author: jpr@google.com (Jake Ratkiewicz) + +// This file defines the registration mechanism for new operations. +// These operations are designed to enable scripts to work with FST classes +// at a high level. + +// If you have a new arc type and want these operations to work with FSTs +// with that arc type, see below for the registration steps +// you must take. + +// These methods are only recommended for use in high-level scripting +// applications. Most users should use the lower-level templated versions +// corresponding to these. + +// If you have a new arc type you'd like these operations to work with, +// use the REGISTER_FST_OPERATIONS macro defined in fstcsript.h + +// If you have a custom operation you'd like to define, you need four +// components. In the following, assume you want to create a new operation +// with the signature +// +// void Foo(const FstClass &ifst, MutableFstClass *ofst); +// +// You need: +// +// 1) A way to bundle the args that your new Foo operation will take, as +// a single struct. The template structs in arg-packs.h provide a handy +// way to do this. In Foo's case, that might look like this: +// +// typedef args::Package FooArgs; +// +// Note: this package of args is going to be passed by non-const pointer. +// +// 2) A function template that is able to perform Foo, given the args and +// arc type. Yours might look like this: +// +// template +// void Foo(FooArgs *args) { +// // Pull out the actual, arc-templated FSTs +// const Fst &ifst = args->arg1.GetFst(); +// MutableFst *ofst = args->arg2->GetMutableFst(); +// +// // actually perform foo on ifst and ofst... +// } +// +// 3) a client-facing function for your operation. This would look like +// the following: +// +// void Foo(const FstClass &ifst, MutableFstClass *ofst) { +// // Check that the arc types of the FSTs match +// if (!ArcTypesMatch(ifst, *ofst, "Foo")) return; +// // package the args +// FooArgs args(ifst, ofst); +// // Finally, call the operation +// Apply >("Foo", ifst->ArcType(), &args); +// } +// +// The Apply<> function template takes care of the link between 2 and 3, +// provided you also have: +// +// 4) A registration for your new operation, on the arc types you care about. +// This can be provided easily by the REGISTER_FST_OPERATION macro in +// operations.h: +// +// REGISTER_FST_OPERATION(Foo, StdArc, FooArgs); +// REGISTER_FST_OPERATION(Foo, MyArc, FooArgs); +// // .. etc +// +// +// That's it! Now when you call Foo(const FstClass &, MutableFstClass *), +// it dispatches (in #3) via the Apply<> function to the correct +// instantiation of the template function in #2. +// + + +#ifndef FST_SCRIPT_SCRIPT_IMPL_H_ +#define FST_SCRIPT_SCRIPT_IMPL_H_ + +// +// This file contains general-purpose templates which are used in the +// implementation of the operations. +// + +#include +using std::pair; using std::make_pair; +#include + +#include +#include +#include + +#include + +namespace fst { +namespace script { + +// +// A generic register for operations with various kinds of signatures. +// Needed since every function signature requires a new registration class. +// The pair is understood to be the operation name and arc +// type; subclasses (or typedefs) need only provide the operation signature. +// + +template +class GenericOperationRegister + : public GenericRegister, + OperationSignature, + GenericOperationRegister > { + public: + void RegisterOperation(const string &operation_name, + const string &arc_type, + OperationSignature op) { + this->SetEntry(make_pair(operation_name, arc_type), op); + } + + OperationSignature GetOperation( + const string &operation_name, const string &arc_type) { + return this->GetEntry(make_pair(operation_name, arc_type)); + } + + protected: + virtual string ConvertKeyToSoFilename( + const pair& key) const { + // Just use the old-style FST for now. + string legal_type(key.second); // the arc type + ConvertToLegalCSymbol(&legal_type); + + return legal_type + "-arc.so"; + } +}; + + +// Operation package - everything you need to register a new type of operation + +// The ArgPack should be the type that's passed into each wrapped function - +// for instance, it might be a struct containing all the args. +// It's always passed by pointer, so const members should be used to enforce +// constness where it's needed. Return values should be implemented as a +// member of ArgPack as well. + +template +struct Operation { + typedef ArgPack Args; + typedef void (*OpType)(ArgPack *args); + + // The register (hash) type + typedef GenericOperationRegister Register; + + // The register-er type + typedef GenericRegisterer Registerer; +}; + + +// Macro for registering new types of operations. + +#define REGISTER_FST_OPERATION(Op, Arc, ArgPack) \ + static fst::script::Operation::Registerer \ + arc_dispatched_operation_ ## ArgPack ## Op ## Arc ## _registerer( \ + make_pair(#Op, Arc::Type()), Op) + + +// +// Template function to apply an operation by name +// + +template +void Apply(const string &op_name, const string &arc_type, + typename OpReg::Args *args) { + typename OpReg::Register *reg = OpReg::Register::GetRegister(); + + typename OpReg::OpType op = reg->GetOperation(op_name, arc_type); + + if (op == 0) { + FSTERROR() << "No operation found for \"" << op_name << "\" on " + << "arc type " << arc_type; + return; + } + + op(args); +} + + +// Helper that logs to ERROR if the arc types of a and b don't match. +// The op_name is also printed. +bool ArcTypesMatch(const FstClass &a, const FstClass &b, + const string &op_name); + +} // namespace script +} // namespace fst + +#endif // FST_SCRIPT_SCRIPT_IMPL_H_ -- cgit v1.2.3