1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // This file provides substitutes for the basic stdio routines used by hyphen.c 7 // to read its dictionary files. We #define the stdio names to these versions 8 // in hnjalloc.h, so that we can use nsIURI and nsIInputStream to specify and 9 // access the dictionary resources. 10 11 #include "hnjalloc.h" 12 #undef FILE // Undo the damage done in hnjalloc.h 13 #include "nsNetUtil.h" 14 #include "nsIInputStream.h" 15 #include "nsIURI.h" 16 #include "nsContentUtils.h" 17 18 #define BUFSIZE 1024 19 20 struct hnjFile_ { 21 nsCOMPtr<nsIInputStream> mStream; 22 char mBuffer[BUFSIZE]; 23 uint32_t mCurPos; 24 uint32_t mLimit; 25 }; 26 27 // replacement for fopen() 28 // (not a full substitute: only supports read access) 29 hnjFile* 30 hnjFopen(const char* aURISpec, const char* aMode) 31 { 32 // this override only needs to support "r" 33 NS_ASSERTION(!strcmp(aMode, "r"), "unsupported fopen() mode in hnjFopen"); 34 35 nsCOMPtr<nsIURI> uri; 36 nsresult rv = NS_NewURI(getter_AddRefs(uri), aURISpec); 37 if (NS_FAILED(rv)) { 38 return nullptr; 39 } 40 41 nsCOMPtr<nsIChannel> channel; 42 rv = NS_NewChannel(getter_AddRefs(channel), 43 uri, 44 nsContentUtils::GetSystemPrincipal(), 45 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, 46 nsIContentPolicy::TYPE_OTHER); 47 if (NS_FAILED(rv)) { 48 return nullptr; 49 } 50 51 nsCOMPtr<nsIInputStream> instream; 52 rv = channel->Open2(getter_AddRefs(instream)); 53 if (NS_FAILED(rv)) { 54 return nullptr; 55 } 56 57 hnjFile *f = new hnjFile; 58 f->mStream = instream; 59 f->mCurPos = 0; 60 f->mLimit = 0; 61 62 return f; 63 } 64 65 // replacement for fclose() 66 int 67 hnjFclose(hnjFile* f) 68 { 69 NS_ASSERTION(f && f->mStream, "bad argument to hnjFclose"); 70 71 int result = 0; 72 nsresult rv = f->mStream->Close(); 73 if (NS_FAILED(rv)) { 74 result = EOF; 75 } 76 f->mStream = nullptr; 77 78 delete f; 79 return result; 80 } 81 82 // replacement for fgets() 83 // (not a full reimplementation, but sufficient for libhyphen's needs) 84 char* 85 hnjFgets(char* s, int n, hnjFile* f) 86 { 87 NS_ASSERTION(s && f, "bad argument to hnjFgets"); 88 89 int i = 0; 90 while (i < n - 1) { 91 if (f->mCurPos < f->mLimit) { 92 char c = f->mBuffer[f->mCurPos++]; 93 s[i++] = c; 94 if (c == '\n' || c == '\r') { 95 break; 96 } 97 continue; 98 } 99 100 f->mCurPos = 0; 101 102 nsresult rv = f->mStream->Read(f->mBuffer, BUFSIZE, &f->mLimit); 103 if (NS_FAILED(rv)) { 104 f->mLimit = 0; 105 return nullptr; 106 } 107 108 if (f->mLimit == 0) { 109 break; 110 } 111 } 112 113 if (i == 0) { 114 return nullptr; // end of file 115 } 116 117 s[i] = '\0'; // null-terminate the returned string 118 return s; 119 } 120