0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009:
0010:
0011:
0012:
0013:
0014:
0015:
0016:
0017:
0018:
0019:
0020:
0021:
0022:
0023:
0024:
0025:
0026:
0027:
0028:
0029:
0030:
0031:
0032:
0033:
0034:
0035:
0036:
0037:
0038:
0039:
0040:
0041:
0042:
0043:
0044:
0045:
0046:
0047:
0048:
0049:
0050:
0051:
0052:
0053:
0054:
0055:
0056:
0057:
0058:
0059:
0060:
0061:
0062:
0063:
0064:
0065:
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073:
0074:
0075:
0076:
0077:
0078:
0079:
0080:
0081:
0082:
0083:
0084:
0085:
0086:
0087:
0088:
0089:
0090:
0091:
0092:
0093:
0094:
0095:
0096:
0097:
0098:
0099:
0100:
0101:
0102:
0103:
0104:
0105:
0106:
0107:
0108:
0109:
0110:
0111:
0112:
0113:
0114:
0115:
0116:
0117:
0118:
0119:
0120:
0121:
0122:
0123:
0124:
0125:
0126:
0127:
0128:
0129:
0130:
0131:
0132:
0133:
0134:
0135:
0136:
0137:
0138:
0139:
0140:
0141:
0142:
0143:
0144:
0145:
0146:
0147:
0148:
0149:
0150:
0151:
0152:
0153:
0154:
0155:
0156:
0157:
0158:
0159:
0160:
0161:
0162:
0163:
0164:
0165:
0166:
0167:
0168:
0169:
0170:
0171:
0172:
0173:
0174:
0175:
0176:
0177:
0178:
0179:
0180:
0181:
0182:
0183:
0184:
0185:
0186:
0187:
0188:
0189:
0190:
0191:
0192:
0193:
0194:
0195:
0196:
0197:
0198:
0199:
0200:
0201:
0202:
0203:
0204:
0205:
0206:
0207:
0208:
0209:
0210:
0211:
0212:
0213:
0214:
0215:
0216:
0217:
0218:
0219:
0220:
0221:
0222:
0223:
0224:
0225:
0226:
0227:
0228:
0229:
0230:
0231:
0232:
0233:
0234:
0235:
0236:
0237:
0238:
0239:
0240:
0241:
0242:
0243:
0244:
0245:
0246:
0247:
0248:
0249:
0250:
0251:
0252:
0253:
0254:
0255:
0256:
0257:
0258:
0259:
0260:
0261:
0262:
0263:
0264:
0265:
0266:
0267:
0268:
0269:
0270:
0271:
0272:
0273:
0274:
0275:
0276:
0277:
0278:
0279:
0280:
0281:
0282:
0283:
0284:
0285:
0286:
0287:
0288:
0289:
0290:
0291:
0292:
0293:
0294:
0295:
0296:
0297:
0298:
0299:
0300:
0301:
0302:
0303:
0304:
0305:
0306:
0307:
0308:
0309:
0310:
0311:
0312:
0313:
0314:
0315:
0316:
0317:
0318:
0319:
0320:
0321:
0322:
0323:
0324:
0325:
0326:
0327:
0328:
0329:
0330:
0331:
0332:
0333:
0334:
0335:
0336:
0337:
0338:
0339:
0340:
0341:
0342:
0343:
0344:
0345:
0346:
0347:
0348:
0349:
0350:
0351:
0352:
0353:
0354:
0355:
0356:
0357:
0358:
0359:
0360:
0361:
0362:
0363:
0364:
0365:
0366:
0367:
0368:
0369:
0370:
0371:
0372:
0373:
0374:
0375:
0376:
0377:
0378:
0379:
0380:
0381:
0382:
0383:
0384:
0385:
0386:
0387:
0388:
0389:
0390:
0391:
0392:
0393:
0394:
0395:
0396:
0397:
0398:
0399:
0400:
0401:
0402:
0403:
0404:
0405:
0406:
0407:
0408:
0409:
0410:
0411:
0412:
0413:
0414:
0415:
0416:
0417:
0418:
0419:
0420:
0421:
0422:
0423:
0424:
0425:
0426:
0427:
0428:
0429:
0430:
0431:
0432:
0433:
0434:
0435:
0436:
0437:
0438:
0439:
0440:
0441:
0442:
0443:
0444:
0445:
0446:
0447:
0448:
0449:
0450:
0451:
0452:
0453:
0454:
0455:
0456:
0457:
0458:
0459:
0460:
0461:
0462:
0463:
0464:
0465:
0466:
0467:
0468:
0469:
0470:
0471:
0472:
0473:
0474:
0475:
0476:
0477:
0478:
0479:
0480:
0481:
0482:
0483:
0484:
0485:
0486:
0487:
0488:
0489:
0490:
0491:
0492:
0493:
0494:
0495:
0496:
0497:
0498:
0499:
0500:
0501:
0502:
0503:
0504:
0505:
0506:
0507:
0508:
0509:
0510:
0511:
0512:
0513:
0514:
0515:
0516:
0517:
0518:
0519:
0520:
0521:
0522:
0523:
0524:
0525:
0526:
0527:
0528:
0529:
0530:
0531:
0532:
0533:
0534:
0535:
0536:
0537:
0538:
0539:
0540:
0541:
0542:
0543:
0544:
0545:
0546:
0547:
0548:
0549:
0550:
0551:
0552:
0553:
0554:
0555:
0556:
0557:
0558:
0559:
0560:
0561:
0562:
0563:
0564:
0565:
0566:
0567:
0568:
0569:
0570:
0571:
0572:
0573:
0574:
0575:
0576:
0577:
0578:
0579:
0580:
0581:
0582:
0583:
0584:
0585:
0586:
0587:
0588:
0589:
0590:
0591:
0592:
0593:
0594:
0595:
0596:
0597:
0598:
0599:
0600:
0601:
0602:
0603:
0604:
0605:
0606:
0607:
0608:
0609:
0610:
0611:
0612:
0613:
0614:
0615:
0616:
0617:
0618:
0619:
0620:
0621:
0622:
0623:
0624:
0625:
0626:
0627:
0628:
0629:
0630:
0631:
0632:
0633:
0634:
0635:
0636:
0637:
0638:
0639:
0640:
0641:
0642:
0643:
0644:
0645:
0646:
0647:
0648:
0649:
0650:
0651:
0652:
0653:
0654:
0655:
0656:
0657:
0658:
0659:
0660:
0661:
0662:
0663:
0664:
0665:
0666:
0667:
0668:
0669:
0670:
0671:
0672:
0673:
0674:
0675:
0676:
0677:
0678:
0679:
0680:
0681:
0682:
0683:
0684:
0685:
0686:
0687:
0688:
0689:
0690:
0691:
0692:
0693:
0694:
0695:
0696:
0697:
0698:
0699:
0700:
0701:
0702:
0703:
0704:
0705:
0706:
0707:
0708:
0709:
0710:
0711:
0712:
0713:
0714:
0715:
0716:
0717:
0718:
0719:
0720:
0721:
0722:
0723:
0724:
0725:
0726:
0727:
0728:
0729:
0730:
0731:
0732:
0733:
0734:
0735:
0736:
0737:
0738:
0739:
0740:
0741:
0742:
0743:
0744:
0745:
0746:
0747:
0748:
0749:
0750:
0751:
0752:
0753:
0754:
0755:
0756:
0757:
0758:
0759:
0760:
0761:
0762:
0763:
0764:
0765:
0766:
0767:
0768:
0769:
0770:
0771:
0772:
0773:
0774:
0775:
0776:
0777:
0778:
0779:
0780:
0781:
0782:
0783:
0784:
0785:
0786:
0787:
0788:
0789:
0790:
0791:
0792:
0793:
0794:
0795:
0796:
0797:
0798:
0799:
0800:
0801:
0802:
0803:
0804:
0805:
0806:
0807:
0808:
0809:
0810:
0811:
0812:
0813:
0814:
0815:
0816:
0817:
0818:
0819:
0820:
0821:
0822:
0823:
0824:
0825:
0826:
0827:
0828:
0829:
0830:
0831:
0832:
0833:
0834:
0835:
0836:
0837:
0838:
0839:
0840:
0841:
0842:
0843:
0844:
0845:
0846:
0847:
0848:
0849:
0850:
0851:
0852:
0853:
0854:
0855:
0856:
0857:
0858:
0859:
0860:
0861:
0862:
0863:
0864:
0865:
0866:
0867:
0868:
0869:
0870:
0871:
0872:
0873:
0874:
0875:
0876:
0877:
0878:
0879:
0880:
0881:
0882:
0883:
0884:
0885:
0886:
0887:
0888:
0889:
0890:
0891:
0892:
0893:
0894:
0895:
0896:
0897:
0898:
0899:
0900:
0901:
0902:
0903:
0904:
0905:
0906:
0907:
0908:
0909:
0910:
0911:
0912:
0913:
0914:
0915:
0916:
0917:
0918:
0919:
0920:
0921:
0922:
0923:
0924:
0925:
0926:
0927:
0928:
0929:
0930:
0931:
0932:
0933:
0934:
0935:
0936:
0937:
0938:
0939:
0940:
0941:
0942:
0943:
0944:
0945:
0946:
0947:
0948:
0949:
0950:
0951:
0952:
0953:
0954:
0955:
0956:
0957:
0958:
0959:
0960:
0961:
0962:
0963:
0964:
0965:
0966:
0967:
0968:
0969:
0970:
0971:
0972:
0973:
0974:
0975:
0976:
0977:
0978:
0979:
0980:
0981:
0982:
0983:
0984:
0985:
0986:
0987:
0988:
0989:
0990:
0991:
0992:
0993:
0994:
0995:
0996:
0997:
0998:
0999:
1000:
1001:
1002:
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010:
1011:
1012:
1013:
1014:
1015:
1016:
1017:
1018:
1019:
1020:
1021:
1022:
1023:
1024:
1025:
1026:
1027:
1028:




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































/*
* Copyright (c), Zeriph Enterprises
* All rights reserved.
*
* Contributor(s):
* Zechariah Perez, omni (at) zeriph (dot) com
*
* THIS SOFTWARE IS PROVIDED BY ZERIPH AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ZERIPH AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* DEV_NOTE: this file is not intended to be used directly by any user code!

i.e. don't #include <omni/xxx_impl.hxx> and don't compile this source directly.
this file is #include'd directly in other source.
*/

// TODO: parts of this are unfinished (i.e. set_size unix)

// so as not to accidentally build this file with the source this macro is defined in io.cpp
#if !defined(OMNI_IO_FILE_FW) || !defined(OMNI_PATH_FW) || !defined(OMNI_L_FW) || !defined(OMNI_STRING_T_FW)
    #error invalid preprocessor directive detected
#endif

#if defined(OMNI_IO_FILE_INTERNAL_FW)
    namespace omni {
    namespace io {
    namespace file_internal {

    #if defined(OMNI_OS_WIN)
        /* DEV_NOTE: this code is Windows only .. it returns the short/long path name for a file
        but that's largely irrelevant as it only returns an 8.3 short path name if it's enabled
        in the registry for above Windows XP. Since this is a one-off type of thing and likely
        not largely used, this will not be exposed or documented beyond this file scope. */

        std::string get_path_name(const std::string& file)
        {
            std::string name = "\\\\?\\";
            long length = ::GetShortPathNameA(file.c_str(), NULL, 0);
            if (length > 0) {
                char *buffer = new char[length];
                length = ::GetShortPathNameA(file.c_str(), buffer, length);
                if (length > 0) {
                    std::string npath(buffer);
                    delete[] buffer;
                    name += npath;
                } else {
                    delete[] buffer;
                }
            } else {
                name += file;
            }
            return name;
        }

        std::wstring get_path_name(const std::wstring& file)
        {
            std::wstring name = L"\\\\?\\";
            long length = ::GetShortPathNameW(file.c_str(), NULL, 0);
            if (length > 0) {
                wchar_t *buffer = new wchar_t[length];
                length = ::GetShortPathNameW(file.c_str(), buffer, length);
                if (length > 0) {
                    std::wstring npath(buffer);
                    delete[] buffer;
                    name += npath;
                } else {
                    delete[] buffer;
                }
            } else {
                name += file;
            }
            return name;
        }
    #endif

    bool exists(const std::string& file)
    {
        if (file.empty()) { return false; }
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                OMNI_FILE_CHECKA_FW(file, false)
                DWORD res = ::GetFileAttributesA(file.c_str());
                return (res != INVALID_FILE_ATTRIBUTES && !(res & FILE_ATTRIBUTE_DIRECTORY));
            #else
                struct stat fi;
                if (::_stat(file.c_str(), &fi) == 0) {
                    #if defined(S_ISSOCK)
                        return !(S_ISDIR(fi.st_mode)) && !(S_ISSOCK(fi.st_mode));
                    #else
                        return !(S_ISDIR(fi.st_mode));
                    #endif
                }
                return false;
            #endif
        #else
            struct stat fi;
            if (::stat(file.c_str(), &fi) == 0) {
                #if defined(S_ISSOCK)
                    return !(S_ISDIR(fi.st_mode)) && !(S_ISSOCK(fi.st_mode));
                #else
                    return !(S_ISDIR(fi.st_mode));
                #endif
            }
            return false;
        #endif
    }
    bool exists(const std::wstring& file)
    {
        if (file.empty()) { return false; }
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
                DWORD res = ::GetFileAttributesW(tf.c_str());
                return (res != INVALID_FILE_ATTRIBUTES && !(res & FILE_ATTRIBUTE_DIRECTORY));
            #else
                struct stat fi;
                if (::_wstat(file.c_str(), &fi) == 0) {
                    #if defined(S_ISSOCK)
                        return !(S_ISDIR(fi.st_mode)) && !(S_ISSOCK(fi.st_mode));
                    #else
                        return !(S_ISDIR(fi.st_mode));
                    #endif
                }
                return false;
            #endif
        #else
            struct stat fi;
            if (::stat(omni::string::util::to_string(file).c_str(), &fi) == 0) {
                #if defined(S_ISSOCK)
                    return !(S_ISDIR(fi.st_mode)) && !(S_ISSOCK(fi.st_mode));
                #else
                    return !(S_ISDIR(fi.st_mode));
                #endif
            }
            return false;
        #endif
    }
    
    template < typename STR, typename ISTREAM, typename OSTREAM >
    bool copy(const STR& file, const STR& new_name)
    {
        ISTREAM src(omni::string::util::to_string(file).c_str(), std::ios::binary);
        if (!src.is_open()) {
            OMNI_ERRV_RETV_FW(OMNI_PATH_NOT_ACCESSIBLE_STR, omni::string::util::to_string_t(file), omni::exceptions::path_exception(omni::string::util::to_string(file)), false)
        }
        OSTREAM dst(omni::string::util::to_string(new_name).c_str(), std::ios::binary);
        if (!dst.is_open()) {
            src.close();
            OMNI_ERRV_RETV_FW(OMNI_PATH_NOT_ACCESSIBLE_STR, omni::string::util::to_string_t(new_name), omni::exceptions::path_exception(omni::string::util::to_string(new_name)), false)
        }
        dst << src.rdbuf();
        src.close();
        dst.close();
        return true;
    }
    bool copy(const std::string& file, const std::string& new_name)
    {
        #if defined(OMNI_OS_WIN) && defined(OMNI_WIN_API)
            OMNI_FILE_CHECKA_FW(file, false)
            if (::CopyFileA(file.c_str(), new_name.c_str(), FALSE) == 0) {
                OMNI_DBGEV("error copying file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                return false;
            }
            return omni::io::file_internal::exists(new_name);
        #else
            return omni::io::file_internal::copy<std::string, std::ifstream, std::ofstream>(file, new_name);
        #endif
    }
    bool copy(const std::wstring& file, const std::wstring& new_name)
    {
        #if defined(OMNI_OS_WIN) && defined(OMNI_WIN_API)
            std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
            std::wstring nf = OMNI_FILE_CHECKW_FW(new_name, false)
            if (::CopyFileW(tf.c_str(), nf.c_str(), FALSE) == 0) {
                OMNI_DBGEV("error copying file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                return false;
            }
            return omni::io::file_internal::exists(new_name);
        #else
            return omni::io::file_internal::copy<std::wstring, std::wifstream, std::wofstream>(file, new_name);
        #endif
    }

    template < typename STR, typename OSTREAM >
    bool create(const STR& file, bool create_path)
    {
        STR parent = omni::io::path::get_parent_name(file);
        if (create_path && !omni::io::directory::exists(parent)) {
            if (!omni::io::directory::create(parent)) {
                return false;
            }
        }
        OSTREAM out(omni::string::util::to_string(file).c_str(), std::ios::binary|std::ios::out);
        out.close(); // close/flush
        return omni::io::file_internal::exists(file);
    }
    bool create(const std::string& file, bool create_path)
    {
        #if defined(OMNI_OS_WIN) && defined(OMNI_WIN_API)
            if (create_path) {
                std::string parent = omni::io::path::get_parent_name(file);
                if (create_path && !omni::io::directory::exists(parent)) {
                    if (!omni::io::directory::create(parent)) {
                        return false;
                    }
                }
            }
            OMNI_FILE_CHECKA_FW(file, false)
            HANDLE hfile = ::CreateFileA(file.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                                                     CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
            int ret = omni::system::last_error();
            if (hfile == INVALID_HANDLE_VALUE || ret > 0) {
                OMNI_DBGEV("error setting file length: ", ret)
                if (hfile != INVALID_HANDLE_VALUE) {
                    ::CloseHandle(hfile);
                }
                return false;
            }
            ::CloseHandle(hfile);
            return omni::io::file_internal::exists(file);
        #else
            return omni::io::file_internal::create<std::string, std::ofstream>(file, create_path);
        #endif
    }
    bool create(const std::wstring& file, bool create_path)
    {
        #if defined(OMNI_OS_WIN) && defined(OMNI_WIN_API)
            if (create_path) {
                std::wstring parent = omni::io::path::get_parent_name(file);
                if (create_path && !omni::io::directory::exists(parent)) {
                    if (!omni::io::directory::create(parent)) {
                        return false;
                    }
                }
            }
            std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
            HANDLE hfile = ::CreateFileW(tf.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                                                 CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
            int ret = omni::system::last_error();
            if (hfile == INVALID_HANDLE_VALUE || ret > 0) {
                OMNI_DBGEV("error setting file length: ", ret)
                if (hfile != INVALID_HANDLE_VALUE) {
                    ::CloseHandle(hfile);
                }
                return false;
            }
            ::CloseHandle(hfile);
            return omni::io::file_internal::exists(file);
        #else
            return omni::io::file_internal::create<std::wstring, std::wofstream>(file, create_path);
        #endif
    }

    template < typename STR, typename ISTRM, typename SSTRM >
    STR get_contents(const STR& file)
    {
        ISTRM ifile(omni::string::util::to_string(file).c_str());
        SSTRM buf;
        buf << ifile.rdbuf();
        return buf.str();
    }
    std::string get_contents(const std::string& file)
    {
        return get_contents<std::string, std::ifstream, std::stringstream>(file);
    }
    std::wstring get_contents(const std::wstring& file)
    {
        return get_contents<std::wstring, std::wifstream, std::wstringstream>(file);
    }

    uint64_t get_size(const std::string& file)
    {
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                OMNI_FILE_CHECKA_FW(file, 0)
                WIN32_FILE_ATTRIBUTE_DATA finfo;
                if (::GetFileAttributesExA(file.c_str(), GetFileExInfoStandard, &finfo) == 0) {
                    return 0;
                }
                LARGE_INTEGER sz;
                sz.HighPart = finfo.nFileSizeHigh;
                sz.LowPart = finfo.nFileSizeLow;
                return static_cast<uint64_t>(sz.QuadPart);
            #else
                struct stat fi;
                if (::_stat(file.c_str(), &fi) == 0) {
                    return static_cast<uint64_t>(fi.st_size);
                }
                return 0;
            #endif
        #else
            struct stat fi;
            if (::stat(file.c_str(), &fi) == 0) {
                return static_cast<uint64_t>(fi.st_size);
            }
            return 0;
        #endif
    }
    uint64_t get_size(const std::wstring& file)
    {
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                std::wstring tf = OMNI_FILE_CHECKW_FW(file, 0)
                WIN32_FILE_ATTRIBUTE_DATA finfo;
                if (::GetFileAttributesExW(tf.c_str(), GetFileExInfoStandard, &finfo) == 0) {
                    return 0;
                }
                LARGE_INTEGER sz;
                sz.HighPart = finfo.nFileSizeHigh;
                sz.LowPart = finfo.nFileSizeLow;
                return static_cast<uint64_t>(sz.QuadPart);
            #else
                struct stat fi;
                if (::_wstat(file.c_str(), &fi) == 0) {
                    return static_cast<uint64_t>(fi.st_size);
                }
                return 0;
            #endif
        #else
            struct stat fi;
            if (::stat(omni::string::util::to_string(file).c_str(), &fi) == 0) {
                return static_cast<uint64_t>(fi.st_size);
            }
            return 0;
        #endif
    }

    bool mv(const std::string& file, const std::string& new_name, bool create_path)
    {
        std::string root = omni::io::cpath::get_parent_name(new_name);
        if (!omni::io::cdirectory::exists(root)) {
            if (create_path) {
                if (!omni::io::cdirectory::create(root, true)) {
                    OMNI_D1_FW("could not create parent directory");
                    return false;
                }
            } else {
                OMNI_D1_FW("error moving file: new path does not exist");
                return false;
            }
        }
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                OMNI_FILE_CHECKA_FW(file, false)
                OMNI_FILE_CHECKA_FW(new_name, false)
                BOOL ret = ::MoveFileA(file.c_str(), new_name.c_str());
                if (ret == 0) {
                    OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                    return false;
                }
            #else
                int ret = ::_rename(file.c_str(), new_name.c_str());
                if (ret != 0) {
                    OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::error_str(ret)));
                    return false;
                }
            #endif
        #else
            int ret = ::rename(file.c_str(), new_name.c_str());
            if (ret != 0) {
                OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::error_str(ret)));
                return false;
            }
        #endif
        return omni::io::file_internal::exists(new_name);
    }
    bool mv(const std::wstring& file, const std::wstring& new_name, bool create_path)
    {
        std::wstring root = omni::io::wpath::get_parent_name(new_name);
        if (!omni::io::wdirectory::exists(root)) {
            if (create_path) {
                if (!omni::io::wdirectory::create(root, true)) {
                    OMNI_D1_FW("could not create parent directory");
                    return false;
                }
            } else {
                OMNI_D1_FW("error moving file: new path does not exist");
                return false;
            }
        }
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
                std::wstring nf = OMNI_FILE_CHECKW_FW(new_name, false)
                BOOL ret = ::MoveFileW(tf.c_str(), nf.c_str());
                if (ret == 0) {
                    OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                    return false;
                }
            #else
                int ret = ::_wrename(file.c_str(), new_name.c_str());
                if (ret != 0) {
                    OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::error_str(ret)));
                    return false;
                }
            #endif
        #else
            int ret = ::rename(omni::string::util::to_string(file).c_str(), omni::string::util::to_string(new_name).c_str());
            if (ret != 0) {
                OMNI_DV1_FW("error moving file: ", omni::string::util::to_string_t(omni::system::error_str(ret)));
                return false;
            }
        #endif
        return omni::io::file_internal::exists(new_name);
    }

    template < typename STR, typename IFSTREAM, typename SEQ >
    uint64_t rd(const STR& file, SEQ& buffer)
    {
        // TODO: does wifstream not take wchar_t[] filename?
        IFSTREAM ifile(omni::string::util::to_string(file).c_str(), std::ios::binary);
        if (!ifile.is_open()) { return 0; }
        ifile.seekg(0, ifile.end);
        uint64_t length = static_cast<uint64_t>(ifile.tellg());
        ifile.seekg(0, ifile.beg);
        // we can't assume the SEQ type will allow contiguous memory, so we have to loop :/
        typename STR::value_type* bf = new typename STR::value_type[length];
        ifile.read(bf, static_cast<std::streamsize>(length));
        length = static_cast<uint64_t>(ifile.gcount());
        ifile.close();
        //for (auto i = 0; i < length; ++i) { buffer[i] = bf[i]; }
        // TODO: verify .. also, is this really the most effeceint way??
        std::copy(buffer.begin(), buffer.end(), bf);
        delete[] bf;
        return length;
    }
    uint64_t read(const std::string& file, omni::seq::uchar_t& buffer)
    {
        return omni::io::file_internal::rd<std::string, std::ifstream, omni::seq::uchar_t>(file, buffer);
    }
    uint64_t read(const std::wstring& file, omni::seq::uchar_t& buffer)
    {
        return omni::io::file_internal::rd<std::wstring, std::wifstream, omni::seq::uchar_t>(file, buffer);
    }
    uint64_t read(const std::string& file, omni::seq::char_t& buffer)
    {
        return omni::io::file_internal::rd<std::string, std::ifstream, omni::seq::char_t>(file, buffer);
    }
    uint64_t read(const std::wstring& file, omni::seq::char_t& buffer)
    {
        return omni::io::file_internal::rd<std::wstring, std::wifstream, omni::seq::char_t>(file, buffer);
    }

    template < typename STR, typename IFSTREAM >
    uint64_t rd_f(const STR& file, STR& buffer)
    {
        IFSTREAM ifile(omni::string::util::to_string(file).c_str(), std::ios::binary);
        if (!ifile.is_open()) { return 0; }
        // TODO: verify std::streamsize will work on files larger than std::numeric_limits<long>::max() (~4GB)
        uint64_t length = static_cast<uint64_t>(ifile.tellg());
        ifile >> buffer;
        length = static_cast<uint64_t>(ifile.tellg()) - length;
        ifile.close();
        return length;
    }
    uint64_t read(const std::string& file, std::string& buffer)
    {
        return omni::io::file_internal::rd_f<std::string, std::ifstream>(file, buffer);
    }
    uint64_t read(const std::wstring& file, std::wstring& buffer)
    {
        return omni::io::file_internal::rd_f<std::wstring, std::wifstream>(file, buffer);
    }

    template < typename STR, typename IFSTREAM, typename SEQ >
    uint64_t rd_raw(const STR& file, SEQ* buffer, uint64_t blen)
    {
        // TODO: verify this functionality
        IFSTREAM ifile(omni::string::util::to_string(file).c_str(), std::ios::binary);
        if (!ifile.is_open()) { return 0; }
        ifile.seekg(0, ifile.end);
        uint64_t length = static_cast<uint64_t>(ifile.tellg());
        ifile.seekg(0, ifile.beg);
        if (length > blen) { length = blen; }
        ifile.read(reinterpret_cast<typename STR::value_type*>(buffer), static_cast<std::streamsize>(length));
        length = static_cast<uint64_t>(ifile.gcount());
        ifile.close();
        return length;
    }
    uint64_t read_raw(const std::string& file, unsigned char* buffer, uint64_t length)
    {
        return omni::io::file_internal::rd_raw<std::string, std::ifstream, unsigned char>(file, buffer, length);
    }
    uint64_t read_raw(const std::wstring& file, unsigned char* buffer, uint64_t length)
    {
        return omni::io::file_internal::rd_raw<std::wstring, std::wifstream, unsigned char>(file, buffer, length);
    }
    uint64_t read_raw(const std::string& file, char* buffer, uint64_t length)
    {
        return omni::io::file_internal::rd_raw<std::string, std::ifstream, char>(file, buffer, length);
    }
    uint64_t read_raw(const std::wstring& file, char* buffer, uint64_t length)
    {
        return omni::io::file_internal::rd_raw<std::wstring, std::wifstream, char>(file, buffer, length);
    }

    bool rem(const std::string& file)
    {
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                OMNI_FILE_CHECKA_FW(file, false)
                if (::DeleteFileA(file.c_str()) == 0) {
                    OMNI_DV1_FW("error deleting file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                    return false;
                }
            #else
                if (::_remove(file.c_str()) != 0) {
                    OMNI_DV1_FW("error deleting file: ", omni::system::last_error());
                    return false;
                }
            #endif
        #else
            if (::remove(file.c_str()) != 0) {
                OMNI_DV1_FW("error deleting file: ", omni::system::last_error());
                return false;
            }
        #endif
        return !omni::io::file::exists(file);
    }
    bool rem(const std::wstring& file)
    {
        #if defined(OMNI_OS_WIN)
            #if defined(OMNI_WIN_API)
                std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
                if (::DeleteFileW(tf.c_str()) == 0) {
                    OMNI_DV1_FW("error deleting file: ", omni::string::util::to_string_t(omni::system::last_error_str()));
                    return false;
                }
            #else
                if (::_wremove(file.c_str()) != 0) {
                    OMNI_DV1_FW("error deleting file: ", omni::system::last_error());
                    return false;
                }
            #endif
        #else
            if (::remove(omni::string::util::to_string(file).c_str()) != 0) {
                OMNI_DV1_FW("error deleting file: ", omni::system::last_error());
                return false;
            }
        #endif
        return !omni::io::file::exists(file);
    }

    #if defined(OMNI_NON_PORTABLE)
        bool set_size(const std::string& file, uint64_t size)
        {
            #if defined(OMNI_OS_WIN) && defined(OMNI_WIN_API)
                OMNI_FILE_CHECKA_FW(file, false)
                HANDLE hfile = ::CreateFileA(file.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                                                         CREATE_NEW|OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                int ret = omni::system::last_error();
                if (hfile == INVALID_HANDLE_VALUE || ret > 0) {
                    OMNI_DBGEV("error setting file length: ", ret)
                    if (hfile != INVALID_HANDLE_VALUE) {
                        ::CloseHandle(hfile);
                    }
                    return false;
                }
                ::SetFilePointer(hfile, size, 0, FILE_BEGIN);
                ::SetEndOfFile(hfile);
                ::CloseHandle(hfile);
            #else
                #if defined(OMNI_OS_WIN)
                    int fd = ::_open(file.c_str(), O_RDWR);
                    if (fd == -1) {
                        OMNI_DBGEV("Could not open file: ", omni::system::last_error())
                        return false;
                    }
                    errno_t ret = _chsize_s(fd, static_cast<__int64>(size));
                    if (ret != 0) {
                        OMNI_DBGEV("error setting file length: ", ret)
                        ::_close(fd);
                        return false;
                    }
                    ::_close(fd);
                #else
                    #if defined(OMNI_IO_USE_TRUNCATE)
                        if (OMNI_IO_FILE_TRUNCATE_FN (file.c_str(), static_cast<off_t>(size)) != 0) {
                            OMNI_DBGEV("error setting file length: ", omni::system::last_error())
                            return false;
                        }
                    #else
                        int fd = ::open(file.c_str(), O_RDWR);
                        if (fd == -1) {
                            OMNI_DBGEV("Could not open file: ", omni::system::last_error())
                            return false;
                        }
                        if (OMNI_IO_FILE_FTRUNCATE_FN (fd, static_cast<off_t>(size)) != 0) {
                            OMNI_DBGEV("error setting file length: ", omni::system::last_error())
                            ::close(fd);
                            return false;
                        }
                        ::close(fd);
                    #endif
                #endif
            #endif
            return true;
        }
        bool set_size(const std::wstring& file, uint64_t size)
        {
            #if defined(OMNI_OS_WIN)
                std::wstring tf = OMNI_FILE_CHECKW_FW(file, false)
                HANDLE hfile = ::CreateFileW(tf.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                                                     CREATE_NEW|OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                int ret = omni::system::last_error();
                if (hfile == INVALID_HANDLE_VALUE || ret > 0) {
                    OMNI_DBGEV("error setting file length: ", ret)
                    if (hfile != INVALID_HANDLE_VALUE) {
                        ::CloseHandle(hfile);
                    }
                    return false;
                }
                ::SetFilePointer(hfile, size, 0, FILE_BEGIN);
                ::SetEndOfFile(hfile);
                ::CloseHandle(hfile);
            #else
                #if defined(OMNI_OS_WIN)
                    int fd = ::_wopen(file.c_str(), O_RDWR);
                    if (fd == -1) {
                        OMNI_DBGEV("Could not open file: ", omni::system::last_error())
                        return false;
                    }
                    errno_t ret = _chsize_s(fd, static_cast<__int64>(size));
                    if (ret != 0) {
                        OMNI_DBGEV("error setting file length: ", ret)
                        ::_close(fd);
                        return false;
                    }
                    ::_close(fd);
                #else
                    #if defined(OMNI_IO_USE_TRUNCATE)
                        if (OMNI_IO_FILE_TRUNCATE_FN (file.c_str(), static_cast<off_t>(size)) != 0) {
                            OMNI_DBGEV("error setting file length: ", omni::system::last_error())
                            return false;
                        }
                    #else
                        int fd = ::open(omni::string::util::to_string(file).c_str(), O_RDWR);
                        if (fd == -1) {
                            OMNI_DBGEV("Could not open file: ", omni::system::last_error())
                            return false;
                        }
                        if (OMNI_IO_FILE_FTRUNCATE_FN (fd, static_cast<off_t>(size)) != 0) {
                            OMNI_DBGEV("error setting file length: ", omni::system::last_error())
                            ::close(fd);
                            return false;
                        }
                        ::close(fd);
                    #endif
                #endif
            #endif
            return true;
        }
    #endif

    template < typename T, typename O >
    uint64_t write_fw(const std::string& file, const T& buffer, bool append)
    {
        // TODO: verify functionality
        O ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        ofile << buffer.c_str();
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write(const std::string& file, const std::string& buffer, bool append)
    {
        return write_fw<std::string, std::ofstream>(file, buffer, append);
    }
    uint64_t write(const std::wstring& file, const std::wstring& buffer, bool append)
    {
        return write_fw<std::wstring, std::wofstream>(omni::string::util::to_string(file), buffer, append);
    }

    template < typename T, typename O, typename S, typename ITR >
    uint64_t write_buf_fw(const std::string& file, const S& buffer, bool append)
    {
        // TODO: verify functionality
        O ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        for (ITR b = buffer.begin(); b != buffer.end(); ++b) {
            ofile << *b;
        }
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write(const std::string& file, const omni::seq::uchar_t& buffer, bool append)
    {
        return write_buf_fw<std::string, std::ofstream, omni::seq::uchar_t, omni::seq::uchar_t::const_iterator>(file, buffer, append);
    }
    uint64_t write(const std::wstring& file, const omni::seq::uchar_t& buffer, bool append)
    {
        return write_buf_fw<std::wstring, std::wofstream, omni::seq::uchar_t, omni::seq::uchar_t::const_iterator>(omni::string::util::to_string(file), buffer, append);
    }
    uint64_t write(const std::string& file, const omni::seq::char_t& buffer, bool append)
    {
        return write_buf_fw<std::string, std::ofstream, omni::seq::char_t, omni::seq::char_t::const_iterator>(file, buffer, append);
    }
    uint64_t write(const std::wstring& file, const omni::seq::char_t& buffer, bool append)
    {
        return write_buf_fw<std::wstring, std::wofstream, omni::seq::char_t, omni::seq::char_t::const_iterator>(omni::string::util::to_string(file), buffer, append);
    }

    template < typename T >
    uint64_t write_raw_fw(const std::string& file, T buffer, size_t sz, bool append)
    {
        // TODO: verify functionality
        std::ofstream ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        ofile.write(reinterpret_cast<const char*>(buffer), static_cast<std::streamsize>(sz));
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write_raw(const std::string& file, const unsigned char* buffer, size_t sz, bool append)
    {
        return write_raw_fw<const unsigned char*>(file, buffer, sz, append);
    }
    uint64_t write_raw(const std::wstring& file, const unsigned char* buffer, size_t sz, bool append)
    {
        return write_raw_fw<const unsigned char*>(omni::string::util::to_string(file), buffer, sz, append);
    }
    uint64_t write_raw(const std::string& file, const char* buffer, size_t sz, bool append)
    {
        return write_raw_fw<const char*>(file, buffer, sz, append);
    }
    uint64_t write_raw(const std::wstring& file, const char* buffer, size_t sz, bool append)
    {
        return write_raw_fw<const char*>(omni::string::util::to_string(file), buffer, sz, append);
    }

    template < typename T, typename O, typename S >
    uint64_t write_line_buf_fw(const std::string& file, const S& buffer, bool append)
    {
        // TODO: verify functionality
        O ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        for (typename S::const_iterator b = buffer.begin(); b != buffer.end(); ++b) {
            ofile << *b;
        }
        ofile << std::endl;
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write_line(const std::string& file, const omni::seq::uchar_t& buffer, bool append)
    {
        return write_line_buf_fw<std::string, std::ofstream, omni::seq::uchar_t>(file, buffer, append);
    }
    uint64_t write_line(const std::wstring& file, const omni::seq::uchar_t& buffer, bool append)
    {
        return write_line_buf_fw<std::wstring, std::wofstream, omni::seq::uchar_t>(omni::string::util::to_string(file), buffer, append);
    }
    uint64_t write_line(const std::string& file, const omni::seq::char_t& buffer, bool append)
    {
        return write_line_buf_fw<std::string, std::ofstream, omni::seq::char_t>(file, buffer, append);
    }
    uint64_t write_line(const std::wstring& file, const omni::seq::char_t& buffer, bool append)
    {
        return write_line_buf_fw<std::wstring, std::wofstream, omni::seq::char_t>(omni::string::util::to_string(file), buffer, append);
    }

    template < typename T, typename O >
    uint64_t write_line_fw(const std::string& file, const T& buffer, bool append)
    {
        // TODO: verify functionality
        O ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        ofile << buffer.c_str() << std::endl;
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write_line(const std::string& file, const std::string& buffer, bool append)
    {
        return write_line_fw<std::string, std::ofstream>(file, buffer, append);
    }
    uint64_t write_line(const std::wstring& file, const std::wstring& buffer, bool append)
    {
        return write_line_fw<std::wstring, std::wofstream>(omni::string::util::to_string(file), buffer, append);
    }

    template < typename T >
    uint64_t write_line_raw_fw(const std::string& file, T buffer, size_t sz, bool append)
    {
        // TODO: verify functionality
        std::ofstream ofile(file.c_str(), (append ? (std::ios::binary | std::ios::app) : std::ios::binary));
        uint64_t start = static_cast<uint64_t>(ofile.tellp());
        uint64_t end = start;
        ofile.write(reinterpret_cast<const char*>(buffer), static_cast<std::streamsize>(sz));
        ofile << std::endl;
        ofile.flush();
        end = static_cast<uint64_t>(ofile.tellp());
        ofile.close();
        return (end - start);
    }
    uint64_t write_line_raw(const std::string& file, const unsigned char* buffer, size_t sz, bool append)
    {
        return write_line_raw_fw<const unsigned char*>(file, buffer, sz, append);
    }
    uint64_t write_line_raw(const std::wstring& file, const unsigned char* buffer, size_t sz, bool append)
    {
        return write_line_raw_fw<const unsigned char*>(omni::string::util::to_string(file), buffer, sz, append);
    }
    uint64_t write_line_raw(const std::string& file, const char* buffer, size_t sz, bool append)
    {
        return write_line_raw_fw<const char*>(file, buffer, sz, append);
    }
    uint64_t write_line_raw(const std::wstring& file, const char* buffer, size_t sz, bool append)
    {
        return write_line_raw_fw<const char*>(omni::string::util::to_string(file), buffer, sz, append);
    }

    } } }
#endif // OMNI_IO_FILE_INTERNAL_FW

bool omni::io::OMNI_PATH_FW::copy(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name) { return omni::io::OMNI_PATH_FW::copy(file, new_name, false); }
bool omni::io::OMNI_PATH_FW::create(const OMNI_STRING_T_FW& file) { return omni::io::OMNI_PATH_FW::create(file, true); }
bool omni::io::OMNI_PATH_FW::exist(const OMNI_STRING_T_FW& file) { return omni::io::OMNI_PATH_FW::exists(file); }
bool omni::io::OMNI_PATH_FW::move(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name) { return omni::io::OMNI_PATH_FW::move(file, new_name, false); }
bool omni::io::OMNI_PATH_FW::rename(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name, bool create_path) { return omni::io::OMNI_PATH_FW::move(file, new_name, create_path); }
bool omni::io::OMNI_PATH_FW::rename(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name) { return omni::io::OMNI_PATH_FW::rename(file, new_name, false); }
uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const omni::seq::uchar_t& buffer) { return omni::io::OMNI_PATH_FW::write(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const omni::seq::char_t& buffer) { return omni::io::OMNI_PATH_FW::write(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& buffer) { return omni::io::OMNI_PATH_FW::write(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write_raw(const OMNI_STRING_T_FW& file, const unsigned char* buffer, uint64_t length) { return omni::io::OMNI_PATH_FW::write_raw(file, buffer, length, false); }
uint64_t omni::io::OMNI_PATH_FW::write_raw(const OMNI_STRING_T_FW& file, const char* buffer, uint64_t length) { return omni::io::OMNI_PATH_FW::write_raw(file, buffer, length, false); }
uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const omni::seq::uchar_t& buffer) { return omni::io::OMNI_PATH_FW::write_line(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const omni::seq::char_t& buffer) { return omni::io::OMNI_PATH_FW::write_line(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& buffer) { return omni::io::OMNI_PATH_FW::write_line(file, buffer, false); }
uint64_t omni::io::OMNI_PATH_FW::write_line_raw(const OMNI_STRING_T_FW& file, const unsigned char* buffer, uint64_t length) { return omni::io::OMNI_PATH_FW::write_line_raw(file, buffer, length, false); }
uint64_t omni::io::OMNI_PATH_FW::write_line_raw(const OMNI_STRING_T_FW& file, const char* buffer, uint64_t length) { return omni::io::OMNI_PATH_FW::write_line_raw(file, buffer, length, false); }

bool omni::io::OMNI_PATH_FW::copy(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name, bool overwrite)
{
    if (file.empty() || new_name.empty()) {
        OMNI_ERR_RETV_FW(OMNI_PATH_EMPTY, omni::exceptions::path_exception(), false);
    }
    if (file == new_name) {
        OMNI_DBGEV("Old and new path are the same: ", omni::string::util::to_string_t(file));
        return true;
    }
    if (!omni::io::file_internal::exists(file)) {
        OMNI_ERRV_RETV_FW(OMNI_FILE_NOT_FOUND_STR, omni::string::util::to_string_t(file), omni::exceptions::file_not_found(omni::string::util::to_string(file)), false);
    }
    if (!overwrite && omni::io::file_internal::exists(new_name)) {
        OMNI_DBGEV("New path already exists: ", omni::string::util::to_string_t(new_name));
        return false;
    }
    if (omni::io::file_internal::copy(file, new_name)) {
        return omni::io::file_internal::exists(new_name);
    }
    return false;
}

bool omni::io::OMNI_PATH_FW::create(const OMNI_STRING_T_FW& file, bool create_path)
{
    return omni::io::file_internal::create(file, create_path);
}

bool omni::io::OMNI_PATH_FW::exists(const OMNI_STRING_T_FW& file)
{
    return omni::io::file_internal::exists(file);
}

OMNI_STRING_T_FW omni::io::OMNI_PATH_FW::get_contents(const OMNI_STRING_T_FW& file)
{
    if (!omni::io::file_internal::exists(file)) {
        OMNI_ERRV_RETV_FW("file does not exist: ", omni::string::util::to_string_t(file), omni::exceptions::path_exception(omni::string::util::to_string(file)), OMNI_STRING_T_FW())
    }
    return omni::io::file_internal::get_contents(file);
}

uint64_t omni::io::OMNI_PATH_FW::get_size(const OMNI_STRING_T_FW& file)
{
    if (!omni::io::file_internal::exists(file)) {
        OMNI_ERRV_RETV_FW("file does not exist: ", omni::string::util::to_string_t(file), omni::exceptions::path_exception(omni::string::util::to_string(file)), 0)
    }
    return omni::io::file_internal::get_size(file);
}

bool omni::io::OMNI_PATH_FW::move(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& new_name, bool create_path)
{
    if (!omni::io::file_internal::exists(file)) {
        OMNI_ERRV_RETV_FW("file does not exist: ", omni::string::util::to_string_t(file), omni::exceptions::path_exception(omni::string::util::to_string(file)), false)
    }
    if (omni::io::file_internal::exists(new_name)) {
        OMNI_ERRV_RETV_FW("file already exists: ", omni::string::util::to_string_t(new_name), omni::exceptions::path_exception(omni::string::util::to_string(new_name)), false)
    }
    return omni::io::file_internal::mv(file, new_name, create_path);
}

uint64_t omni::io::OMNI_PATH_FW::read(const OMNI_STRING_T_FW& file, omni::seq::uchar_t& buffer)
{
    return omni::io::file_internal::read(file, buffer);
}

uint64_t omni::io::OMNI_PATH_FW::read(const OMNI_STRING_T_FW& file, omni::seq::char_t& buffer)
{
    return omni::io::file_internal::read(file, buffer);
}

uint64_t omni::io::OMNI_PATH_FW::read(const OMNI_STRING_T_FW& file, OMNI_STRING_T_FW& buffer)
{
    return omni::io::file_internal::read(file, buffer);
}

uint64_t omni::io::OMNI_PATH_FW::read_raw(const OMNI_STRING_T_FW& file, unsigned char* buffer, uint64_t length)
{
    return omni::io::file_internal::read_raw(file, buffer, length);
}

uint64_t omni::io::OMNI_PATH_FW::read_raw(const OMNI_STRING_T_FW& file, char* buffer, uint64_t length)
{
    return omni::io::file_internal::read_raw(file, buffer, length);
}

bool omni::io::OMNI_PATH_FW::remove(const OMNI_STRING_T_FW& file)
{
    if (!omni::io::file_internal::exists(file)) {
        OMNI_DV1_FW("file does not exists: ", omni::string::util::to_string_t(file));
        return true;
    }
    return omni::io::file_internal::rem(file);
}

#if defined(OMNI_NON_PORTABLE)
bool omni::io::OMNI_PATH_FW::set_size(const OMNI_STRING_T_FW& file, uint64_t size)
{
    // The file must exist before this function can continue
    if (!omni::io::file_internal::exists(file)) {
        if (!omni::io::file_internal::create(file, true)) {
            OMNI_DBGE("could not create file")
            return false;
        }
    }

    if (!omni::io::file_internal::set_size(file, size)) { return false; }

    // DEV_NOTE: the following comments are here for instructional purpose
    /*
    // This function CAN destroy data. This functions uses API to extend or shorten
    // a file. If data is in the file and you extend the file, the data will stay
    // in place and the file length will simple be extended. If you shorten the file
    // the data at the end of the file will be freed (in other words, it won't be deleted
    // simply not associated with a file).

    // DEV_NOTE: It is possible, though uncommon, for an extended file to contain random
    // data where the file has been extended. This is typical of a sparse file. It is common
    // in Unix/Linux but no so much in Windows. Note that the reason we don't just write out
    // 'length' worth of null is because depending on 'length' this could take a long time.
    // No pun intended. Using the API to create a 'sparse' file, it simply tells the FAT
    // (file allocation table) that file 'X' is 'length' in size
    */
    return omni::io::OMNI_PATH_FW::get_size(file) == size;
}
#endif

uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const omni::seq::uchar_t& buffer, bool append)
{
    return omni::io::file_internal::write(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const omni::seq::char_t& buffer, bool append)
{
    return omni::io::file_internal::write(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& buffer, bool append)
{
    return omni::io::file_internal::write(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_raw(const OMNI_STRING_T_FW& file, const unsigned char* buffer, uint64_t length, bool append)
{
    return omni::io::file_internal::write_raw(file, buffer, length, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_raw(const OMNI_STRING_T_FW& file, const char* buffer, uint64_t length, bool append)
{
    return omni::io::file_internal::write_raw(file, buffer, length, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const omni::seq::uchar_t& buffer, bool append)
{
    return omni::io::file_internal::write_line(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const omni::seq::char_t& buffer, bool append)
{
    return omni::io::file_internal::write_line(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_line(const OMNI_STRING_T_FW& file, const OMNI_STRING_T_FW& buffer, bool append)
{
    return omni::io::file_internal::write_line(file, buffer, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_line_raw(const OMNI_STRING_T_FW& file, const unsigned char* buffer, uint64_t length, bool append)
{
    return omni::io::file_internal::write_line_raw(file, buffer, length, append);
}

uint64_t omni::io::OMNI_PATH_FW::write_line_raw(const OMNI_STRING_T_FW& file, const char* buffer, uint64_t length, bool append)
{
    return omni::io::file_internal::write_line_raw(file, buffer, length, append);
}